4 * Created on: Oct 18, 2010
8 #include "opencv2/calib3d/calib3d.hpp"
9 #include "opencv2/highgui/highgui.hpp"
10 #include "opencv2/imgproc/imgproc.hpp"
11 #include "opencv2/features2d/features2d.hpp"
21 cout << "\nThis program demonstrated the use of features2d with the Fast corner detector and brief descriptors\n"
22 << "to track planar objects by computing their homography from the key (training) image to the query (test) image\n\n" << endl;
23 cout << "usage: " << av[0] << " <video device number>\n" << endl;
24 cout << "The following keys do stuff:" << endl;
25 cout << " t : grabs a reference frame to match against" << endl;
26 cout << " l : makes the reference frame new every frame" << endl;
27 cout << " q or escape: quit" << endl;
32 void drawMatchesRelative(const vector<KeyPoint>& train, const vector<KeyPoint>& query,
33 std::vector<cv::DMatch>& matches, Mat& img, const vector<unsigned char>& mask = vector<
36 for (int i = 0; i < (int)matches.size(); i++)
38 if (mask.empty() || mask[i])
40 Point2f pt_new = query[matches[i].queryIdx].pt;
41 Point2f pt_old = train[matches[i].trainIdx].pt;
43 cv::line(img, pt_new, pt_old, Scalar(125, 255, 125), 1);
44 cv::circle(img, pt_new, 2, Scalar(255, 0, 125), 1);
50 //Takes a descriptor and turns it into an xy point
51 void keypoints2points(const vector<KeyPoint>& in, vector<Point2f>& out)
54 out.reserve(in.size());
55 for (size_t i = 0; i < in.size(); ++i)
57 out.push_back(in[i].pt);
61 //Takes an xy point and appends that to a keypoint structure
62 void points2keypoints(const vector<Point2f>& in, vector<KeyPoint>& out)
65 out.reserve(in.size());
66 for (size_t i = 0; i < in.size(); ++i)
68 out.push_back(KeyPoint(in[i], 1));
72 //Uses computed homography H to warp original input points to new planar position
73 void warpKeypoints(const Mat& H, const vector<KeyPoint>& in, vector<KeyPoint>& out)
76 keypoints2points(in, pts);
77 vector<Point2f> pts_w(pts.size());
79 perspectiveTransform(Mat(pts), m_pts_w, H);
80 points2keypoints(pts_w, out);
83 //Converts matching indices to xy points
84 void matches2points(const vector<KeyPoint>& train, const vector<KeyPoint>& query,
85 const std::vector<cv::DMatch>& matches, std::vector<cv::Point2f>& pts_train,
86 std::vector<Point2f>& pts_query)
91 pts_train.reserve(matches.size());
92 pts_query.reserve(matches.size());
96 for (; i < matches.size(); i++)
99 const DMatch & dmatch = matches[i];
101 pts_query.push_back(query[dmatch.queryIdx].pt);
102 pts_train.push_back(train[dmatch.trainIdx].pt);
110 H = Mat::eye(3, 3, CV_32FC1);
114 int main(int ac, char ** av)
123 BriefDescriptorExtractor brief(32);
125 VideoCapture capture;
126 capture.open(atoi(av[1]));
127 if (!capture.isOpened())
130 cout << "capture device " << atoi(av[1]) << " failed to open!" << endl;
134 cout << "following keys do stuff:" << endl;
135 cout << "t : grabs a reference frame to match against" << endl;
136 cout << "l : makes the reference frame new every frame" << endl;
137 cout << "q or escape: quit" << endl;
141 vector<DMatch> matches;
143 BFMatcher desc_matcher(NORM_HAMMING);
145 vector<Point2f> train_pts, query_pts;
146 vector<KeyPoint> train_kpts, query_kpts;
147 vector<unsigned char> match_mask;
151 bool ref_live = true;
153 Mat train_desc, query_desc;
154 const int DESIRED_FTRS = 500;
155 GridAdaptedFeatureDetector detector(new FastFeatureDetector(10, true), DESIRED_FTRS, 4, 4);
157 Mat H_prev = Mat::eye(3, 3, CV_32FC1);
164 cvtColor(frame, gray, CV_RGB2GRAY);
166 detector.detect(gray, query_kpts); //Find interest points
168 brief.compute(gray, query_kpts, query_desc); //Compute brief descriptors at each keypoint location
170 if (!train_kpts.empty())
173 vector<KeyPoint> test_kpts;
174 warpKeypoints(H_prev.inv(), query_kpts, test_kpts);
176 Mat mask = windowedMatchingMask(test_kpts, train_kpts, 25, 25);
177 desc_matcher.match(query_desc, train_desc, matches, mask);
178 drawKeypoints(frame, test_kpts, frame, Scalar(255, 0, 0), DrawMatchesFlags::DRAW_OVER_OUTIMG);
180 matches2points(train_kpts, query_kpts, matches, train_pts, query_pts);
182 if (matches.size() > 5)
184 Mat H = findHomography(train_pts, query_pts, RANSAC, 4, match_mask);
185 if (countNonZero(Mat(match_mask)) > 15)
191 drawMatchesRelative(train_kpts, query_kpts, matches, frame, match_mask);
199 H_prev = Mat::eye(3, 3, CV_32FC1);
201 drawKeypoints(gray, query_kpts, out);
205 imshow("frame", frame);
209 train_kpts = query_kpts;
210 query_desc.copyTo(train_desc);
212 char key = (char)waitKey(2);
221 train_kpts = query_kpts;
222 query_desc.copyTo(train_desc);