bf99ec79e00c8430fd7f18c1ec112645f1eb5bcc
[platform/upstream/opencv.git] / samples / cpp / brief_match_test.cpp
1 /*
2  * matching_test.cpp
3  *
4  *  Created on: Oct 17, 2010
5  *      Author: ethan
6  */
7 #include "opencv2/core.hpp"
8 #include <opencv2/core/utility.hpp>
9 #include "opencv2/calib3d.hpp"
10 #include "opencv2/features2d.hpp"
11 #include "opencv2/imgproc.hpp"
12 #include "opencv2/highgui.hpp"
13 #include <vector>
14 #include <iostream>
15
16 using namespace cv;
17 using namespace std;
18
19 //Copy (x,y) location of descriptor matches found from KeyPoint data structures into Point2f vectors
20 static void matches2points(const vector<DMatch>& matches, const vector<KeyPoint>& kpts_train,
21                     const vector<KeyPoint>& kpts_query, vector<Point2f>& pts_train, vector<Point2f>& pts_query)
22 {
23   pts_train.clear();
24   pts_query.clear();
25   pts_train.reserve(matches.size());
26   pts_query.reserve(matches.size());
27   for (size_t i = 0; i < matches.size(); i++)
28   {
29     const DMatch& match = matches[i];
30     pts_query.push_back(kpts_query[match.queryIdx].pt);
31     pts_train.push_back(kpts_train[match.trainIdx].pt);
32   }
33
34 }
35
36 static double match(const vector<KeyPoint>& /*kpts_train*/, const vector<KeyPoint>& /*kpts_query*/, DescriptorMatcher& matcher,
37             const Mat& train, const Mat& query, vector<DMatch>& matches)
38 {
39
40   double t = (double)getTickCount();
41   matcher.match(query, train, matches); //Using features2d
42   return ((double)getTickCount() - t) / getTickFrequency();
43 }
44
45 static void help()
46 {
47        cout << "This program shows how to use BRIEF descriptor to match points in features2d" << endl <<
48                "It takes in two images, finds keypoints and matches them displaying matches and final homography warped results" << endl <<
49                 "Usage: " << endl <<
50                     "image1 image2 " << endl <<
51                 "Example: " << endl <<
52                     "box.png box_in_scene.png " << endl;
53 }
54
55 const char* keys =
56 {
57     "{@first_image  | box.png          | the first image}"
58     "{@second_image | box_in_scene.png | the second image}"
59 };
60
61 int main(int argc, const char ** argv)
62 {
63
64   help();
65   CommandLineParser parser(argc, argv, keys);
66   string im1_name = parser.get<string>(0);
67   string im2_name = parser.get<string>(1);
68
69   Mat im1 = imread(im1_name, IMREAD_GRAYSCALE);
70   Mat im2 = imread(im2_name, IMREAD_GRAYSCALE);
71
72   if (im1.empty() || im2.empty())
73   {
74     cout << "could not open one of the images..." << endl;
75     cout << "the cmd parameters have next current value: " << endl;
76     parser.printMessage();
77     return 1;
78   }
79
80   double t = (double)getTickCount();
81
82   FastFeatureDetector detector(50);
83   BriefDescriptorExtractor extractor(32); //this is really 32 x 8 matches since they are binary matches packed into bytes
84
85   vector<KeyPoint> kpts_1, kpts_2;
86   detector.detect(im1, kpts_1);
87   detector.detect(im2, kpts_2);
88
89   t = ((double)getTickCount() - t) / getTickFrequency();
90
91   cout << "found " << kpts_1.size() << " keypoints in " << im1_name << endl << "fount " << kpts_2.size()
92       << " keypoints in " << im2_name << endl << "took " << t << " seconds." << endl;
93
94   Mat desc_1, desc_2;
95
96   cout << "computing descriptors..." << endl;
97
98   t = (double)getTickCount();
99
100   extractor.compute(im1, kpts_1, desc_1);
101   extractor.compute(im2, kpts_2, desc_2);
102
103   t = ((double)getTickCount() - t) / getTickFrequency();
104
105   cout << "done computing descriptors... took " << t << " seconds" << endl;
106
107   //Do matching using features2d
108   cout << "matching with BruteForceMatcher<Hamming>" << endl;
109   BFMatcher matcher_popcount(extractor.defaultNorm());
110   vector<DMatch> matches_popcount;
111   double pop_time = match(kpts_1, kpts_2, matcher_popcount, desc_1, desc_2, matches_popcount);
112   cout << "done BruteForceMatcher<Hamming> matching. took " << pop_time << " seconds" << endl;
113
114   vector<Point2f> mpts_1, mpts_2;
115   matches2points(matches_popcount, kpts_1, kpts_2, mpts_1, mpts_2); //Extract a list of the (x,y) location of the matches
116   vector<char> outlier_mask;
117   Mat H = findHomography(mpts_2, mpts_1, RANSAC, 1, outlier_mask);
118
119   Mat outimg;
120   drawMatches(im2, kpts_2, im1, kpts_1, matches_popcount, outimg, Scalar::all(-1), Scalar::all(-1), outlier_mask);
121   imshow("matches - popcount - outliers removed", outimg);
122
123   Mat warped;
124   Mat diff;
125   warpPerspective(im2, warped, H, im1.size());
126   imshow("warped", warped);
127   absdiff(im1,warped,diff);
128   imshow("diff", diff);
129   waitKey();
130   return 0;
131 }