- 操作系統:ubuntu22.04
- OpenCV版本:OpenCV4.9
- IDE:Visual Studio Code
- 編程語言:C++11
算法描述
從兩幅圖像中的對應點計算基本矩陣。
cv::findFundamentalMat 是 OpenCV 中用于計算兩幅圖像之間基本矩陣(Fundamental Matrix)的函數。基本矩陣描述了兩個未校準攝像機之間的幾何關系,它在計算機視覺中用于立體視覺、運動結構恢復(Structure from Motion, SfM)、視覺里程計等任務。
函數原型
Mat cv::findFundamentalMat
(InputArray points1,InputArray points2,int method,double ransacReprojThreshold,double confidence,int maxIters,OutputArray mask = noArray()
)
參數
- 參數points1:來自第一幅圖像的 N 個點數組。點的坐標應該是浮點數(單精度或雙精度)。
- 參數points2:第二幅圖像的點數組,與 points1 具有相同的大小和格式。
- 參數method:計算基本矩陣的方法。
- FM_7POINT:用于7點算法。N=7
- FM_8POINT:用于8點算法。N≥8
- FM_RANSAC:用于RANSAC算法。N≥8
- FM_LMEDS:用于最小中值法(LMedS)算法。N≥8
- 參數ransacReprojThreshold:僅用于 RANSAC 的參數。它是點到極線的最大距離(以像素為單位),超過該距離的點被認為是離群點,并不用于計算最終的基本矩陣。根據點定位的準確性、圖像分辨率和圖像噪聲,它可以設置為1-3等。
- 參數confidence:僅用于 RANSAC 和 LMedS 方法的參數。它指定了估計矩陣正確的期望置信水平(概率)。
- 參數[out] mask:可選輸出掩碼。
- 參數maxIters:穩健方法的最大迭代次數。
說明
極幾何由以下方程描述:
[ p 2 ; 1 ] T F [ p 1 ; 1 ] = 0 [p_2; 1]^T F [p_1; 1] = 0 [p2?;1]TF[p1?;1]=0
其中 F 是基本矩陣,p1和p2分別是第一幅和第二幅圖像中的對應點。
該函數使用上述列出的四種方法之一來計算基本矩陣,并返回找到的基本矩陣。通常只找到一個矩陣。但在7點算法的情況下,該函數可能返回多達3個解(一個 9×3 矩陣,按順序存儲所有3個矩陣)。
// Example. Estimation of fundamental matrix using the RANSAC algorithm
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);
代碼示例
#include <iostream>
#include <opencv2/opencv.hpp>using namespace cv;
using namespace std;int main( int argc, char** argv )
{// 創建虛擬的匹配點數據(假設我們有8對匹配點)vector< Point2f > points1 = { Point2f( 154.0f, 38.0f ), Point2f( 285.0f, 176.0f ), Point2f( 279.0f, 238.0f ), Point2f( 276.0f, 284.0f ),Point2f( 273.0f, 342.0f ), Point2f( 267.0f, 397.0f ), Point2f( 262.0f, 446.0f ), Point2f( 254.0f, 495.0f ) };vector< Point2f > points2 = { Point2f( 149.0f, 49.0f ), Point2f( 280.0f, 187.0f ), Point2f( 274.0f, 249.0f ), Point2f( 271.0f, 295.0f ),Point2f( 268.0f, 353.0f ), Point2f( 262.0f, 408.0f ), Point2f( 257.0f, 457.0f ), Point2f( 249.0f, 506.0f ) };// 定義輸出的基本矩陣和掩碼Mat fundamentalMatrix, mask;// 使用 RANSAC 方法計算基本矩陣fundamentalMatrix = findFundamentalMat( points1, points2,FM_RANSAC, // 使用RANSAC方法1.0, // 點到極線的最大重投影誤差0.99, // 置信水平2000, // 最大迭代次數mask ); // 輸出掩碼// 打印結果cout << "Fundamental Matrix:\n" << fundamentalMatrix << endl;// 打印哪些點被認為是內點cout << "Inliers mask:\n";for ( size_t i = 0; i < mask.total(); ++i ){if ( mask.at< uchar >( i ) ){cout << "Point " << i + 1 << " is an inlier." << endl;}else{cout << "Point " << i + 1 << " is an outlier." << endl;}}return 0;
}
運行結果
Fundamental Matrix:
[-3.247212965698772e-20, -0.0008949509319799827, 0.704568065615863;0.0008949509319799836, 3.892534466973619e-19, 0.229349120734492;-0.7144125258676433, -0.2338238753943923, 1]
Inliers mask:
Point 1 is an inlier.
Point 2 is an inlier.
Point 3 is an inlier.
Point 4 is an inlier.
Point 5 is an inlier.
Point 6 is an inlier.
Point 7 is an inlier.
Point 8 is an inlier.