OpenCV 4.1.0 Java : how to fix "unknown exception" when trying to use BFMatcher with ORB-based keypoints and descriptors?

434 views Asked by At

Basically, I want to see if there is a first object ("sight") is visible in other images ("test") (like this), using ORB and BFMatcher in OpenCV. ORB by itself works fine ; it detects a satisfying number of keypoints in my images. However, when I try to use BFMatcher to compare 2 sets of descriptors, it crashes instantly without giving actual information.

  • Tried to print the whole keypoints and descriptors matrices (not provided here because it would be too long), and they seem to be perfectly correct ;
  • Loading images in Imgcodecs.IMREAD_GRAYSCALE doesn't change anything, not even ORB's results in the first place ;
  • Changing ORB's mask (instead of just sending a new Mat() everytime) seems to eliminate all results.
final File inputDir = new File("features/");
final File sightFile = new File(inputDir.getAbsolutePath() + "/" + "sight.jpg");
final File outputDir = new File(inputDir.getAbsolutePath() + "/" + "matching" + "/");

// In BFMatcher terms : query data
Mat sightImage = new Mat();
MatOfKeyPoint sightKeyPoints = new MatOfKeyPoint();
Mat sightDescriptors = new Mat();

// In BFMatcher terms : train data
Mat testImage = new Mat();
MatOfKeyPoint testKeyPoints = new MatOfKeyPoint();
Mat testDescriptors = new Mat();

// Loading sight image
sightImage = Imgcodecs.imread(sightFile.getAbsolutePath());
//sightImage = Imgcodecs.imread(sightFile.getAbsolutePath(), Imgcodecs.IMREAD_GRAYSCALE);
// Note : loading in greyscale (see previous line) does the exact same things

// Testing if there was any read error
if (sightImage.empty()) {
    // (actually never goes here)
    System.out.println("Empty image: " + sightFile.getAbsolutePath());
    System.exit(0);
}

// Creating the output directory
outputDir.mkdirs();

// Init ORB detector (to get features from a single image)
ORB orb = ORB.create();

// Init BFMatcher (to compare features between 2 images)
BFMatcher bf = new BFMatcher(Core.NORM_HAMMING, true);

// Sight features (last 2 parameters are OUT parameters)
// Also, the 2nd parameter is a mask ; just throwing "new Mat()" seems to work
orb.detectAndCompute(sightImage, new Mat(), sightKeyPoints, sightDescriptors);

// SEE OUTPUT
System.out.println("sight descriptor matrix :\tsize " + sightDescriptors.size() + "x"
        + sightDescriptors.get(0, 0).length + "\tempty ? " + sightDescriptors.empty());
System.out.println("sight key points matrix :\tsize " + sightKeyPoints.size() + "x"
        + sightKeyPoints.get(0, 0).length + "\tempty ? " + sightKeyPoints.empty());

// For each file other than sightFile
for (final File fileEntry : inputDir.listFiles()) {
    if (!fileEntry.isDirectory() && !fileEntry.equals(sightFile)) {
        // Matches matrix
        MatOfDMatch matches = new MatOfDMatch();

        // Loading test image
        testImage = Imgcodecs.imread(fileEntry.getAbsolutePath());
        //testImage = Imgcodecs.imread(fileEntry.getAbsolutePath(), Imgcodecs.IMREAD_GRAYSCALE);
        // Note : loading in greyscale (see previous line) does the exact same things

        // Testing if there was any read error
        if (testImage.empty()) {
            // (actually never goes here)
            System.out.println("Empty image: " + fileEntry.getAbsolutePath());
            continue;
        }

        // Test image features (last 2 parameters are OUT parameters)
        // Also, the 2nd parameter is a mask ; just throwing "new Mat()" seems to work
        orb.detectAndCompute(testImage, new Mat(), testKeyPoints, testDescriptors);

        // SEE OUTPUT
        System.out.println("test image descriptor matrix :\tsize " + testDescriptors.size() + "x"
                + testDescriptors.get(0, 0).length + "\tempty ? " + testDescriptors.empty());
        System.out.println("test image key points matrix :\tsize " + testKeyPoints.size() + "x"
                + testKeyPoints.get(0, 0).length + "\tempty ? " + testKeyPoints.empty());

        // Match descriptors (3rd parameter is an OUT parameter)
        bf.match(sightDescriptors, testDescriptors, matches);
        // CRASHES HERE !!!!!

        // (etc.)
    }
}

Actual output :

sight descriptor matrix :   size 32x500x1   empty ? false
sight key points matrix :   size 1x500x7    empty ? false
test image descriptor matrix :  size 32x500x1   empty ? false
test image key points matrix :  size 1x500x7    empty ? false
Exception in thread "main" java.lang.Exception: unknown exception
    at org.opencv.features2d.DescriptorMatcher.match_1(Native Method)
    at org.opencv.features2d.DescriptorMatcher.match(DescriptorMatcher.java:245)
    at testopencv.DetectionTest.FeatureMatchingTest(DetectionTest.java:235)
    at testopencv.DetectionTest.main(DetectionTest.java:29)

Well, the sysout calls seem to be OK, the exception is obviously not...

0

There are 0 answers