Skip to content

Commit a6f750a

Browse files
committed
feature based image alignment
1 parent 79acbe5 commit a6f750a

File tree

3 files changed

+78
-0
lines changed

3 files changed

+78
-0
lines changed

ImageAlignment-FeatureBased/align.cpp

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
#include <opencv2/opencv.hpp>
2+
#include "opencv2/xfeatures2d.hpp"
3+
#include "opencv2/features2d.hpp"
4+
5+
using namespace std;
6+
using namespace cv;
7+
using namespace cv::xfeatures2d;
8+
9+
const int MAX_MATCHES = 500;
10+
const float GOOD_MATCH_PERCENT = 0.15f;
11+
12+
13+
void alignImages(Mat &im1, Mat &im2, Mat &im1Reg, Mat &h)
14+
15+
{
16+
17+
// Convert images to grayscale
18+
Mat im1Gray, im2Gray;
19+
cvtColor(im1, im1Gray, CV_BGR2GRAY);
20+
cvtColor(im2, im2Gray, CV_BGR2GRAY);
21+
22+
// Variables to store keypoints and descriptors
23+
std::vector<KeyPoint> keypoints1, keypoints2;
24+
Mat descriptors1, descriptors2;
25+
26+
// Detect ORB features and compute descriptors.
27+
Ptr<Feature2D> orb = ORB::create(MAX_MATCHES);
28+
orb->detectAndCompute(im1Gray, Mat(), keypoints1, descriptors1);
29+
orb->detectAndCompute(im2Gray, Mat(), keypoints2, descriptors2);
30+
31+
// Match features.
32+
std::vector<DMatch> matches;
33+
Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create("BruteForce-Hamming");
34+
matcher->match(descriptors1, descriptors2, matches, Mat());
35+
36+
// Sort matches by score
37+
std::sort(matches.begin(), matches.end());
38+
39+
// Remove not so good matches
40+
const int numGoodMatches = matches.size() * GOOD_MATCH_PERCENT;
41+
matches.erase(matches.begin()+numGoodMatches, matches.end());
42+
43+
44+
// Draw top matches
45+
Mat imMatches;
46+
drawMatches(im1, keypoints1, im2, keypoints2, matches, imMatches);
47+
imwrite("matches.jpg", imMatches);
48+
49+
50+
// Extract location of good matches
51+
std::vector<Point2f> points1;
52+
std::vector<Point2f> points2;
53+
54+
for( size_t i = 0; i < matches.size(); i++ )
55+
{
56+
points1.push_back( keypoints1[ matches[i].queryIdx ].pt );
57+
points2.push_back( keypoints2[ matches[i].trainIdx ].pt );
58+
}
59+
60+
// Find homography
61+
h = findHomography( points1, points2, RANSAC );
62+
63+
// Use homography
64+
warpPerspective(im1, im1Reg, h, im2.size());
65+
66+
}
67+
68+
69+
int main(int argc, char **argv)
70+
{
71+
Mat imReference = imread("form.jpg");
72+
Mat im = imread("scanned-form.jpg");
73+
Mat imReg, h;
74+
75+
alignImages(im, imReference, imReg, h);
76+
imwrite("aligned.jpg", imReg);
77+
78+
}

ImageAlignment-FeatureBased/form.jpg

330 KB
Loading
345 KB
Loading

0 commit comments

Comments
 (0)