計算機視覺之OPENCV求解本質矩陣(Fundamental)函數說明

OPENCV求解本質矩陣函數說明

從兩張圖像的對應點計算本質矩陣

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

計算本質矩陣的方法:

  • 7點法

  • 8點法 矩陣E中有九個參數,根據尺度不變性,可以通過八對點估計本質矩陣,也就是所謂的八點法

  • RANSAC算法

  • LMedS算法

ransacReprojThreshold參數僅用於RANSAC。 它是從點到對極線的最大距離(以像素爲單位),超過該距離,該點被視爲異常值,並且不用於計算最終的基本矩陣。 可以將其設置爲1-3,具體取決於點定位的精度,圖像分辨率和圖像噪聲。

置信度僅用於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. 7-point algorithm is used.
       FM_RANSAC = 8  //!< RANSAC algorithm. It needs at least 15 points. 7-point algorithm is used.
     };

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['recoverPose’函數]

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 = -svd.u.col(2);
}


R1,R2,t1,t2四種組合得到四組可能的解

OPENCV求解本質矩陣函數說明

從兩張圖像的對應點計算本質矩陣

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

計算本質矩陣的方法:

  • 7點法

  • 8點法 矩陣E中有九個參數,根據尺度不變性,可以通過八對點估計本質矩陣,也就是所謂的八點法

  • RANSAC算法

  • LMedS算法

ransacReprojThreshold參數僅用於RANSAC。 它是從點到對極線的最大距離(以像素爲單位),超過該距離,該點被視爲異常值,並且不用於計算最終的基本矩陣。 可以將其設置爲1-3,具體取決於點定位的精度,圖像分辨率和圖像噪聲。

置信度僅用於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. 7-point algorithm is used.
       FM_RANSAC = 8  //!< RANSAC algorithm. It needs at least 15 points. 7-point algorithm is used.
     };

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['recoverPose’函數]

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 = -svd.u.col(2);
}


R1,R2,t1,t2四種組合得到四組可能的解

運行結果

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章