32 #include <opencv2/core/core.hpp> 33 #include <opencv2/highgui/highgui.hpp> 34 #include <opencv2/features2d/features2d.hpp> 35 #include <opencv2/calib3d/calib3d.hpp> 36 #include <opencv2/opencv_modules.hpp> 38 #ifdef HAVE_OPENCV_NONFREE 39 #if CV_MAJOR_VERSION == 2 && CV_MINOR_VERSION >=4 40 #include <opencv2/nonfree/gpu.hpp> 41 #include <opencv2/nonfree/features2d.hpp> 44 #ifdef HAVE_OPENCV_XFEATURES2D 45 #include <opencv2/xfeatures2d.hpp> 46 #include <opencv2/xfeatures2d/cuda.hpp> 53 "Return similarity between two images (the number of similar features between the images).\n" 55 " ./find_object-similarity [option] object.png scene.png\n" 57 " -inliers return inliers percentage : inliers / (inliers + outliers)\n" 58 " -quiet don't show messages\n");
65 int main(
int argc,
char * argv[])
71 printf(
"Two images required!\n");
76 for(
int i=1; i<argc-2; ++i)
78 if(std::string(argv[i]).compare(
"-inliers") == 0)
82 else if(std::string(argv[i]).compare(
"-quiet") == 0)
88 printf(
"Option %s not recognized!", argv[1]);
96 cv::Mat objectImg = cv::imread(argv[argc-2], cv::IMREAD_GRAYSCALE);
97 cv::Mat sceneImg = cv::imread(argv[argc-1], cv::IMREAD_GRAYSCALE);
100 if(!objectImg.empty() && !sceneImg.empty())
102 std::vector<cv::KeyPoint> objectKeypoints;
103 std::vector<cv::KeyPoint> sceneKeypoints;
104 cv::Mat objectDescriptors;
105 cv::Mat sceneDescriptors;
107 #if CV_MAJOR_VERSION < 3 112 sift.detect(objectImg, objectKeypoints);
113 sift.detect(sceneImg, sceneKeypoints);
118 sift.compute(objectImg, objectKeypoints, objectDescriptors);
119 sift.compute(sceneImg, sceneKeypoints, sceneDescriptors);
124 cv::Ptr<cv::xfeatures2d::SIFT> sift = cv::xfeatures2d::SIFT::create();
125 sift->detect(objectImg, objectKeypoints);
126 sift->detect(sceneImg, sceneKeypoints);
131 sift->compute(objectImg, objectKeypoints, objectDescriptors);
132 sift->compute(sceneImg, sceneKeypoints, sceneDescriptors);
139 std::vector<std::vector<cv::DMatch> > matches;
143 cv::flann::Index flannIndex(sceneDescriptors, cv::flann::KDTreeIndexParams(), cvflann::FLANN_DIST_EUCLIDEAN);
144 results = cv::Mat(objectDescriptors.rows, k, CV_32SC1);
145 dists = cv::Mat(objectDescriptors.rows, k, CV_32FC1);
148 flannIndex.knnSearch(objectDescriptors, results, dists, k, cv::flann::SearchParams() );
155 float nndrRatio = 0.6f;
156 std::vector<cv::Point2f> mpts_1, mpts_2;
157 std::vector<int> indexes_1, indexes_2;
158 std::vector<uchar> outlier_mask;
161 for(
int i=0; i<objectDescriptors.rows; ++i)
164 if(dists.at<
float>(i,0) <= nndrRatio * dists.at<
float>(i,1))
166 mpts_1.push_back(objectKeypoints.at(i).pt);
167 indexes_1.push_back(i);
169 mpts_2.push_back(sceneKeypoints.at(results.at<
int>(i,0)).pt);
170 indexes_2.push_back(results.at<
int>(i,0));
177 unsigned int minInliers = 8;
178 if(mpts_1.size() >= minInliers)
180 cv::Mat H = findHomography(mpts_1,
185 int inliers=0, outliers=0;
186 for(
unsigned int k=0; k<mpts_1.size();++k)
188 if(outlier_mask.at(k))
198 printf(
"Total=%d Inliers=%d Outliers=%d\n", (
int)mpts_1.size(), inliers, outliers);
199 value = (inliers*100) / (inliers+outliers);
204 value = (int)mpts_1.size();
209 printf(
"Images are not valid!\n");
213 printf(
"Similarity = %d\n", value);
int main(int argc, char *argv[])