我试图用OpenCV对一些点进行三角测量,我发现了这个 cv::triangulatePoints()
函数 . 问题是几乎没有文档或示例 .
我有一些疑问 .
-
What method does it use? 我've making a small research about triangulations and there are several methods (Linear, Linear LS, eigen, iterative LS, iterative eigen,...) but I can't在OpenCV中查找它使用的是哪一个 .
-
How should I use it? 似乎作为输入它需要一个投影矩阵和 3xN 同质 2D 点 . 我将它们定义为
std::vector<cv::Point3d> pnts
,但作为输出它需要 4xN 数组,显然我不能创建std::vector<cv::Point4d>
,因为它不存在,那么我该如何定义输出向量?
对于我尝试的第二个问题: cv::Mat pnts3D(4,N,CV_64F);
和 cv::Mat pnts3d;
,似乎都不起作用(它抛出异常) .
5 回答
1.- The method 使用的是最小二乘法 . 有比这更复杂的算法 . 它仍然是最常见的一种,因为在某些情况下其他方法可能会失败(即,如果点在平面上或在无限上,则其他方法会失败) .
该方法可以在Richard Hartley和Andrew Zisserman的 Multiple View Geometry in Computer Vision 中找到(p312)
2.- The usage :
用图像中的点填充2个chanel点矩阵 .
cam0
和cam1
是Mat3x4
摄像机矩阵(内部和外部参数) . 您可以通过乘以A * RT来构造它们,其中A是内在参数矩阵,RT是旋转平移3x4姿势矩阵 .NOTE :
pnts3D
在定义时需要为4通道 1xNcv::Mat
,如果没有则抛出异常,但结果为cv::Mat(4,N,cv_64FC1)
矩阵 . 真的很混乱,但这是我没有例外的唯一方法 .UPDATE :从版本3.0或更早版本开始,这不再是真的,
pnts3D
也可以是Mat(4,N,CV_64FC1)
类型,或者可以保持完全为空(通常,它是在函数内部创建的) .@Ander Biguri回答的一小部分内容 . 您应该在非
undistort
ed图像上获取图像点,并在cam0pnts
和cam1pnts
上调用undistortPoints()
,因为cv::triangulatePoints
期望标准化坐标中的2D点(独立于摄像机)和cam0
和cam1
应该只是 [R|t^T] matricies你没有需要多次使用 A .感谢Ander Biguri!他的回答对我很有帮助 . 但我总是喜欢使用std :: vector的替代方案,我编写了他的解决方案:
所以你只需要在点上做emplace_back . 主要优点:在开始填充之前,您不需要知道
N
的大小 . 不幸的是,没有cv :: Point4f,所以pnts3D必须是cv :: Mat ...我试过cv :: triangulatePoints,但不知怎的,它计算垃圾 . 我被迫手动实现线性三角测量方法,它为三角形3D点返回一个4x1矩阵:
输入参数是两个3×4相机投影矩阵和相应的左/右像素对(x,y,w) .
或者你也可以使用Hartley&Zisserman在这里实现的方法:http://www.morethantechnical.com/2012/01/04/simple-triangulation-with-opencv-from-harley-zisserman-w-code/