我试图用OpenCV来三角测量一些点,我发现了这个cv::triangulatePoints()
函数。问题是几乎没有文档或例子。
我对此有些怀疑。
1.它使用什么方法?我对三角测量做了一些研究,有几种方法(线性、线性LS、特征值、迭代LS、迭代特征值...),但我找不到OpenCV使用的是哪一种。
1.我应该如何使用它?它似乎需要一个投影矩阵和3xN齐次2D点作为输入,我将它们定义为std::vector<cv::Point3d> pnts
,但作为输出,它需要4xN数组,显然我不能创建std::vector<cv::Point4d>
,因为它不存在,那么我应该如何定义输出向量?
对于第二个问题,我试着回答:cv::Mat pnts3D(4, N, CV_64F);
和cv::Mat pnts3d;
,但似乎都不起作用(它抛出异常)。
5条答案
按热度按时间pqwbnv8z1#
1.-使用的方法是最小二乘法。还有比这更复杂的算法。尽管如此,它仍然是最常用的一种,因为其他方法在某些情况下可能会失败(例如,如果点在平面上或无穷远处,其他一些方法会失败)。
该方法可以在 Richard Hartley和Andrew Zisserman(p312)的***计算机视觉中的多视图几何***中找到。
2.-用法:
用图像中的点填充2通道点矩阵。
cam0
和cam1
是Mat3x4
摄影机矩阵(内部和外部参数)。可以通过乘以A*RT
来构造它们,其中A
是内部参数矩阵,RT
是旋转平移3x 4姿势矩阵。注意:
pnts3D
需要是一个4通道1xNcv::Mat
当定义时,抛出异常,如果不是,但结果是一个cv::Mat(4, N, cv_64FC1)
矩阵。真的很混乱,但这是唯一的方法,我没有得到一个异常。UPDATE:从3.0版或更早版本开始,这不再成立,
pnts3D
也可以是Mat(4, N, CV_64FC1)
类型,或者可以完全为空(通常,它在函数内部创建)。yzxexxkh2#
对@Ander Biguri的回答做了一点补充。您应该在非
undistort
艾德的图像上获取图像点,并在cam0pnts
和cam1pnts
上调用undistortPoints()
,因为cv::triangulatePoints
需要归一化坐标中的2D点(独立于相机),而cam0
和cam1
应该仅为**[R|t^T]矩阵不需要乘以A**。h79rfbju3#
感谢Ander Biguri!他的回答帮了我很大的忙。但我总是更喜欢std::vector的替代方案,我将他的解决方案编辑为:
所以你只需要在点中做emplace_back即可。主要优点:在开始填充它们之前,你不需要知道
N
的大小。不幸的是,没有cv::Point 4f,所以pnts 3D必须是cv::Mat...06odsfpq4#
我试过cv::triangulatePoints,但不知怎么的它计算垃圾,我被迫手动实现线性三角测量方法,它为三角测量的3D点返回一个4x 1矩阵:
输入参数是两个3 × 4摄像机投影矩阵和对应的左/右像素对(x,y,w)。
j8yoct9x5#
除了吉内斯·伊达尔戈的评论外,
如果你做了立体校准,并且可以从那里精确地估计出基本矩阵,它是基于棋盘格计算出来的。
使用correctMatches函数细化检测到的关键点