OpenCV-ArUco中tvecs rvecs的基本理解
Fundamental understanding of tvecs rvecs in OpenCV-ArUco
我想使用 ArUco 找到标记的 "space coordinates"。
我在理解 tvecs
和 rvecs
时遇到问题。我到目前为止 tvecs
是翻译而 rvecs
是旋转。但是它们是如何定位的,它们在代码中的编写顺序是什么,或者我该如何定位它们?
Here is a little sketch of the setup. 我在 X,Y[= 位置有一个摄像头(刚刚绘制的笔记本电脑网络摄像头以说明摄像头的方向) 70=],Z,Camera是朝向的,可以用a围绕X的角度来描述, 角度 b 围绕 Y, 角度 c 围绕 Z (以 Rad 为单位的角度)。
因此,如果我的相机是静止的,我会拍摄 ChArUco 板的不同照片,并为相机校准算法提供 tvecs_camerapos
(Z, Y,X) 和 rvecs_camerapos
(c,b ,a).我得到了 cameraMatrix,distCoeffs
和 tvecs_cameracalib
,rvecs_cameracalib
。 t/rvecs_camerapos
和 t/rvecs_cameracalib
不同,我觉得很奇怪。
- t/rvecs 的 nomination/order 是否正确?
- 如果相机不移动,我应该使用
camerapos
还是cameracalib
进行姿态估计?
我觉得t/rvecs_cameracalib
可以忽略不计,因为我只对相机标定算法的内参感兴趣
现在我想找到X,Y,Z 标记的位置 ,我使用 aruco.estimatePoseSingleMarkers
和 t/rvecs_camerapos
并检索 t/rvecs_markerpos
。 tvecs_markerpos
与我的预期值不符。
- 我需要对
t/rvecs_markerpos
进行转换才能找到 X,Y,Z 的标记?
- 我的误解在哪里?
在我的理解中,相机坐标是3D世界的参考系。 rvec 和 tvec 是用于获取任何其他 3D 点(在世界参考系中)w.r.t 相机坐标系的位置的变换。所以这两个向量都是外参数[R|t]。内在参数通常来自校准。现在,如果您想将世界参考系中的任何其他 3D 点 w.r.t 投影到图像平面上,您需要先将该 3D 点放入相机坐标系中,然后再将其投影到图像上以获得正确的视角。
图像平面中的点 (u,v,1)=[内在] [外在] [3D 点,1]
参考坐标系为相机。 rvec,tvec 将标记的 6D 姿势提供给相机。
处理相机和相机校准(包括 AruCo)的 OpenCV 例程使用 pinhole camera model。世界原点定义为相机模型的投影中心(所有进入相机的光线汇聚于此),Z轴定义为相机模型的光轴,X和Y轴构成正交系Z. +Z 在镜头前,+X 在右,+Y 在下。所有 AruCo 坐标都在此坐标系中定义。这就解释了为什么你的 "camera" tvecs 和 rvecs 会改变:它们不定义你的相机在某个世界坐标系中的位置,而是定义标记相对于你的相机的位置。
你真的不需要知道相机校准算法是如何工作的,除了它会给你一个相机矩阵和一些镜头畸变参数,你可以将它们用作其他 AruCo 和 OpenCV 例程的输入。
获得校准数据后,您可以使用 AruCo 识别标记以及 return 它们在相机定义的 3D 坐标系中的位置和方向,并对相机镜头的失真进行正确补偿。例如,这足以在您的相机视频源之上使用 OpenGL 进行增强现实。
标记的tvec是标记从原点的平移(x,y,z);距离单位是您用来定义打印校准图表的任何单位(即,如果您使用 mm 向 OpenCV 描述校准图表,则 tvecs 中的距离单位是 mm)。
标记的 rvec 是一个 3D 旋转矢量,它定义了旋转轴和围绕该轴的旋转角度,并给出了标记的方向。可以使用 Rodrigues 函数 (cv::Rodrigues()) 将其转换为 3x3 旋转矩阵。它要么是将标记的局部轴转换为世界(相机)轴的旋转,要么是相反的——我记不清了,但你可以很容易地检查。
我想使用 ArUco 找到标记的 "space coordinates"。
我在理解 tvecs
和 rvecs
时遇到问题。我到目前为止 tvecs
是翻译而 rvecs
是旋转。但是它们是如何定位的,它们在代码中的编写顺序是什么,或者我该如何定位它们?
Here is a little sketch of the setup. 我在 X,Y[= 位置有一个摄像头(刚刚绘制的笔记本电脑网络摄像头以说明摄像头的方向) 70=],Z,Camera是朝向的,可以用a围绕X的角度来描述, 角度 b 围绕 Y, 角度 c 围绕 Z (以 Rad 为单位的角度)。
因此,如果我的相机是静止的,我会拍摄 ChArUco 板的不同照片,并为相机校准算法提供 tvecs_camerapos
(Z, Y,X) 和 rvecs_camerapos
(c,b ,a).我得到了 cameraMatrix,distCoeffs
和 tvecs_cameracalib
,rvecs_cameracalib
。 t/rvecs_camerapos
和 t/rvecs_cameracalib
不同,我觉得很奇怪。
- t/rvecs 的 nomination/order 是否正确?
- 如果相机不移动,我应该使用
camerapos
还是cameracalib
进行姿态估计?
我觉得t/rvecs_cameracalib
可以忽略不计,因为我只对相机标定算法的内参感兴趣
现在我想找到X,Y,Z 标记的位置 ,我使用 aruco.estimatePoseSingleMarkers
和 t/rvecs_camerapos
并检索 t/rvecs_markerpos
。 tvecs_markerpos
与我的预期值不符。
- 我需要对
t/rvecs_markerpos
进行转换才能找到 X,Y,Z 的标记? - 我的误解在哪里?
在我的理解中,相机坐标是3D世界的参考系。 rvec 和 tvec 是用于获取任何其他 3D 点(在世界参考系中)w.r.t 相机坐标系的位置的变换。所以这两个向量都是外参数[R|t]。内在参数通常来自校准。现在,如果您想将世界参考系中的任何其他 3D 点 w.r.t 投影到图像平面上,您需要先将该 3D 点放入相机坐标系中,然后再将其投影到图像上以获得正确的视角。
图像平面中的点 (u,v,1)=[内在] [外在] [3D 点,1]
参考坐标系为相机。 rvec,tvec 将标记的 6D 姿势提供给相机。
处理相机和相机校准(包括 AruCo)的 OpenCV 例程使用 pinhole camera model。世界原点定义为相机模型的投影中心(所有进入相机的光线汇聚于此),Z轴定义为相机模型的光轴,X和Y轴构成正交系Z. +Z 在镜头前,+X 在右,+Y 在下。所有 AruCo 坐标都在此坐标系中定义。这就解释了为什么你的 "camera" tvecs 和 rvecs 会改变:它们不定义你的相机在某个世界坐标系中的位置,而是定义标记相对于你的相机的位置。
你真的不需要知道相机校准算法是如何工作的,除了它会给你一个相机矩阵和一些镜头畸变参数,你可以将它们用作其他 AruCo 和 OpenCV 例程的输入。
获得校准数据后,您可以使用 AruCo 识别标记以及 return 它们在相机定义的 3D 坐标系中的位置和方向,并对相机镜头的失真进行正确补偿。例如,这足以在您的相机视频源之上使用 OpenGL 进行增强现实。
标记的tvec是标记从原点的平移(x,y,z);距离单位是您用来定义打印校准图表的任何单位(即,如果您使用 mm 向 OpenCV 描述校准图表,则 tvecs 中的距离单位是 mm)。
标记的 rvec 是一个 3D 旋转矢量,它定义了旋转轴和围绕该轴的旋转角度,并给出了标记的方向。可以使用 Rodrigues 函数 (cv::Rodrigues()) 将其转换为 3x3 旋转矩阵。它要么是将标记的局部轴转换为世界(相机)轴的旋转,要么是相反的——我记不清了,但你可以很容易地检查。