더북(TheBook)

두 장의 영상에서 추출한 특징점을 매칭하고, 매칭 정보를 이용하여 호모그래피를 계산하는 예제 코드를 코드 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 스낵 박스가 있는 위치에 녹색으로 사각형을 그립니다.

신간 소식 구독하기
뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.