使用单相机进行标记姿态估计的误差
Posted
技术标签:
【中文标题】使用单相机进行标记姿态估计的误差【英文标题】:Error in marker pose estimation using single camera 【发布时间】:2017-04-27 07:44:04 【问题描述】:我使用以下 OpenCV 代码来估计方形 Marker 的位姿,并在图像上绘制标记的 3 个轴。但是标记的 Z 轴会不时旋转 180 度,如下图所示。如何使z轴稳定?
// Marker world coordinates
vector<Point3f> objecPoints;
objecPoints.push_back(Point3f(0, 0, 0));
objecPoints.push_back(Point3f(0, 2.4, 0));
objecPoints.push_back(Point3f(2.4, 2.4, 0));
objecPoints.push_back(Point3f(2.4, 0.0, 0));
// 2D image coordinates of 4 marker corners. They are arranged in the same order for each frame
vector<Point2f> marker2DPoints;
// Calculate Rotation and Translation
cv::Mat Rvec;
cv::Mat_<float> Tvec;
cv::Mat raux, taux;
cv::solvePnP(objecPoints, marker2DPoints, camMatrix, distCoeff, raux, taux);
// Draw marker pose on the image
vector<Point3f> axisPoints3D;
axisPoints3D.push_back(Point3f(0, 0, 0));
axisPoints3D.push_back(Point3f(2.4, 0, 0));
axisPoints3D.push_back(Point3f(0, 2.4, 0));
axisPoints3D.push_back(Point3f(0, 0, 2.4));
vector<Point2f> axisPoints2D;
// Take the camMatrix and distCoeff from camera calibration results
projectPoints(axisPoints3D, Rvec, Tvec, camMatrix, distCoeff, axisPoints2D);
line(srcImg, axisPoints2D[0], axisPoints2D[1], CV_RGB(0, 0, 255), 1, CV_AA);
line(srcImg, axisPoints2D[0], axisPoints2D[2], CV_RGB(0, 255, 0), 1, CV_AA);
line(srcImg, axisPoints2D[0], axisPoints2D[3], CV_RGB(255, 0, 0), 1, CV_AA);
【问题讨论】:
在我看来,正确的标记 (ID 4) 是对称的(如果将它翻转到轴上,它仍然会注册为同一个 Aruco 标记)。如果是这种情况,则标签的方向似乎不明确。这只发生在 ID 4 上吗? (ID 3 不是对称的;我想知道您是否可以将 ID 4 换成类似的非对称标签)。 【参考方案1】:作为评论可能会更好,但我没有足够的声誉。我认为这可能是由于 solvePnP 获取标签坐标的顺序。 此外,由于 solvePnP 只是尝试将 3D 平面上的 4 个点与图像中的 4 个 2D 点进行匹配(在这种情况下),因此有多种解决方案。标签可以围绕其上轴旋转,也可以上下翻转。 solvePnP 不知道从提供的点是向上的方向。
我有一种预感,对于这个问题,solvePnP 有点太笼统了,因为稳定的标签检测算法应该能够以稳定的顺序将角点输入到姿态估计代码中。
编辑:角的顺序很重要,solvePnP 给出的解决方案取决于它。也许生成角点的算法没有以一致的顺序提供角点?请分享 tags.points 的输出
【讨论】:
我在source of the latest OpenCV 中发现了这个,他们在内部也使用solvePnP 来估计一个名为ArUco 的新标签的位姿。 标记的四个角已经正确排序并且对于所有帧都是一致的。角点标有不同颜色的点(绿色、蓝色、黑色和青色),它们是一致的,如上图和下图所示。以上是关于使用单相机进行标记姿态估计的误差的主要内容,如果未能解决你的问题,请参考以下文章