【发布时间】:2015-11-20 13:12:22
【问题描述】:
我正在尝试获取空间中几个点的 3D 坐标,但我从 undistortPoints() 和 triangulatePoints() 得到了奇怪的结果。
由于两个相机的分辨率不同,我分别校准,得到0,34和0,43的RMS误差,然后用stereoCalibrate()得到更多的矩阵,得到0,708的RMS,然后用stereoRectify() 获取剩余矩阵。有了这个,我开始着手收集坐标,但得到了奇怪的结果。
例如,输入是:(935, 262),undistortPoints() 输出在某一点上是 (1228.709125, 342.79841),而在另一点上分别是 (934, 176) 和 (1227.9016, 292.4686)。这很奇怪,因为这两个点都非常靠近帧的中间,那里的失真最小。我没想到它会将它们移动 300 像素。
当传递给traingulatePoints() 时,结果变得更加奇怪——我测量了现实生活中三个点之间的距离(用尺子),并计算了每张图片上像素之间的距离。因为这一次点在一个相当平坦的平面上,所以这两个长度(像素和实数)匹配,如 |AB|/|BC|在这两种情况下都是大约 4/9。然而,triangulatePoints() 给了我不正常的结果,|AB|/|BC|为 3/2 或 4/2。
这是我的代码:
double pointsBok[2] = { bokList[j].toFloat()+xBok/2, bokList[j+1].toFloat()+yBok/2 };
cv::Mat imgPointsBokProper = cv::Mat(1,1, CV_64FC2, pointsBok);
double pointsTyl[2] = { tylList[j].toFloat()+xTyl/2, tylList[j+1].toFloat()+yTyl/2 };
//cv::Mat imgPointsTyl = cv::Mat(2,1, CV_64FC1, pointsTyl);
cv::Mat imgPointsTylProper = cv::Mat(1,1, CV_64FC2, pointsTyl);
cv::undistortPoints(imgPointsBokProper, imgPointsBokProper,
intrinsicOne, distCoeffsOne, R1, P1);
cv::undistortPoints(imgPointsTylProper, imgPointsTylProper,
intrinsicTwo, distCoeffsTwo, R2, P2);
cv::triangulatePoints(P1, P2, imgWutBok, imgWutTyl, point4D);
double wResult = point4D.at<double>(3,0);
double realX = point4D.at<double>(0,0)/wResult;
double realY = point4D.at<double>(1,0)/wResult;
double realZ = point4D.at<double>(2,0)/wResult;
点之间的角度有点好,但通常不是:
`7,16816 168,389 4,44275` vs `5,85232 170,422 3,72561` (degrees)
`8,44743 166,835 4,71715` vs `12,4064 158,132 9,46158`
`9,34182 165,388 5,26994` vs `19,0785 150,883 10,0389`
我尝试在整个帧上使用undistort(),但得到的结果同样奇怪。 B 点和 C 点之间的距离在任何时候都应该几乎没有变化,但这就是我得到的:
7502,42
4876,46
3230,13
2740,67
2239,95
逐帧。
角度:
【问题讨论】:
-
能否包含您用于校准的代码和三角测量部分的一些示例图像?
-
这可能很难......有很多。明天我会尽量只发布相关部分
-
@abarry 至于校准内在函数,我就是这样做的。我单独校准每个相机(因为它们具有不同的分辨率和纵横比),然后我用我从以前的校准中得到的校准立体系统。校准后,我立即将 undistort() 图像应用于两个图像,并且图像像箭头一样笔直。我确实在同一组视频上尝试了 undistortPoints() 和 undistort(),图表在上面。
-
您应该在三角测量之前(以及在不失真之后)校正您的图像(使用
stereoRectify),以便对应点具有相同的高度,否则视差图将不准确。 -
@Petersaber 在未失真后,它们不再被纠正,因此结果将是错误的。有关示例和进一步说明,您可以查看 Gary Bradski 和 Adrian Kaehler 所著的 Learning OpenCV 第 12 章
标签: c++ opencv triangulation