mirror of https://github.com/opencv/opencv.git
parent
d84b970bf2
commit
5915e4c7ee
3 changed files with 366 additions and 0 deletions
@ -0,0 +1,118 @@ |
||||
/*
|
||||
* matching_test.cpp |
||||
* |
||||
* Created on: Oct 17, 2010 |
||||
* Author: ethan |
||||
*/ |
||||
#include <opencv2/opencv.hpp> |
||||
#include <vector> |
||||
#include <iostream> |
||||
|
||||
using namespace cv; |
||||
|
||||
using std::cout; |
||||
using std::cerr; |
||||
using std::endl; |
||||
using std::vector; |
||||
|
||||
void matches2points(const vector<DMatch>& matches, const vector<KeyPoint>& kpts_train, |
||||
const vector<KeyPoint>& kpts_query, vector<Point2f>& pts_train, vector<Point2f>& pts_query) |
||||
{ |
||||
pts_train.clear(); |
||||
pts_query.clear(); |
||||
pts_train.reserve(matches.size()); |
||||
pts_query.reserve(matches.size()); |
||||
for (size_t i = 0; i < matches.size(); i++) |
||||
{ |
||||
const DMatch& match = matches[i]; |
||||
pts_query.push_back(kpts_query[match.queryIdx].pt); |
||||
pts_train.push_back(kpts_train[match.trainIdx].pt); |
||||
} |
||||
|
||||
} |
||||
|
||||
float match(const vector<KeyPoint>& kpts_train, const vector<KeyPoint>& kpts_query, DescriptorMatcher& matcher, |
||||
const Mat& train, const Mat& query, vector<DMatch>& matches) |
||||
{ |
||||
|
||||
float t = (double)getTickCount(); |
||||
matcher.match(query, train, matches); |
||||
return ((double)getTickCount() - t) / getTickFrequency(); |
||||
} |
||||
|
||||
int main(int ac, char ** av) |
||||
{ |
||||
if (ac != 3) |
||||
{ |
||||
cerr << "usage: " << av[0] << " im1.jpg im2.jpg" << endl; |
||||
return 1; |
||||
} |
||||
string im1_name, im2_name; |
||||
im1_name = av[1]; |
||||
im2_name = av[2]; |
||||
|
||||
Mat im1 = imread(im1_name, CV_LOAD_IMAGE_GRAYSCALE); |
||||
Mat im2 = imread(im2_name, CV_LOAD_IMAGE_GRAYSCALE); |
||||
|
||||
if (im1.empty() || im2.empty()) |
||||
{ |
||||
cerr << "could not open one of the images..." << endl; |
||||
return 1; |
||||
} |
||||
|
||||
double t = (double)getTickCount(); |
||||
|
||||
FastFeatureDetector detector(50); |
||||
BriefDescriptorExtractor extractor(32); |
||||
|
||||
vector<KeyPoint> kpts_1, kpts_2; |
||||
detector.detect(im1, kpts_1); |
||||
detector.detect(im2, kpts_2); |
||||
|
||||
t = ((double)getTickCount() - t) / getTickFrequency(); |
||||
|
||||
cout << "found " << kpts_1.size() << " keypoints in " << im1_name << endl << "fount " << kpts_2.size() |
||||
<< " keypoints in " << im2_name << endl << "took " << t << " seconds." << endl; |
||||
|
||||
Mat desc_1, desc_2; |
||||
|
||||
cout << "computing descriptors..." << endl; |
||||
|
||||
t = (double)getTickCount(); |
||||
|
||||
extractor.compute(im1, kpts_1, desc_1); |
||||
extractor.compute(im2, kpts_2, desc_2); |
||||
|
||||
t = ((double)getTickCount() - t) / getTickFrequency(); |
||||
|
||||
cout << "done computing descriptors... took " << t << " seconds" << endl; |
||||
|
||||
cout << "matching with BruteForceMatcher<HammingLUT>" << endl; |
||||
BruteForceMatcher<HammingLUT> matcher; |
||||
vector<DMatch> matches_lut; |
||||
float lut_time = match(kpts_1, kpts_2, matcher, desc_1, desc_2, matches_lut); |
||||
cout << "done BruteForceMatcher<HammingLUT> matching. took " << lut_time << " seconds" << endl; |
||||
|
||||
cout << "matching with BruteForceMatcher<Hamming>" << endl; |
||||
BruteForceMatcher<Hamming> matcher_popcount; |
||||
vector<DMatch> matches_popcount; |
||||
float pop_time = match(kpts_1, kpts_2, matcher_popcount, desc_1, desc_2, matches_popcount); |
||||
cout << "done BruteForceMatcher<Hamming> matching. took " << pop_time << " seconds" << endl; |
||||
|
||||
vector<Point2f> mpts_1, mpts_2; |
||||
matches2points(matches_popcount, kpts_1, kpts_2, mpts_1, mpts_2); |
||||
vector<uchar> outlier_mask; |
||||
Mat H = findHomography(Mat(mpts_2), Mat(mpts_1), outlier_mask, RANSAC, 1); |
||||
|
||||
Mat outimg; |
||||
drawMatches(im2, kpts_2, im1, kpts_1, matches_popcount, outimg, Scalar::all(-1), Scalar::all(-1), |
||||
reinterpret_cast<const vector<char>&> (outlier_mask)); |
||||
imshow("matches - popcount - outliers removed", outimg); |
||||
|
||||
Mat warped; |
||||
warpPerspective(im2, warped, H, im1.size()); |
||||
imshow("warped", warped); |
||||
imshow("diff", im1 - warped); |
||||
waitKey(); |
||||
return 0; |
||||
} |
@ -0,0 +1,34 @@ |
||||
#include "opencv2/core/core.hpp" |
||||
|
||||
using namespace std; |
||||
using namespace cv; |
||||
|
||||
int main() |
||||
{ |
||||
Mat i = Mat::eye(4, 4, CV_32F); |
||||
cout << "i = " << i << ";" << endl; |
||||
|
||||
Mat r = Mat(10, 10, CV_8UC1); |
||||
randu(r, Scalar(0), Scalar(255)); |
||||
|
||||
cout << "r = " << r << ";" << endl; |
||||
|
||||
Point2f p(5, 1); |
||||
cout << "p = " << p << ";" << endl; |
||||
|
||||
Point3f p3f(2, 6, 7); |
||||
cout << "p3f = " << p3f << ";" << endl; |
||||
|
||||
vector<Point2f> points(20); |
||||
for (size_t i = 0; i < points.size(); ++i) |
||||
{ |
||||
points[i] = Point2f(i * 5, i % 7); |
||||
} |
||||
cout << "points = " << points << ";" << endl; |
||||
|
||||
cout << "#csv" << endl; |
||||
|
||||
writeCSV(cout, r); |
||||
|
||||
return 1; |
||||
} |
@ -0,0 +1,214 @@ |
||||
/*
|
||||
* video_homography.cpp |
||||
* |
||||
* Created on: Oct 18, 2010 |
||||
* Author: erublee |
||||
*/ |
||||
|
||||
#include <opencv2/opencv.hpp> |
||||
#include <iostream> |
||||
#include <list> |
||||
#include <vector> |
||||
|
||||
using namespace std; |
||||
using namespace cv; |
||||
|
||||
namespace |
||||
{ |
||||
void drawMatchesRelative(const vector<KeyPoint>& train, const vector<KeyPoint>& query, |
||||
std::vector<cv::DMatch>& matches, Mat& img, const vector<unsigned char>& mask = vector< |
||||
unsigned char> ()) |
||||
{ |
||||
for (int i = 0; i < (int)matches.size(); i++) |
||||
{ |
||||
if (mask.empty() || mask[i]) |
||||
{ |
||||
Point2f pt_new = query[matches[i].queryIdx].pt; |
||||
Point2f pt_old = train[matches[i].trainIdx].pt; |
||||
Point2f dist = pt_new - pt_old; |
||||
|
||||
cv::line(img, pt_new, pt_old, Scalar(125, 255, 125), 1); |
||||
cv::circle(img, pt_new, 2, Scalar(255, 0, 125), 1); |
||||
|
||||
} |
||||
} |
||||
} |
||||
|
||||
void keypoints2points(const vector<KeyPoint>& in, vector<Point2f>& out) |
||||
{ |
||||
out.clear(); |
||||
out.reserve(in.size()); |
||||
for (size_t i = 0; i < in.size(); ++i) |
||||
{ |
||||
out.push_back(in[i].pt); |
||||
} |
||||
} |
||||
|
||||
void points2keypoints(const vector<Point2f>& in, vector<KeyPoint>& out) |
||||
{ |
||||
out.clear(); |
||||
out.reserve(in.size()); |
||||
for (size_t i = 0; i < in.size(); ++i) |
||||
{ |
||||
out.push_back(KeyPoint(in[i], 1)); |
||||
} |
||||
} |
||||
|
||||
void warpKeypoints(const Mat& H, const vector<KeyPoint>& in, vector<KeyPoint>& out) |
||||
{ |
||||
vector<Point2f> pts; |
||||
keypoints2points(in, pts); |
||||
vector<Point2f> pts_w(pts.size()); |
||||
Mat m_pts_w(pts_w); |
||||
perspectiveTransform(Mat(pts), m_pts_w, H); |
||||
points2keypoints(pts_w, out); |
||||
} |
||||
|
||||
void matches2points(const vector<KeyPoint>& train, const vector<KeyPoint>& query, |
||||
const std::vector<cv::DMatch>& matches, std::vector<cv::Point2f>& pts_train, |
||||
std::vector<Point2f>& pts_query) |
||||
{ |
||||
|
||||
pts_train.clear(); |
||||
pts_query.clear(); |
||||
pts_train.reserve(matches.size()); |
||||
pts_query.reserve(matches.size()); |
||||
|
||||
size_t i = 0; |
||||
|
||||
for (; i < matches.size(); i++) |
||||
{ |
||||
|
||||
const DMatch & dmatch = matches[i]; |
||||
|
||||
pts_query.push_back(query[dmatch.queryIdx].pt); |
||||
pts_train.push_back(train[dmatch.trainIdx].pt); |
||||
|
||||
} |
||||
|
||||
} |
||||
|
||||
void resetH(Mat&H) |
||||
{ |
||||
H = Mat::eye(3, 3, CV_32FC1); |
||||
} |
||||
} |
||||
int main(int ac, char ** av) |
||||
{ |
||||
|
||||
if (ac != 2) |
||||
{ |
||||
cout << "usage: " << av[0] << " <video device number>" << endl; |
||||
return 1; |
||||
} |
||||
|
||||
BriefDescriptorExtractor brief(32); |
||||
|
||||
VideoCapture capture; |
||||
capture.open(atoi(av[1])); |
||||
if (!capture.isOpened()) |
||||
{ |
||||
cout << "capture device " << atoi(av[1]) << " failed to open!" << endl; |
||||
return 1; |
||||
} |
||||
|
||||
cout << "following keys do stuff:" << endl; |
||||
cout << "t : grabs a reference frame to match against" << endl; |
||||
cout << "l : makes the reference frame new every frame" << endl; |
||||
cout << "q or escape: quit" << endl; |
||||
|
||||
Mat frame; |
||||
|
||||
vector<DMatch> matches; |
||||
|
||||
BruteForceMatcher<Hamming> desc_matcher; |
||||
|
||||
vector<Point2f> train_pts, query_pts; |
||||
vector<KeyPoint> train_kpts, query_kpts; |
||||
vector<unsigned char> match_mask; |
||||
|
||||
Mat gray; |
||||
|
||||
bool ref_live = true; |
||||
|
||||
Mat train_desc, query_desc; |
||||
const int DESIRED_FTRS = 500; |
||||
GridAdaptedFeatureDetector detector(new FastFeatureDetector(10, true), DESIRED_FTRS, 4, 4); |
||||
|
||||
Mat H_prev = Mat::eye(3, 3, CV_32FC1); |
||||
for (;;) |
||||
{ |
||||
capture >> frame; |
||||
if (frame.empty()) |
||||
continue; |
||||
|
||||
cvtColor(frame, gray, CV_RGB2GRAY); |
||||
|
||||
detector.detect(gray, query_kpts); |
||||
|
||||
brief.compute(gray, query_kpts, query_desc); |
||||
|
||||
if (!train_kpts.empty()) |
||||
{ |
||||
|
||||
vector<KeyPoint> test_kpts; |
||||
warpKeypoints(H_prev.inv(), query_kpts, test_kpts); |
||||
|
||||
Mat mask = windowedMatchingMask(test_kpts, train_kpts, 25, 25); |
||||
desc_matcher.match(query_desc, train_desc, matches, mask); |
||||
drawKeypoints(frame, test_kpts, frame, Scalar(255, 0, 0), DrawMatchesFlags::DRAW_OVER_OUTIMG); |
||||
|
||||
matches2points(train_kpts, query_kpts, matches, train_pts, query_pts); |
||||
|
||||
if (matches.size() > 5) |
||||
{ |
||||
Mat H = findHomography(Mat(train_pts), Mat(query_pts), match_mask, RANSAC, 4); |
||||
if (countNonZero(Mat(match_mask)) > 15) |
||||
{ |
||||
H_prev = H; |
||||
} |
||||
else |
||||
resetH(H_prev); |
||||
drawMatchesRelative(train_kpts, query_kpts, matches, frame, match_mask); |
||||
} |
||||
else |
||||
resetH(H_prev); |
||||
|
||||
} |
||||
else |
||||
{ |
||||
H_prev = Mat::eye(3, 3, CV_32FC1); |
||||
Mat out; |
||||
drawKeypoints(gray, query_kpts, out); |
||||
frame = out; |
||||
} |
||||
|
||||
imshow("frame", frame); |
||||
|
||||
if (ref_live) |
||||
{ |
||||
train_kpts = query_kpts; |
||||
query_desc.copyTo(train_desc); |
||||
} |
||||
char key = waitKey(2); |
||||
switch (key) |
||||
{ |
||||
case 'l': |
||||
ref_live = true; |
||||
resetH(H_prev); |
||||
break; |
||||
case 't': |
||||
ref_live = false; |
||||
train_kpts = query_kpts; |
||||
query_desc.copyTo(train_desc); |
||||
resetH(H_prev); |
||||
break; |
||||
case 27: |
||||
case 'q': |
||||
return 0; |
||||
break; |
||||
} |
||||
|
||||
} |
||||
return 0; |
||||
} |
Loading…
Reference in new issue