9

我有许多校准过的相机拍摄平面场景的照片。为简单起见,我们假设有 3 个摄像头。这些相机正在进行一般运动,但主要是平移加上一些温和的旋转。相机位置示例

任务是将它们完全缝合。我对 3D 坐标一无所知,只是使用校准相机拍摄的一组图像。

我所做的:

我通过在每对图像(1->2、2->3、1->3)之间使用findHomography来检测 OpenCV 中的 SURF/SIFT 实现的特征以获得初始单应性。从这些单应性中,我得到了每个相机姿势的初始估计(与此类似的过程)

然后我尝试使用捆绑调整技术来最小化每个匹配对的重投影误差。优化的参数是三个平移值和三个旋转值(从 Rodrigues 的旋转公式获得),尽管我可以稍后添加内在参数(焦点、主点等)。

假设图像#2 将是参考帧(通过与其他两个图像有最多的匹配),它的旋转和平移矩阵分别是恒等矩阵和零矩阵。

我计算从图像#2到图像#1的关键点(在图像#2和图像#1中都可见)的重投影为(伪代码)

[x1_; y1_; z1_] = K1*R1*inv(K2)*[x2; y2; 1] + K1*T1/Z2;
x1 = x1_/z1_;
y1 = y1_/z1_;

或者

x1 = ((f1/f2)*r11*x2 + (f1/f2)*r12*y2 + f1*r13 + f1*tx/Z2) / ((1/f2)*r31*x2 + (1/f2)*r32*y2 + r33 + tx/Z2)
y1 = ((f1/f2)*r21*x2 + (f1/f2)*r22*y2 + f1*r23 + f1*ty/Z2) / ((1/f2)*r31*x2 + (1/f2)*r32*y2 + r33 + ty/Z2)

其中 r__ 是 R1 矩阵的元素,两个内在矩阵的形式为

[f 0 0]
[0 f 0]
[0 0 1]

我假设参考系的 Z2 坐标为 1。

下一阶段是使用获得的相机矩阵(K1、R1、T1、K3、R3、T3)将图像#1 和#3 扭曲到图像#2 的公共坐标系中。

问题是我不知道正确重投影到图像#2的参考帧所需的Z1和Z3,因为从图像#1->#2的反转重投影看起来像这样:

x2 = ((f2/f1)*R11*x1 + (f2/f1)*R12*y1 + f2*R13 - f0/Z1*(R11*tx + R12*ty + R13*tz)) / ((1/f1)*R31*x1 + (1/f1)*R32*y1 + R33 - 1/Z1*(R31*tx + R32*ty + R33*tz))
y2 = ((f2/f1)*R21*x1 + (f2/f1)*R22*y1 + f2*R23 - f0/Z1*(R21*tx + R22*ty + R23*tz)) / ((1/f1)*R31*x1 + (1/f1)*R32*y1 + R33 - 1/Z1*(R31*tx + R32*ty + R33*tz))

其中 R__ 是 inv(R1) 矩阵的元素。

有没有更好的方法来计算束调整(2d->2d)的重投影误差,然后将图像扭曲到公共坐标系中?我注意到 OpenCV 在他们的拼接模块中有非常相似的框架,但它是在纯旋转运动的假设下运行的,这不是这里的情况。

4

2 回答 2

1

我在我的帖子如何从外部参数中获取立体图像中的点自动回答了这个问题

请注意,我使用的方法(已测试且正在工作!)仅当 3D 坐标(现实世界!)中的对象是平面且位于 Z=0(您校准相机的外部参数的点)时才有效。在这种情况下,此方法与您的校准一样精确。注意:为了获得最佳校准检查 openCVs 圆形校准,它的复制误差为 0.018 像素(由在我大学工作的博士生测试)。

于 2013-04-09T14:10:03.053 回答
1

您可能已经发现了关于拒绝错误的错误。它与这一行有关:

[x1_; y1_; z1_] = K1*R1*inv(K2)*[x2; y2; 1] + K1*T1/Z2;

点 [x2; y2; 1] 在比例常数 C*[x2; y2; 1] 在这里你设置 C=1 时通常是未知的。在第一种观点中,可能性的轨迹表现为一条极线。您可以使用最小二乘三角剖分沿着这条线找到最有可能存在 3D 点的点,然后将重新投影的点计算为:

[x1_; y1_; z1_] = K1*(R1*X + T1);

并像上面一样从那里开始。点云中每个这样的点 X 的 3D 坐标可以使用其对应的归一化坐标 (x1,y1), (x2,y2),... 以及相应的旋转矩阵和平移向量来计算,通过格式化它们进入矩阵问题:

A X = b

然后求解最小二乘:

min |A X - b|_2

此处的第 3 页和第 4 页对此进行了说明。

于 2013-07-17T00:21:41.453 回答