#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/imgproc/imgproc_c.h"
#include "opencv2/imgproc/imgproc.hpp"
#include
#include
#include
using
namespace
std;
using
namespace
cv;
char
* image_filename1 =
"apple_vinegar_0.png"
;
char
* image_filename2 =
"apple_vinegar_2.png"
;
unsigned
int
hamdist(unsigned
int
x, unsigned
int
y)
{
unsigned
int
dist = 0, val = x ^ y;
// Count the number of set bits
while
(val)
{
++dist;
val &= val - 1;
}
return
dist;
}
unsigned
int
hamdist2(unsigned
char
* a, unsigned
char
* b,
size_t
size)
{
HammingLUT lut;
unsigned
int
result;
result = lut((a), (b), size);
return
result;
}
void
naive_nn_search(vector& keys1, Mat& descp1,
vector& keys2, Mat& descp2,
vector& matches)
{
for
(
int
i = 0; i < (
int
)keys2.size(); i++){
unsigned
int
min_dist = INT_MAX;
int
min_idx = -1;
unsigned
char
* query_feat = descp2.ptr(i);
for
(
int
j = 0; j < (
int
)keys1.size(); j++){
unsigned
char
* train_feat = descp1.ptr(j);
unsigned
int
dist = hamdist2(query_feat, train_feat, 32);
if
(dist < min_dist){
min_dist = dist;
min_idx = j;
}
}
//if(min_dist <= (unsigned int)(second_dist * 0.8)){
if
(min_dist <= 50){
matches.push_back(DMatch(i, min_idx, 0, (
float
)min_dist));
}
}
}
void
naive_nn_search2(vector& keys1, Mat& descp1,
vector& keys2, Mat& descp2,
vector& matches)
{
for
(
int
i = 0; i < (
int
)keys2.size(); i++){
unsigned
int
min_dist = INT_MAX;
unsigned
int
sec_dist = INT_MAX;
int
min_idx = -1, sec_idx = -1;
unsigned
char
* query_feat = descp2.ptr(i);
for
(
int
j = 0; j < (
int
)keys1.size(); j++){
unsigned
char
* train_feat = descp1.ptr(j);
unsigned
int
dist = hamdist2(query_feat, train_feat, 32);
if
(dist < min_dist){
sec_dist = min_dist;
sec_idx = min_idx;
min_dist = dist;
min_idx = j;
}
else
if
(dist < sec_dist){
sec_dist = dist;
sec_idx = j;
}
}
if
(min_dist <= (unsigned
int
)(sec_dist * 0.8) && min_dist <=50){
//if(min_dist <= 50){
matches.push_back(DMatch(i, min_idx, 0, (
float
)min_dist));
}
}
}
int
main(
int
argc,
char
* argv[])
{
Mat img1 = imread(image_filename1, 0);
Mat img2 = imread(image_filename2, 0);
//GaussianBlur(img1, img1, Size(5, 5), 0);
//GaussianBlur(img2, img2, Size(5, 5), 0);
ORB orb1(3000, ORB::CommonParams(1.2, 8));
ORB orb2(100, ORB::CommonParams(1.2, 1));
vector keys1, keys2;
Mat descriptors1, descriptors2;
orb1(img1, Mat(), keys1, descriptors1,
false
);
printf
(
"tem feat num: %d\n"
, keys1.size());
int64 st, et;
st = cvGetTickCount();
orb2(img2, Mat(), keys2, descriptors2,
false
);
et = cvGetTickCount();
printf
(
"orb2 extraction time: %f\n"
, (et-st)/(
double
)cvGetTickFrequency()/1000.);
printf
(
"query feat num: %d\n"
, keys2.size());
// find matches
vector matches;
st = cvGetTickCount();
//for(int i = 0; i < 10; i++){
naive_nn_search2(keys1, descriptors1, keys2, descriptors2, matches);
//}
et = cvGetTickCount();
printf
(
"match time: %f\n"
, (et-st)/(
double
)cvGetTickFrequency()/1000.);
printf
(
"matchs num: %d\n"
, matches.size());
Mat showImg;
drawMatches(img2, keys2, img1, keys1, matches, showImg, CV_RGB(0, 255, 0), CV_RGB(0, 0, 255));
string winName =
"Matches"
;
namedWindow( winName, WINDOW_AUTOSIZE );
imshow( winName, showImg );
waitKey();
vector
pt1;
vector
pt2;
for
(
int
i = 0; i < (
int
)matches.size(); i++){
pt1.push_back(Point2f(keys2[matches[i].queryIdx].pt.x, keys2[matches[i].queryIdx].pt.y));
pt2.push_back(Point2f(keys1[matches[i].trainIdx].pt.x, keys1[matches[i].trainIdx].pt.y));
}
Mat homo;
st = cvGetTickCount();
homo = findHomography(pt1, pt2, Mat(), CV_RANSAC, 5);
et = cvGetTickCount();
printf
(
"ransac time: %f\n"
, (et-st)/(
double
)cvGetTickFrequency()/1000.);
printf
(
"homo\n"
"%f %f %f\n"
"%f %f %f\n"
"%f %f %f\n"
,
homo.at(0,0), homo.at(0,1), homo.at(0,2),
homo.at(1,0), homo.at(1,1), homo.at(1,2),
homo.at(2,0),homo.at(2,1),homo.at(2,2));
vector
reproj;
reproj.resize(pt1.size());
perspectiveTransform(pt1, reproj, homo);
Mat diff;
diff = Mat(reproj) - Mat(pt2);
int
inlier = 0;
double
err_sum = 0;
for
(
int
i = 0; i < diff.rows; i++){
float
* ptr = diff.ptr(i);
float
err = ptr[0]*ptr[0] + ptr[1]*ptr[1];
if
(err < 25.f){
inlier++;
err_sum +=
sqrt
(err);
}
}
printf
(
"inlier num: %d\n"
, inlier);
printf
(
"ratio %f\n"
, inlier / (
float
)(diff.rows));
printf
(
"mean reprojection error: %f\n"
, err_sum / inlier);
return
0;
}
#include <iostream>
#include "opencv2/core/core.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
#include <vector>
using namespace cv;
using namespace std;
int main()
{
Mat img_1 = imread("D:\\image\\img1.jpg");
Mat img_2 = imread("D:\\image\\img2.jpg");
if (!img_1.data || !img_2.data)
{
cout << "error reading images " << endl;
return -1;
}
ORB orb;
vector<KeyPoint> keyPoints_1, keyPoints_2;
Mat descriptors_1, descriptors_2;
orb(img_1, Mat(), keyPoints_1, descriptors_1);
orb(img_2, Mat(), keyPoints_2, descriptors_2);
BruteForceMatcher<HammingLUT> matcher;
vector<DMatch> matches;
matcher.match(descriptors_1, descriptors_2, matches);
double max_dist = 0; double min_dist = 100;
//-- Quick calculation of max and min distances between keypoints
for( int i = 0; i < descriptors_1.rows; i++ )
{
double dist = matches[i].distance;
if( dist < min_dist ) min_dist = dist;
if( dist > max_dist ) max_dist = dist;
}
printf("-- Max dist : %f \n", max_dist );
printf("-- Min dist : %f \n", min_dist );
//-- Draw only "good" matches (i.e. whose distance is less than 0.6*max_dist )
//-- PS.- radiusMatch can also be used here.
std::vector< DMatch > good_matches;
for( int i = 0; i < descriptors_1.rows; i++ )
{
if( matches[i].distance < 0.6*max_dist )
{
good_matches.push_back( matches[i]);
}
}
Mat img_matches;
drawMatches(img_1, keyPoints_1, img_2, keyPoints_2,
good_matches, img_matches, Scalar::all(-1), Scalar::all(-1),
vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);
imshow( "Match", img_matches);
cvWaitKey();
return 0;
}