抱歉,标题有误导性,因为我不知道如何面对这个问题。我所说的 ROI 是鱼眼视图的透视图。它们也可以被解释为鱼眼在相机/世界坐标中产生的半球的切线视图。我有一个可行的解决方案。
首先,您必须定义一个具有内在和外在参数的虚拟透视相机模型,特别是我们想要 53ª 的 fov,并且我们希望透视图对整个鱼眼域进行密集采样,因此我们需要以不同的角度放置几个沿 x 轴和 y 轴写入鱼眼相机。外部因素被赋予鱼眼姿势。在这种情况下,我只关心具有 [0,0,0] 平移的旋转虚拟相机。该size
参数描述了透视图像的大小。
def getVirtualCameraMatrix(viewfield, size, x_angle=0, y_angle=0, z_angle=0):
f = 0.5*size[1] / np.tan(np.radians(0.5*viewfield))
intrinsic_matrix = np.array([[f, 0, size[1]/2],
[0, f, size[0]/2],
[0, 0, 1]])
rmat_x = np.array([[1, 0, 0],
[0, np.cos(np.radians(x_angle)), -np.sin(np.radians(x_angle))],
[0, np.sin(np.radians(x_angle)), np.cos(np.radians(x_angle))]])
rmat_y = np.array([[np.cos(np.radians(y_angle)), 0, np.sin(np.radians(y_angle))],
[0, 1, 0],
[-np.sin(np.radians(y_angle)), 0, np.cos(np.radians(y_angle))]])
rmat_z = np.array([[np.cos(np.radians(z_angle)), -np.sin(np.radians(z_angle)), 0],
[np.sin(np.radians(z_angle)), np.cos(np.radians(z_angle)), 0],
[0, 0, 1]])
params = {'rotation': rmat_z @ rmat_y @ rmat_x,
'translation': np.array([0, 0, 0]),
'intrinsics': {
'image_size': size,
'focal_length': f,
'principal_point': [size[0]/2, size[1]/2],
'matrix': intrinsic_matrix}}
return params
然后,为了获得每个透视图,我们必须从目标到源,即从透视图到鱼眼以获取后者中的像素值。应按以下步骤进行:
- 建立一个像素坐标meshgrid
- 将每个像素坐标反向投影到相机坐标为:
K^-1 * 像素坐标
其中 K^-1 是 的倒数params['intrinsics']['matrix']
。(你可以得到它np.linalg.inv
)
- 将透视相机坐标中的 3D 点转换为鱼眼相机坐标,将反向旋转应用于步骤 2,即:
E^-1 * K^-1 * 像素坐标
其中 E^-1 是params['rotation']
world2cam
投影 3 到鱼眼图像,使用 Scaramuzza方法获得切线/透视图。链接在问题帖子中