计算机视觉之OpenCV求解基础矩阵(Fundamental)函数说明

本文详细介绍了OpenCV中用于计算基础矩阵的函数,包括7点法、8点法、RANSAC和LMedS算法。计算出的基础矩阵可用于极线计算和立体校正。代码示例展示了如何从两帧图像恢复相机运动,通过特征匹配和SVD分解求得旋转矩阵R和平移矩阵t。此外,还讨论了如何从基础矩阵恢复R和t,以及正确解的筛选方法。
摘要由CSDN通过智能技术生成

OpenCV求解基础矩阵函数说明

从两张图像的对应点计算基础矩阵

CV_EXPORTS_W Mat findFundamentalMat( InputArray points1, InputArray points2,
                                     int method = FM_RANSAC,
                                     double param1 = 3., double param2 = 0.99,
                                     OutputArray mask = noArray() );

具体参数说明:

points1:第一张图像的N个点;
points2:   第二张图像的点;
param1:   该参数用于RANSAC算法(随机采样过程一致性),它是从点到对极线的最大距离(以像素为单位),超过该距离,该点被视为异常值,并且不用于计算最终的基础矩阵。 可以将其设置为1-3,具体取决于点定位的精度,图像分辨率和图像噪声。
param2:   该参数仅仅在RANSAC算法以及LMedS算法中, 它指定了估计矩阵正确的期望置信度(概率)。

计算基础矩阵的方法:

  • 7点法

  • 8点法 矩阵E中有九个参数,根据尺度不变性,可以通过八对点估计基础矩阵,也就是所谓的八点法

  • RANSAC算法

  • LMedS算法

该函数使用上面列出的四种方法之一计算基础矩阵,然后返回找到的基础矩阵。 通常只找到一个矩阵。 但是在使用7点算法的情况下,该函数最多可以返回3个解,该矩阵顺序存储所有3个矩阵)。

所计算的基础矩阵可以进一步传递给
computeCorrespondEpilines,后者找到与指定点相对应的极线。 也可以将其传递给stereoRectifyUncalibrated来计算整流变换。

代码实现:

enum { FM_7POINT = 1, //!< 7-point algorithm
       FM_8POINT = 2, //!< 8-point algorithm
       FM_LMEDS  = 4, //!< least-median algorithm.
       FM_RANSAC = 8  //!< RANSAC algorithm. 
     };

example.cpp

 int point_count = 100;
    vector<Point2f> points1(point_count);
    vector<Point2f> points2(point_count);

    // initialize the points here ...
    for( int i = 0; i < point_count; i++ )
    {
        points1[i] = ...;
        points2[i] = ...;
    }

    Mat fundamental_matrix =
     findFundamentalMat(points1, points2, FM_RANSAC, 3, 0.99);

如何从两帧图像恢复相机的运动(即可到从一张图片到另一张图片的变换矩阵)

  • 特征匹配得到关键点(必须依靠正确的匹配)
  • 计算基础矩阵E(findFundamentalMat)或者本质矩阵
  • 从E中通过SVD分解得到旋转矩阵R和平移矩阵t['decomposeE’函数]

2D->2D点: 对极几何

基础矩阵(Fundamental matrix)

本质矩阵(Essential matix)

手写基础矩阵恢复R,t

void InitialEXRotation::decomposeE(cv::Mat E,
                                 cv::Mat_<double> &R1, cv::Mat_<double> &R2,
                                 cv::Mat_<double> &t1, cv::Mat_<double> &t2)
{
    cv::SVD svd(E, cv::SVD::MODIFY_A);
    cv::Matx33d W(0, -1, 0,
                  1, 0, 0,
                  0, 0, 1);
    cv::Matx33d Wt(0, 1, 0,
                   -1, 0, 0,
                   0, 0, 1);
    R1 = svd.u * cv::Mat(W) * svd.vt;
    R2 = svd.u * cv::Mat(Wt) * svd.vt;
    t1 = svd.u.col(2);//opencv函数 工程trick
    cv::Mat_<double> t3;
    cv::Mat_<double> ut;
    cv::transpose(svd.u, ut);
    cv::Matx33d t(1, 0, 0, 0, 1, 0, 0, 0, 0);
    std::cout << " Wt: " <<t.col(0)<< std::endl;
    std::cout << "svd.u " << svd.u << std::endl;
    std::cout << "svd.vt" << svd.vt << std::endl;
    t3 = svd.u * cv::Mat(W) *cv::Mat(t)*ut;// 视觉SLAM十四讲公式
    std::cout << " t1: " << t1 << std::endl; //验证t1与t3是否相等
    std::cout << " t3: " << t3<< std::endl;
    t2 &#
  • 2
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

纷繁中淡定

你的鼓励是我装逼的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值