基本上,我想在 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 调用似乎还可以,异常显然不是...