두 장의 영상에서 추출한 특징점을 매칭하고, 매칭 정보를 이용하여 호모그래피를 계산하는 예제 코드를 코드 14-8에 나타냈습니다. 코드 14-8의 find_homography() 함수는 box.png 영상과 box_in_scene.png 영상에서 추출한 ORB 특징점을 이용하여 매칭을 수행하고, 매칭 정보로부터 두 영상 사이의 호모그래피를 계산합니다. 그리고 계산된 호모그래피를 이용하여 box_in_scene.png 장면 영상에서 box.png 스낵 박스가 있는 위치를 검출합니다. find_homography() 함수가 정의된 소스 파일과 사용된 영상 파일은 내려받은 예제 파일 중 ch14/matching 프로젝트에서 확인할 수 있습니다.
코드 14-8 키포인트 매칭 및 호모그래피 계산 예제 [ch14/matching]
01 void find_homography() 02 { 03 Mat src1 = imread("box.png", IMREAD_GRAYSCALE); 04 Mat src2 = imread("box_in_scene.png", IMREAD_GRAYSCALE); 05 06 if (src1.empty() || src2.empty()) { 07 cerr << "Image load failed!" << endl; 08 return; 09 } 10 11 Ptr<Feature2D> orb = ORB::create(); 12 13 vector<KeyPoint> keypoints1, keypoints2; 14 Mat desc1, desc2; 15 orb->detectAndCompute(src1, Mat(), keypoints1, desc1); 16 orb->detectAndCompute(src2, Mat(), keypoints2, desc2); 17 18 Ptr<DescriptorMatcher> matcher = BFMatcher::create(NORM_HAMMING); 19 20 vector<DMatch> matches; 21 matcher->match(desc1, desc2, matches); 22 23 std::sort(matches.begin(), matches.end()); 24 vector<DMatch> good_matches(matches.begin(), matches.begin() + 50); 25 26 Mat dst; 27 drawMatches(src1, keypoints1, src2, keypoints2, good_matches, dst, 28 Scalar::all(-1), Scalar::all(-1), vector<char>(), 29 DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS); 30 31 vector<Point2f> pts1, pts2; 32 for (size_t i = 0; i < good_matches.size(); i++) { 33 pts1.push_back(keypoints1[good_matches[i].queryIdx].pt); 34 pts2.push_back(keypoints2[good_matches[i].trainIdx].pt); 35 } 36 37 Mat H = findHomography(pts1, pts2, RANSAC); 38 39 vector<Point2f> corners1, corners2; 40 corners1.push_back(Point2f(0, 0)); 41 corners1.push_back(Point2f(src1.cols - 1.f, 0)); 42 corners1.push_back(Point2f(src1.cols - 1.f, src1.rows - 1.f)); 43 corners1.push_back(Point2f(0, src1.rows - 1.f)); 44 perspectiveTransform(corners1, corners2, H); 45 46 vector<Point> corners_dst; 47 for (Point2f pt : corners2) { 48 corners_dst.push_back(Point(cvRound(pt.x + src1.cols), cvRound(pt.y))); 49 } 50 51 polylines(dst, corners_dst, true, Scalar(0, 255, 0), 2, LINE_AA); 52 53 imshow("dst", dst); 54 55 waitKey(); 56 destroyAllWindows(); 57 }
• 31~35행 good_matches 매칭 결과에 저장된 질의 영상과 훈련 영상의 특징점 좌표를 추출하여 vector <Point2f> 타입의 변수 pts1, pts2에 저장합니다.
• 37행 pts1 점들이 pts2 점들로 이동하는 호모그래피 행렬을 구하여 H에 저장합니다. 호모그래피 계산 방법은 RANSAC 알고리즘을 사용합니다.
• 39~44행 src1 영상의 네 모서리 점을 corners1에 저장한 후, 호모그래피 행렬 H를 이용하여 이 점들이 이동하는 위치를 계산하여 corners2에 저장합니다.
• 46~49행 매칭 결과 영상 dst에서 corner2 점들이 위치하는 좌표를 corners_dst에 저장합니다.
• 51행 매칭 결과 영상 dst에서 box.png 스낵 박스가 있는 위치에 녹색으로 사각형을 그립니다.