相机姿态估计:如何解释旋转和平移矩阵?

Posted

技术标签:

【中文标题】相机姿态估计:如何解释旋转和平移矩阵?【英文标题】:Camera pose estimation: How do I interpret rotation and translation matrices? 【发布时间】:2015-07-16 06:49:13 【问题描述】:

假设我在两个图像之间有良好的对应关系,并尝试恢复它们之间的相机运动。 我可以为此使用 OpenCV 3 的新功能,如下所示:

 Mat E = findEssentialMat(imgpts1, imgpts2, focal, principalPoint, RANSAC, 0.999, 1, mask);

 int inliers = recoverPose(E, imgpts1, imgpts2, R, t, focal, principalPoint, mask);

 Mat mtxR, mtxQ;
 Mat Qx, Qy, Qz;
 Vec3d angles = RQDecomp3x3(R, mtxR, mtxQ, Qx, Qy, Qz);

 cout << "Translation: " << t.t() << endl;
 cout << "Euler angles [x y z] in degrees: " << angles.t() << endl;

现在,我很难理解 Rt 的实际含义。它们是否是将坐标从相机空间 1 映射到相机空间 2 所需的变换,如p_2 = R * p_1 + t

考虑这个例子,手动标记对应的真实情况

我得到的输出是这样的:

Translation: [-0.9661243151855488, -0.04921320381132761, 0.253341406362796]
Euler angles [x y z] in degrees: [9.780449804801876, 46.49315494782735, 15.66510133665445]

我尝试将其与我在图像中看到的内容相匹配并提出解释,[-0.96,-0.04,0.25] 告诉我,我已向右移动,因为坐标沿负 x 轴移动,但它还会告诉我,我已经移动得更远了,因为坐标已经沿着正 z 轴移动。

我还围绕 y 轴旋转了相机(向左,我认为这将是围绕负 y 轴逆时针旋转,因为在 OpenCV 中,y 轴指向下方,不是吗? )

问题:我的解释是否正确,如果不正确,正确的是什么?

【问题讨论】:

【参考方案1】:

其实你的解释是正确的。

首先,关于 y 轴的方向,您是正确的。有关 OpenCV 的相机坐标系的说明,请参阅here。

您的代码会将第二个摄像头的 R 和 t 返回到第一个摄像头。这意味着如果 x1 是第一个图像中的一个点并且 x2 是第二个图像中的一个点,则以下等式成立 x1 = R*x2 + t。 现在,在您的情况下,右侧图像(前视图)来自摄像头 1,而汽车的左侧图像(侧视图)来自摄像头 2。

看看这个等式,我们首先看到的是应用了旋转。因此,图像您的相机当前拍摄左帧。现在您的 R 指定绕 y 轴旋转约 46 度。由于角度 alpha 的旋转点与将坐标轴反向旋转该角度相同,因此您的 R 告诉您向左旋转。正如您自己指出的那样,如果查看图片,这似乎是正确的。由于围绕其他轴的旋转很小且难以成像,因此我们在此省略它们。 因此,在应用旋转之后,您仍然站在拍摄左框架的相同位置,但您的相机或多或少指向汽车后部或汽车正后方的空间。

现在让我们看看平移向量。您对向右移动和更远移动的解释也是正确的。让我试着解释一下原因。想象一下,从您当前的位置开始,使用新的相机方向,您只能向右移动。您会直接撞到汽车或需要将相机放在发动机罩上方。因此,向右移动后,您还需要进一步移动才能到达您拍摄正确照片的位置。

我希望这个解释能帮助你想象你的 R 和 t 描述的运动。

【讨论】:

【参考方案2】:

事实证明我的解释是正确的,关系p2 = R * p1 + t 确实成立。可以通过使用cv::triangulatePoints()cv::convertPointsFromHomogeneous 从对应点(相对于摄像机 1)获取 3D 坐标,然后应用上述等式来验证这一点。与相机 2 的相机矩阵相乘,然后得到 p2 图像坐标。

【讨论】:

【参考方案3】:

你的解释听起来对我来说是正确的。我不是 100% 关于 OpenCV 中轴的方向,但我相信你对 Y 轴的看法是正确的。

输出也很有意义,不仅从代码的角度来看,而且如果您查看这两个图像,您可以大致想象完整 90 度旋转将指向的位置(它基本上是相同的角度,但在相反的一侧汽车)

这也是通过刚体运动机制对该概念的一个相当不错的解释: http://nghiaho.com/?page_id=671

【讨论】:

【参考方案4】:

让我们看看。 OpenCV 相机坐标系为“X 朝向图像右侧,Y 朝向图像底部,Z = X x Y 朝向场景”。 Q=[R|t]是从camera2到camera1的坐标变换,所以t是以camera1为根,以camera2为顶点的向量,以camera1帧表示。因此,您的平移向量意味着camera2位于camera 1的左侧,根据您的图像,只有当汽车的侧视图在camera2中并且汽车的前视图在camera 1中时才有可能。这与正Z分量一致翻译,因为在侧视图中,汽车看起来离相机更远。

此标识也与您计算的欧拉角一致:它们在 OpenGL 约定中返回,从而表示从源到目标的旋转。在您的情况下,围绕camera1的垂直轴旋转46度,逆时针w.r.t。向下的 Y 轴为您带来您所拥有的侧视图。

【讨论】:

但是正 z 分量会告诉我 camera2 已经向汽车移动,但这不符合 camera2 是左侧图像的解释。我错过了什么? 重新阅读我写的内容:“t 是以 camera1 为根的向量,尖端在 camera2”。 t 的正 Z 分量仅表示 camera2 的中心在 camera1 的 XY 平面前面,即在 camera1 的中心前面。考虑到您的图像,这完全合理:只需想象在查看汽车前部的视图中扩展图像平面,然后决定侧视图的相机应该在该平面的哪一侧。另外,如果您觉得有用,请点赞/接受答案。 如果我这样做,在我看来,相机 2 的中心在相机 1 的后面,所以 z 应该是负数。但由于轮换,不是很清楚。

以上是关于相机姿态估计:如何解释旋转和平移矩阵?的主要内容,如果未能解决你的问题,请参考以下文章

使用 OpenCV SolvePnP 进行高架相机的姿态估计会导致高度偏离几厘米

如何根据两个连续帧的投影变换矩阵估计相机姿态?

使用单相机进行标记姿态估计的误差

根据相机旋转矩阵求解三个轴的旋转角/欧拉角

使用DLT进行姿态估计需要多少个点?

基准标记或相机姿态估计