根据鱼眼相机公式rf=f*θ,其中θ=atan(rc/f),即可实现从pinhole相机模型到fisheye相机模型的像素映射。可自行设置焦距,我使用如下代码完成了将cityscape数据集转换为鱼眼视角。
import numpy as np
import cv2
import os
class ConvertFisheye():
"""
rf = f*atan(rc/f)
其中theta=atan(rc/f)
"""
def __init__(self):
self.focal_length = 520 # 可自行设置fisheye焦距
def convert(self, img):
h, w = img.shape[0], img.shape[1]
dstImg = np.zeros(img.shape, np.uint8)
ux, uy = w/2, h/2 # 传统图像的主点,principle point(也是鱼眼的主点,因为同分辨率的)
for i in range(h):
for j in range(w):
dx, dy = j-ux, i-uy # 传统图像的图像坐标
rc = np.sqrt(dx**2 + dy**2) # distance between the image point and the principal point
theta = np.arctan2(rc, self.focal_length) # θ is the angle between the principal axis and the incoming ray
gama = np.arctan2(dy, dx) # 图像点到图像主点的连线的角度,鱼眼和传统都一样
rf = self.focal_length*theta
xf = rf*np.cos(gama)
yf = rf*np.sin(gama)
x = int(xf + ux) # 原图j对应鱼眼的x
y = int(yf + uy) # 原图i对应鱼眼的y
dstImg[y][x] = img[i][j]
# cv2.imshow('a', dstImg)
# cv2.waitKey()
return(dstImg)
if __name__ == "__main__":
input_root_path = 'E:\\all_dataset\\cityscape_val\\val'
output_root_path = 'E:\\all_dataset\\cityscape_fisheye_val\\label_img'
cf = ConvertFisheye()
i = 0
if not os.path.exists(output_root_path):
os.makedirs(output_root_path)
for root, dirs, files in os.walk(input_root_path):
for f in files:
if 'color' in f and not os.path.exists(os.path.join(output_root_path, f)):
i += 1
img_path = os.path.join(root, f)
print(img_path, i)
img = cv2.imread(img_path)
dstImg = cf.convert(img)
cv2.imwrite(os.path.join(output_root_path, f), dstImg)