1

I have a picture of some cupshere

and a picture of a cat here

I want to compare these two pictures in OpenCV using surf and match them using BFMatcher.

Here is the code:

//read the image
cv::Mat image1= cv::imread("C:\\Users\\The\\Desktop\\cub.jpg");
cv::Mat image2= cv::imread("C:\\Users\\The\\Desktop\\cat.jpg");
//detect the key points using surf
cv::SurfFeatureDetector surf(300,4,2,true,false);
   //image 1 key points
vector<cv::KeyPoint> image1Keypoints;
//detect the key points in image 1 using surf
surf.detect(image1,image1Keypoints);
//draw the keypoints of image1
cv::drawKeypoints(image1,image1Keypoints,image1,                                      
  cv::Scalar(255,255,255),cv::DrawMatchesFlags::DRAW_OVER_OUTIMG);
cv::namedWindow("Original image 1 with keypoints");
cv::imshow("Original image 1 with keypoints",image1);
// image 2 key points
std::vector<cv::KeyPoint> image2keypoints;
//detect the key points in image 1 using surf
 surf.detect(image2,image2keypoints);
 //draw the key points
 cv::drawKeypoints(image2,keypoints1,image2,                                   
      cv::Scalar(255,255,255),cv::DrawMatchesFlags::DRAW_OVER_OUTIMG);                      
 //the extracted image display
cv::namedWindow("image 2 with keypoints");
cv::imshow("image 2 with keypoints",image2);

From the above code this the cups image features this

and the cat image features: this

cv::SiftDescriptorExtractor sift;
cv::Mat image1Descriptor;
cv::Mat image2Desccriptor;
sift.compute(image1,
             image1Keypoints,
             image1Descriptor);
sift.compute(image2,
             keypoints1,
             image2Desccriptor);
 cv::BFMatcher matcher(cv::NORM_L2,true);
std::vector<cv::DMatch> matches;
matcher.match(image2Desccriptor,image1Descriptor,matches);
cout<<"match=";
//the number of matched features between the two images
cout<<matches.size()<<endl;
cv::Mat imageMatches;   
cv::drawMatches(image2,keypoints1,image1,image1Keypoints,                
   matches,imageMatches,cv::DrawMatchesFlags::DRAW_OVER_OUTIMG);              
cv::namedWindow("matches");
cv::imshow("matches",imageMatches);
cv::waitKey(0);

What really confused me is the matched picture: matches

There are around 833 matched features but the images are completely different.

What is wrong with my code & how can i decrease the number of matches. I was able to decrease the number of matches by changing the surf parameters but it is because it detect small number of features. For example by changing the siftFeature detector to this:

cv::SurfFeatureDetector surf(1000,4,2,true,false);

I was able to get matches=77 but still it is a high number of matches and the matches are decreased because I was getting small number of features compared to the above numbers.

Jeru Luke
  • 20,118
  • 13
  • 80
  • 87
Yirga
  • 881
  • 1
  • 12
  • 31
  • As I scroll I see a story.... :-D – P0W Jan 27 '17 at 10:06
  • 2
    You're comparing small image patches (32x32 or so), i.e. the descriptors... Matching descriptors doesn't mean comparing images. You have to do some other steps after the matching. – Miki Jan 27 '17 at 10:07
  • @POW my question is for two different images how it is possible to have that much amount of match and how to decrease the number of matches? – Yirga Jan 27 '17 at 10:09
  • @Miki can you elaborate what you mean by "you have to use some other steps after matching" i am a beginner to opencv. – Yirga Jan 27 '17 at 10:15
  • 3
    For example, estimate a transformation on matched keypoints, and check the number of outliers. Fewer outliers means more similar images. Or use the descriptors in a classifier like BoW, SVM, or whatever. – Miki Jan 27 '17 at 10:20

1 Answers1

1

You should check this answer.

Typically, BruteForce will return the distance between two matches. The lower the distance between two features, the similar they are. By applying a threshold onto these distances will help you remove false positive matches.

However, feature matches by itself will not guarantee that the objects in two images will be the same. To do this kind of verification you need to go a bit further on your implementation and (for instance) geometrically verify the positive matches with an Homography.

Community
  • 1
  • 1
NAmorim
  • 706
  • 6
  • 12