I am trying to implement a very simple program for finding similarities between two images.
I am using the ORB feature detector and image descriptor for this task and I am identifying the matches using knnMatch:
FeatureDetector detector = FeatureDetector.create(FeatureDetector.ORB);
DescriptorExtractor descriptor = DescriptorExtractor.create(DescriptorExtractor.ORB);
DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMING);
// DETECTION
// first image
Mat img1 = Imgcodecs.imread(path1, Imgcodecs.CV_LOAD_IMAGE_GRAYSCALE);
Mat descriptors1 = new Mat();
MatOfKeyPoint keypoints1 = new MatOfKeyPoint();
detector.detect(img1, keypoints1);
descriptor.compute(img1, keypoints1, descriptors1);
// second image
Mat img2 = Imgcodecs.imread(path2, Imgcodecs.CV_LOAD_IMAGE_GRAYSCALE);
Mat descriptors2 = new Mat();
MatOfKeyPoint keypoints2 = new MatOfKeyPoint();
detector.detect(img2, keypoints2);
descriptor.compute(img2, keypoints2, descriptors2);
// MATCHING
// match these two keypoints sets
List<MatOfDMatch> matches = new ArrayList<MatOfDMatch>();
matcher.knnMatch(descriptors1, descriptors2, matches, 5);
I am able to draw the matches as follows:
// DRAWING OUTPUT
Mat outputImg = new Mat();
// this will draw all matches, works fine
Features2d.drawMatches2(img1, keypoints1, img2, keypoints2, matches, outputImg);
// save image
Imgcodecs.imwrite("result.jpg", outputImg);
The problem is that there are too many matches and it includes also those that are way off. I can't seem to find how to extract only the good matches (exceeding some threshold)? Could someone point me to the right direction or redirect me to some basic working example? I have spent several hours on this and seem to be lost..
EDIT:
I tried looking at Keypoint matching just works two times...? (java opencv) but the standard (non-knn) match uses different structures and and I could not make it work.