Ask Your Question
1

ORB Detector / ORB Extractor retrieve bad results

asked 2016-05-18 06:33:35 -0600

jannarc gravatar image

I'm trying to get similar results as in image description "http://docs.opencv.org/2.4/doc/tutorials/features2d/feature_flann_matcher/feature_flann_matcher.html#feature-flann-matcher" but I'm employing ORB rather than SURF and bruteforce instead of FLANN. Descriptors and matches I get seem almost random. image description My code is as follows

package main;
import java.util.ArrayList;
import java.util.List;
import org.opencv.features2d.*;
import org.opencv.core.*;
import org.opencv.imgcodecs.*;


public class Main 
{
public static void main(String[] args)
{
    System.loadLibrary("opencv_java310");
    Mat img1 = Imgcodecs.imread("D:\\Projects\\HelloOpenCV\\box.png", Imgcodecs.CV_LOAD_IMAGE_GRAYSCALE);
    Mat img2 = Imgcodecs.imread("D:\\Projects\\HelloOpenCV\\box_in_scene.png", Imgcodecs.CV_LOAD_IMAGE_GRAYSCALE);

    FeatureDetector detector = FeatureDetector.create(FeatureDetector.ORB);
    MatOfKeyPoint keypoints1 = new MatOfKeyPoint();
    detector.detect(img1, keypoints1);

    FeatureDetector detector2 = FeatureDetector.create(FeatureDetector.ORB);
    MatOfKeyPoint keypoints2 = new MatOfKeyPoint();
    detector2.detect(img2, keypoints2);

    DescriptorExtractor extractor = DescriptorExtractor.create(DescriptorExtractor.ORB);
    Mat descriptors1 = new Mat();
    extractor.compute(img1, keypoints1, descriptors1);

    DescriptorExtractor extractor2 = DescriptorExtractor.create(DescriptorExtractor.ORB);
    Mat descriptors2 = new Mat();
    extractor2.compute(img2, keypoints2, descriptors2);

    DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE);
    MatOfDMatch matches = new MatOfDMatch();

    matcher.match(descriptors1, descriptors2, matches);
    /**/
    List<DMatch> matchesList = matches.toList();
    double maxDistance = 0;
    double minDistance = 1000;

    int rowCount = matchesList.size();
    for (int i = 0; i < rowCount; i++) 
    {
        double dist = matchesList.get(i).distance;
        if (dist < minDistance) minDistance = dist;
        if (dist > maxDistance) maxDistance = dist;
    }

    List<DMatch> goodMatchesList = new ArrayList<DMatch>();
    double upperBound = 1.6 * minDistance;
    for (int i = 0; i < rowCount; i++) 
    {
        if (matchesList.get(i).distance <= upperBound) 
        {
            goodMatchesList.add(matchesList.get(i));
        }
    }
    MatOfDMatch goodMatches = new MatOfDMatch();
    goodMatches.fromList(goodMatchesList); 

    Mat img_matches = new Mat();
    Features2d.drawMatches(img1, keypoints1, img2, keypoints2, goodMatches, img_matches);
    Imgcodecs.imwrite("D:\\Projects\\HelloOpenCV\\Test.bmp", img_matches);      
}
}

I feel I'm missing something trivial here. I tried AKAZE/AKAZE either, result was different but not better.

edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
3

answered 2016-05-18 09:28:55 -0600

berak gravatar image

updated 2016-05-18 09:30:50 -0600

for binary descriptors, like ORB, BRISK,BRIEF and AKAZE, you have to use BRUTEFORCE_HAMMING for the matching (BRUTEFORCE alone uses L2 distance, which is only feasible for float descriptors, like SIFT and SURF)

edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2016-05-18 06:33:35 -0600

Seen: 1,857 times

Last updated: May 18 '16