0

我在尝试在鱼眼图像中选择虚拟子图像(我们称之为 ROI)时遇到问题,然后我想不失真。

我有以下鱼眼校准参数。Scaramuzza 校准模型. 我想做的是创建一个虚拟针孔相机阵列(53° FOV),它们之间有一定程度的重叠,并从鱼眼中采样它们对应的子图像。所以想象一下,我的鱼眼 FOV 大约是 180°,我想用我的 53° 虚拟摄像机覆盖整个 FOV,它们之间有 20° 重叠,也就是说,我需要大约 180/(53-20)=5.45 个摄像机(我是不是 100% 确定这个计算必须考虑更多)。如果我错了,请纠正我:不扭曲整个鱼眼图像并从那里提取针孔视图与推断鱼眼域中的 ROI 并分别不扭曲它们中的每一个是否相同?如果没有,我想第二个是正确的方法,但我应该如何进行。我如何知道鱼眼相机的哪个区域属于每个 53°FOV 相机?我的直觉告诉我,指向鱼眼边缘的那些应该比靠近中心的那些具有更扭曲的 ROI。

我不太擅长理解投影空间以及如何在其中操作。希望你们无论如何都能帮助我。

4

1 回答 1

0

抱歉,标题有误导性,因为我不知道如何面对这个问题。我所说的 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

然后,为了获得每个透视图,我们必须从目标到源,即从透视图到鱼眼以获取后者中的像素值。应按以下步骤进行:

  1. 建立一个像素坐标meshgrid
  2. 将每个像素坐标反向投影到相机坐标为:

K^-1 * 像素坐标

其中 K^-1 是 的倒数params['intrinsics']['matrix']。(你可以得到它np.linalg.inv

  1. 将透视相机坐标中的 3D 点转换为鱼眼相机坐标,将反向旋转应用于步骤 2,即:

E^-1 * K^-1 * 像素坐标

其中 E^-1 是params['rotation']

  1. world2cam投影 3 到鱼眼图像,使用 Scaramuzza方法获得切线/透视图。链接在问题帖子中
于 2020-12-16T10:55:55.333 回答