相机姿态估计:如何解释旋转和平移矩阵?
Camera pose estimation: How do I interpret rotation and translation matrices?
假设我在两个图像之间有很好的对应关系,并尝试恢复它们之间的相机运动。
我可以为此使用 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;
现在,我很难理解 R
和 t
的实际含义。它们是将坐标从摄像机 space 1 映射到摄像机 space 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 轴指向下方,是吗不是吗?)
问题:我的解释是否正确,如果不正确,正确的是什么?
你的解释对我来说是正确的。我不是 100% 了解 OpenCV 中轴的方向,但我相信你对 Y 轴的看法是正确的。
输出也很有意义,不仅从代码的角度来看,而且如果您查看这两张图像,您可以粗略地想象完整的 90 度旋转指向的位置(它基本上是相同的角度,但在汽车的对面)
这也是通过刚体运动力学对概念的一个相当不错的解释:
http://nghiaho.com/?page_id=671
让我们看看。 OpenCV相机坐标系为"X toward image right, Y toward image bottom, Z = X x Y toward the scene"。 Q=[R|t] 是从 camera2 到 camera1 的坐标变换,因此 t 是以 camera1 为根,以 camera2 为尖端的向量,以 camera1 帧表示。因此,您的平移向量意味着 camera2 在 camera 1 的左侧,根据您的图像,只有当汽车的侧视图在 camera2 中并且汽车的前视图在 camera 1 中时才有可能。这与正 Z 分量一致的翻译,因为在侧视图中,汽车看起来离相机更远。
此标识也与您计算的欧拉角一致:它们在 OpenGL 约定中返回,因此表示从源到目标的旋转。在您的例子中,绕 camera1 的垂直轴逆时针旋转 46 度 w.r.t。向下的 Y 轴,将您带到您所拥有的侧视图。
其实你的解释是正确的。
首先你是对的,关于y轴的方向。有关 OpenCV 相机坐标系的说明,请参见 here。
您的代码将 return 从第二个摄像头到第一个摄像头的 R 和 t。这意味着如果 x1 是第一个图像中的一个点,x2 是第二个图像中的一个点,则以下等式成立 x1 = R*x2 + t
。
现在,在您的情况下,右边的图像(前视图)来自相机 1,汽车的左侧图像(侧视图)来自相机 2。
看看这个等式,我们看到首先应用了旋转。所以成像你的相机当前拍摄的是左边的画面。现在您的 R 指定绕 y 轴旋转约 46 度。由于按角度 alpha 旋转点与按此角度反向旋转坐标轴相同,因此您的 R 告诉您向左旋转。正如您自己指出的那样,如果看图片,这似乎是正确的。由于围绕其他轴的旋转很小且难以成像,因此我们在这里省略它们。
因此,在应用旋转后,您仍然站在拍摄左帧的相同位置,但您的相机或多或少指向汽车后部或汽车正后方的 space。
现在让我们看看翻译向量。您对向右移动和更远移动的解释也是正确的。让我试着解释一下为什么。想象一下,从您当前的位置,使用新的相机方向,您只能向右移动。您会直接撞到汽车或需要将相机放在发动机罩上方。所以向右移动后你还需要再移动远一点才能到达你拍对的位置。
我希望这个解释能帮助您想象您的 R 和 t 描述的运动。
事实证明我的解释是正确的,p2 = R * p1 + t
这个关系确实成立。可以通过使用 cv::triangulatePoints()
和 cv::convertPointsFromHomogeneous
从对应点(相对于相机 1)获取 3D 坐标,然后应用上述等式来验证这一点。然后与相机 2 的相机矩阵相乘产生 p2
图像坐标。
假设我在两个图像之间有很好的对应关系,并尝试恢复它们之间的相机运动。 我可以为此使用 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;
现在,我很难理解 R
和 t
的实际含义。它们是将坐标从摄像机 space 1 映射到摄像机 space 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 轴指向下方,是吗不是吗?)
问题:我的解释是否正确,如果不正确,正确的是什么?
你的解释对我来说是正确的。我不是 100% 了解 OpenCV 中轴的方向,但我相信你对 Y 轴的看法是正确的。
输出也很有意义,不仅从代码的角度来看,而且如果您查看这两张图像,您可以粗略地想象完整的 90 度旋转指向的位置(它基本上是相同的角度,但在汽车的对面)
这也是通过刚体运动力学对概念的一个相当不错的解释: http://nghiaho.com/?page_id=671
让我们看看。 OpenCV相机坐标系为"X toward image right, Y toward image bottom, Z = X x Y toward the scene"。 Q=[R|t] 是从 camera2 到 camera1 的坐标变换,因此 t 是以 camera1 为根,以 camera2 为尖端的向量,以 camera1 帧表示。因此,您的平移向量意味着 camera2 在 camera 1 的左侧,根据您的图像,只有当汽车的侧视图在 camera2 中并且汽车的前视图在 camera 1 中时才有可能。这与正 Z 分量一致的翻译,因为在侧视图中,汽车看起来离相机更远。
此标识也与您计算的欧拉角一致:它们在 OpenGL 约定中返回,因此表示从源到目标的旋转。在您的例子中,绕 camera1 的垂直轴逆时针旋转 46 度 w.r.t。向下的 Y 轴,将您带到您所拥有的侧视图。
其实你的解释是正确的。
首先你是对的,关于y轴的方向。有关 OpenCV 相机坐标系的说明,请参见 here。
您的代码将 return 从第二个摄像头到第一个摄像头的 R 和 t。这意味着如果 x1 是第一个图像中的一个点,x2 是第二个图像中的一个点,则以下等式成立 x1 = R*x2 + t
。
现在,在您的情况下,右边的图像(前视图)来自相机 1,汽车的左侧图像(侧视图)来自相机 2。
看看这个等式,我们看到首先应用了旋转。所以成像你的相机当前拍摄的是左边的画面。现在您的 R 指定绕 y 轴旋转约 46 度。由于按角度 alpha 旋转点与按此角度反向旋转坐标轴相同,因此您的 R 告诉您向左旋转。正如您自己指出的那样,如果看图片,这似乎是正确的。由于围绕其他轴的旋转很小且难以成像,因此我们在这里省略它们。 因此,在应用旋转后,您仍然站在拍摄左帧的相同位置,但您的相机或多或少指向汽车后部或汽车正后方的 space。
现在让我们看看翻译向量。您对向右移动和更远移动的解释也是正确的。让我试着解释一下为什么。想象一下,从您当前的位置,使用新的相机方向,您只能向右移动。您会直接撞到汽车或需要将相机放在发动机罩上方。所以向右移动后你还需要再移动远一点才能到达你拍对的位置。
我希望这个解释能帮助您想象您的 R 和 t 描述的运动。
事实证明我的解释是正确的,p2 = R * p1 + t
这个关系确实成立。可以通过使用 cv::triangulatePoints()
和 cv::convertPointsFromHomogeneous
从对应点(相对于相机 1)获取 3D 坐标,然后应用上述等式来验证这一点。然后与相机 2 的相机矩阵相乘产生 p2
图像坐标。