在 OpenCV 中,没有使用两个不同的相机计算基本矩阵的标准函数。但是自己实现它非常容易。
您可以向five-point.cpp 添加一个函数并重新编译OpenCV。
我刚刚添加了一个重载函数cv::findEssentialMat,并为第二个摄像头矩阵添加了一个附加参数。
cv::Mat cv::findEssentialMat(InputArray _points1, InputArray _points2, InputArray _cameraMatrix1, InputArray _cameraMatrix2, int method, double prob, double threshold, OutputArray _mask)
{
CV_INSTRUMENT_REGION();
Mat points1, points2, cameraMatrix1, cameraMatrix2;
_points1.getMat().convertTo(points1, CV_64F);
_points2.getMat().convertTo(points2, CV_64F);
_cameraMatrix1.getMat().convertTo(cameraMatrix1, CV_64F);
_cameraMatrix2.getMat().convertTo(cameraMatrix2, CV_64F);
int npoints = points1.checkVector(2);
CV_Assert(npoints >= 0 && points2.checkVector(2) == npoints &&
points1.type() == points2.type());
CV_Assert(cameraMatrix1.rows == 3 && cameraMatrix1.cols == 3 && cameraMatrix1.channels() == 1);
CV_Assert(cameraMatrix2.rows == 3 && cameraMatrix2.cols == 3 && cameraMatrix2.channels() == 1);
if (points1.channels() > 1)
{
points1 = points1.reshape(1, npoints);
points2 = points2.reshape(1, npoints);
}
double fx1 = cameraMatrix1.at<double>(0, 0);
double fy1 = cameraMatrix1.at<double>(1, 1);
double cx1 = cameraMatrix1.at<double>(0, 2);
double cy1 = cameraMatrix1.at<double>(1, 2);
double fx2 = cameraMatrix2.at<double>(0, 0);
double fy2 = cameraMatrix2.at<double>(1, 1);
double cx2 = cameraMatrix2.at<double>(0, 2);
double cy2 = cameraMatrix2.at<double>(1, 2);
points1.col(0) = (points1.col(0) - cx1) / fx1;
points2.col(0) = (points2.col(0) - cx2) / fx2;
points1.col(1) = (points1.col(1) - cy1) / fy1;
points2.col(1) = (points2.col(1) - cy2) / fy2;
// Reshape data to fit opencv ransac function
points1 = points1.reshape(2, npoints);
points2 = points2.reshape(2, npoints);
threshold /= (fx1 + fy1) / 2;
Mat E;
if (method == RANSAC)
createRANSACPointSetRegistrator(makePtr<EMEstimatorCallback>(), 5, threshold, prob)->run(points1, points2, E, _mask);
else
createLMeDSPointSetRegistrator(makePtr<EMEstimatorCallback>(), 5, prob)->run(points1, points2, E, _mask);
return E;
}
然后你必须将函数声明添加到calib3d.hpp,重新编译并重新安装你的OpenCV版本。
附加问题:如果我已经计算了基本矩阵,我是否可以将其用作方法computeCorrespondEpilines() 中的参数,而不是基本矩阵,假设图像已经校正?
是的,我认为这应该可行。