OpenCV中的外参矩阵计算

10
我正在使用opencv校准我的网络摄像头。我将摄像头固定在支架上,以使其保持静止,并使用棋盘校准模式将其移动到相机前方,并使用检测到的点计算校准。这与许多opencv示例中所提供的相同(https://docs.opencv.org/3.1.0/dc/dbb/tutorial_py_calibration.html)。
现在,这给了我相机内部矩阵和旋转和平移分量,用于将每个棋盘视图从棋盘空间映射到世界空间。
然而,我感兴趣的是全局外部矩阵,即一旦我已经去除棋盘,我想能够指定图像场景中的一个点即x、y及其高度,并给出其在世界空间中的位置。据我所知,我需要内部和外部矩阵。如何从这里开始计算外部矩阵呢?我可以使用已经收集到的棋盘校准步骤的测量来计算外部矩阵吗?
1个回答

11

让我先给您提供一些背景信息。请考虑以下图片(来自https://docs.opencv.org/2.4/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html):

enter image description here

相机已经“附加”了一个刚性参考框架(Xc,Yc,Zc)。您成功执行的内部校准允许您将点(Xc,Yc,Zc)转换为其在图像上的投影(u,v),并将图像中的点(u,v)转换为射线(Xc,Yc,Zc)(只能获得比例因子)。
实际应用中,您希望将相机放置在外部“世界”参考框架中,我们称之为(X,Y,Z)。然后有一个刚性变换,由旋转矩阵R和平移向量T表示:
|Xc|    |X|
|Yc|= R |Y| + T
|Zc|    |Z|

这是外参校准(也可以写成4x4矩阵,这就是所谓的外参矩阵)。

现在,下面是答案。要获得RT,您可以执行以下操作:

  1. 固定世界参考系,例如地面可以是(x,y)平面,并选择一个原点。

  2. 在这个参考系中设置一些具有已知坐标的点,例如地板上的方形网格中的点。

  3. 拍照并获取相应的2D图像坐标。

  4. 使用 solvePnP 获取旋转和平移,使用以下参数:

    • objectPoints:世界参考系中的3D点。
    • imagePoints:与objectPoints顺序相同的图像中对应的2D点。
    • cameraMatris:您已经拥有的内部矩阵。
    • distCoeffs:您已经拥有的畸变系数。
    • rvectvec:这些将是输出。
    • useExtrinsicGuess:false
    • flags:您可以使用CV_ITERATIVE
  5. 最后,使用Rodrigues函数从rvec获取R

您需要至少三个不共线的点和相应的3D-2D坐标才能使用solvePnP(link),但是更多点会更好。为了获得高质量的点,您可以打印一个大棋盘图案,将其平放在地板上,并将其用作网格。重要的是图案在图像中不要太小(越大,您的校准就越稳定)。
而且,非常重要的是:对于内部校准,您使用了具有特定大小正方形的棋盘图案,但是您告诉算法(对每个模式都进行了某种形式的solvePnPs),每个正方形的大小为1。这虽然不是明确的,但是在示例代码的第10行中完成了此操作,其中网格的坐标为0,1,2,...:
objp[:,:2] = np.mgrid[0:7,0:6].T.reshape(-1,2)
外部校准的世界比例必须匹配此比例,因此您有几种可能性:
  1. 使用相同的比例尺,例如使用相同的网格或测量您的“世界”平面的坐标以相同的比例尺。在这种情况下,您的“世界”将不会按照正确的比例尺。

  2. 建议:使用正确的比例尺重新进行内部校准,例如:

    objp[:,:2] = (size_of_a_square*np.mgrid[0:7,0:6]).T.reshape(-1,2)

    其中,size_of_a_square是正方形的实际大小。

  3. (尚未完成此操作,但在理论上可行,如果无法完成第2步,请执行此操作)通过缩放fx和fy来重用内部校准。这是可能的,因为相机只看到一个比例因子内的所有内容,并且声明的正方形大小仅更改fx和fy(每个正方形的姿势中的T也会更改,但那是另一回事)。如果实际正方形的大小为L,则在调用solvePnP之前将fx和fy替换为Lfx和Lfy。


即使今天,这仍然是很麻烦的,因为没有单个、功能良好的程序或ROS包能够方便地实现它。理论背景可以,但没有可执行文件,我们仍然无法做到。 - Schütze
@Milo,在不移动初始外参参数的情况下,可以对相机进行校准吗? - thewoz
你好@thewoz。很抱歉,我不太明白这个问题。您能详细说明一下吗? - Milo
嗨@Milo,OpenCV中的校准相机功能可以找到最小化投影误差的相机内部和外部参数。现在我非常精确地知道了外部参数,但是我缺少内部参数。如果我在OpenCV中使用该函数,则找到的内部参数将适用于算法找到的外部参数,但不适用于“真实”的参数。 - thewoz
@thewoz:如果我理解正确,您正在使用OpenCV的内部校准和手动指定的外部校准,但它没有按预期工作?它应该可以正常工作。也许您没有以正确的方式指定外部校准,但没有更多信息很难确定。您能否提供更多详细信息?也许您需要发布一个新问题? - Milo
鉴于第三种可能性,我尝试使用实际世界中的1和正方形图案的大小(在我的情况下为3.7厘米)来校准相机(用于内部参数),但是fx和fy没有改变。如果我将正方形图案更改为50厘米,我是否需要乘以相机矩阵的fx和fy? - witoong623

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接