#include #include // OpenCV stuff #include #include #include #include #include // for homography void showUsage() { printf( "\n" "Return similarity between two images (the number of similar features between the images).\n" "Usage :\n" " ./find_object-similarity [option] object.png scene.png\n" "Options: \n" " -inliers return inliers percentage : inliers / (inliers + outliers)\n" " -quiet don't show messages\n"); exit(-1); } enum {mTotal, mInliers}; int main(int argc, char * argv[]) { bool quiet = false; int method = mTotal; //total matches if(argc<3) { printf("Two images required!\n"); showUsage(); } else if(argc>3) { for(int i=1; i objectKeypoints; std::vector sceneKeypoints; cv::Mat objectDescriptors; cv::Mat sceneDescriptors; //////////////////////////// // EXTRACT KEYPOINTS //////////////////////////// cv::SIFT sift; sift.detect(objectImg, objectKeypoints); sift.detect(sceneImg, sceneKeypoints); //////////////////////////// // EXTRACT DESCRIPTORS //////////////////////////// sift.compute(objectImg, objectKeypoints, objectDescriptors); sift.compute(sceneImg, sceneKeypoints, sceneDescriptors); //////////////////////////// // NEAREST NEIGHBOR MATCHING USING FLANN LIBRARY (included in OpenCV) //////////////////////////// cv::Mat results; cv::Mat dists; std::vector > matches; int k=2; // find the 2 nearest neighbors // Create Flann KDTree index cv::flann::Index flannIndex(sceneDescriptors, cv::flann::KDTreeIndexParams(), cvflann::FLANN_DIST_EUCLIDEAN); results = cv::Mat(objectDescriptors.rows, k, CV_32SC1); // Results index dists = cv::Mat(objectDescriptors.rows, k, CV_32FC1); // Distance results are CV_32FC1 // search (nearest neighbor) flannIndex.knnSearch(objectDescriptors, results, dists, k, cv::flann::SearchParams() ); //////////////////////////// // PROCESS NEAREST NEIGHBOR RESULTS //////////////////////////// // Find correspondences by NNDR (Nearest Neighbor Distance Ratio) float nndrRatio = 0.6; std::vector mpts_1, mpts_2; // Used for homography std::vector indexes_1, indexes_2; // Used for homography std::vector outlier_mask; // Used for homography // Check if this descriptor matches with those of the objects for(int i=0; i(i,0) <= nndrRatio * dists.at(i,1)) { mpts_1.push_back(objectKeypoints.at(i).pt); indexes_1.push_back(i); mpts_2.push_back(sceneKeypoints.at(results.at(i,0)).pt); indexes_2.push_back(results.at(i,0)); } } if(method == mInliers) { // FIND HOMOGRAPHY unsigned int minInliers = 8; if(mpts_1.size() >= minInliers) { cv::Mat H = findHomography(mpts_1, mpts_2, cv::RANSAC, 1.0, outlier_mask); int inliers=0, outliers=0; for(unsigned int k=0; k