OpenCV undistortPoints和triangulatePoint给出了奇怪的结果(立体声)
我试图在空间中得到几个点的3D坐标,但是我得到了来自undistortPoints()
和triangulatePoints()
奇怪结果。
由于两台摄像机的分辨率不同,我分别对它们进行了校准,获得了0,34
和0,43
RMS误差,然后使用stereoCalibrate()
得到更多的matrix,得到0,708
的RMS,然后使用stereoRectify()
剩下的matrix。 在手边,我已经开始收集坐标的工作,但是我得到了奇怪的结果。
例如,input是(1228.709125, 342.79841)
(935, 262)
, undistortPoints()
输出是(1228.709125, 342.79841)
,而另一个则是(1227.9016, 292.4686)
(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;
点之间的angular度有点不错,但通常不是:
`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
一帧一帧。
像素距离(底部)与实际距离(顶部) – 应该非常相似:
angular度:
此外,不应该undistortPoints()
和undistort()
给出相同的结果(另一组video在这里)?
函数cv :: undistort一气呵成地做了不失真和重投影。 它执行以下操作列表:
- 撤消相机投影(与相机matrix的逆相乘)
- 应用失真模型来消除失真
- 通过提供的旋转matrixR1 / R2进行旋转
- 项目使用提供的投影matrixP1 / P2指向图像
如果你通过matrixR1,P1和 R2,P2来自cv :: stereoCalibrate(),input点将失真并被纠正。 整理意味着图像被转换成相应的点具有相同的y坐标。 对于图像纠正没有独特的解决scheme,因为您可以对两个图像应用任何平移或缩放,而不会改变对应点的alignment。 也就是说,cv :: stereoCalibrate()可以移动投影的中心(比如300像素)。 如果你想纯粹的不失真,你可以通过一个标识matrix(而不是R1)和原始相机matrixK(而不是P1)。 这应该导致与原始像素坐标相似的像素坐标。