0

基本上,我想在 OpenCV 中使用 ORB 和 BFMatcher 看看是否有第一个对象(“sight”)在其他图像(“test”)中可见(像这样)。ORB 本身工作正常;它在我的图像中检测到令人满意的关键点数量。但是,当我尝试使用BFMatcher比较两组描述符时,它会立即崩溃而没有提供实际信息。

  • 试图打印整个关键点和描述符矩阵(这里没有提供,因为它太长了),它们似乎是完全正确的;
  • 加载图像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 调用似乎还可以,异常显然不是...

4

0 回答 0