OpenCV 4.1.0 Java: как исправить «неизвестное исключение» при попытке использовать BFMatcher с ORB-ключами и дескрипторами? - PullRequest
0 голосов
/ 04 июля 2019

По сути, я хочу посмотреть, есть ли первый объект ("прицел") виден на других изображениях ("тест") (например, это ), используя ORB и BFMatcher в OpenCV. ORB сам по себе отлично работает ;он обнаруживает достаточное количество ключевых точек в моих изображениях.Однако, когда я пытаюсь использовать BFMatcher для сравнения 2 наборов дескрипторов, мгновенно завершает работу без предоставления фактической информации.

  • Пытался напечатать целые ключевые точкии матрицы дескрипторов (не предоставленные здесь, потому что они будут слишком длинными), и они кажутся совершенно правильными;
  • Загрузка изображений в Imgcodecs.IMREAD_GRAYSCALE ничего не меняет, в первую очередь даже результаты ORB;
  • Изменение маски ORB (вместо простой отправки new Mat() каждый раз), по-видимому, исключает все результаты.
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.)
    }
}

Фактический результат:

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)

Ну, вызовы sysout вроде бы в порядке, исключение, очевидно, нет ...

...