用opencv计算外在矩阵

问题描述 投票:1回答:1

我正在使用opencv来校准我的网络摄像头。因此,我所做的是将我的网络摄像头固定到一个装备上,使其保持静止,我使用了棋盘校准模式并将其移到摄像机前面并使用检测到的点来计算校准。所以,这正如我们在许多opencv示例中所见(https://docs.opencv.org/3.1.0/dc/dbb/tutorial_py_calibration.html

现在,这给了我相机内在矩阵和旋转和平移组件,用于将每个棋盘视图从棋盘空间映射到世界空间。

然而,我感兴趣的是全局外在矩阵,即一旦我移除了棋盘,我希望能够在图像场景中指定一个点,即x,y及其高度,它给了我在世界空间中的位置。据我所知,我需要内在和外在矩阵。如何从这里开始计算外在矩阵?我是否可以使用我从棋盘校准步骤中收集的测量值来计算外在矩阵?

opencv camera-calibration coordinate-transformation
1个回答
2
投票

让我来一些背景。请看下面的图片,(来自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矩阵,即你所谓的外在矩阵)。

现在,答案。要获得R和T,您可以执行以下操作:

  1. 修复您的世界参考框架,例如地面可以是(x,y)平面,并为其选择原点。
  2. 在此参考系中设置一些具有已知坐标的点,例如,在地板中的方形网格中的点。
  3. 拍照并获得相应的2D图像坐标。
  4. 使用solvePnP获取旋转和平移,使用以下参数: objectPoints:世界参考框架中的3D点。 imagePoints:图像中对应的2D点与objectPoints的顺序相同。 cameraMatris:你已经拥有的内在矩阵。 distCoeffs:你已经拥有的失真系数。 rvec,tvec:这些将是产出。 useExtrinsicGuess:false flags:您可以使用CV_ITERATIVE
  5. 最后,使用Rodrigues函数从rvec获得R.

您需要至少3个非共线点和相应的3D-2D坐标才能使solvePnP正常工作(link),但越多越好。要获得高质量的分数,您可以打印出一个巨大的棋盘图案,将其平放在地板上,并将其用作网格。重要的是图像中的图案不是太小(校准越大,校准就越稳定)。

并且,非常重要:对于内在校准,您使用了具有特定大小的正方形的国际象棋模式,但是您告诉算法(对每个模式执行某种解决方案),每个方块的大小为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。
© www.soinside.com 2019 - 2024. All rights reserved.