1. 程式人生 > >OpenCV3 外極線的繪製

OpenCV3 外極線的繪製

兩張視角相似的圖片,通過提取特徵點、描述子,然後進行匹配,再通過單應約束優化之後得到的匹配關係基本就是正確的匹配了。然後在此基礎上想畫出外極線,來驗證一下匹配的結果是否正確。於是就寫了一個簡單的函式。假設已經得到了匹配的特徵點了,下面的函式將會畫出這些點對應的外極線。

//畫出外極線,對應點已經經過了RANSAC優化
void DrawEpiLines(const Mat& img_1, const Mat& img_2, vector<Point2f>points1, vector<Point2f>points2){

	cv::Mat F = cv::findFundamentalMat(points1, points2, CV_FM_8POINT);
        //首先根據對應點計算出兩檢視的基礎矩陣,基礎矩陣包含了兩個相機的外引數關係

       std::vector<cv::Vec<float, 3>> epilines1, epilines2;
	cv::computeCorrespondEpilines(points1, 1, F, epilines1);//計算對應點的外極線epilines是一個三元組(a,b,c),表示點在另一檢視中對應的外極線ax+by+c=0;
        cv::computeCorrespondEpilines(points2, 2, F, epilines2);
	//將圖片轉換為RGB圖,畫圖的時候外極線用彩色繪製
	cv::Mat img1, img2;
	if (img_1.type() == CV_8UC3)
	{
		 img_1.copyTo(img1);
		 img_2.copyTo(img2);
	 }
	 else if (img_1.type() == CV_8UC1)
	 {
		 cvtColor(img_1, img1, COLOR_GRAY2BGR);
		 cvtColor(img_2, img2, COLOR_GRAY2BGR);
	 }
	 else
	 {
		 cout << "unknow img type\n" << endl;
		 exit(0);
	 }

	 cv::RNG& rng = theRNG();
	 for (uint i = 0; i < points2.size(); i++)
	{
		Scalar color = Scalar(rng(256), rng(256), rng(256));//隨機產生顏色

		circle(img2, points2[i], 5, color);//在檢視2中把關鍵點用圓圈畫出來,然後再繪製在對應點處的外極線
		line(img2, Point(0, -epilines1[i][2] / epilines1[i][1]), Point(img2.cols, -(epilines1[i][2] + epilines1[i][0] * img2.cols) / epilines1[i][1]), color);
                //繪製外極線的時候,選擇兩個點,一個是x=0處的點,一個是x為圖片寬度處
		 circle(img1, points1[i], 4, color);
		 line(img1, cv::Point(0, -epilines2[i][2] / epilines2[i][1]), cv::Point(img1.cols, -(epilines2[i][2] + epilines2[i][0] * img1.cols) / epilines2[i][1]), color);
		
 	}
 	cv::imshow("img2 epiline1", img2);
	cv::imshow("img1 epiline2", img1);

	waitKey(0);
}