OPENCV:如何使用5点算法从来自不同相机的两个图像之间的特征匹配来计算必需矩阵



基本上我想在这里与此功能相同的事情:https://docs.opencv.org/master/d9/d0c/group__calib3d.html#ga13f7e34de8fa516a686a56a56af1196247f

但是,参数描述指出,该算法假定这两个图像的匹配特征点来自带有相同摄像机矩阵的摄像机。

如果我匹配功能,但是带有不同相机矩阵的两个不同摄像机的图像怎么办?如何计算5点必需矩阵?

其他问题:如果我计算了必需矩阵,可以在方法computeCorrespondEpilines()而不是基本矩阵中使用它作为参数,假设图像已经纠正?

在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()而不是基本矩阵中使用它作为参数,假设图像已经纠正?

是的,我认为这应该有效。

最新更新