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四種組合得到四組可能的解