我试图使用OpenCV库比较两个图像(确定它们是否相似).我配置了java包装器并找到了几个我正在尝试重写为Java的教程(主要是在C/C++中).我正在使用特征检测方法.
问题是我目前拥有的算法没有产生任何合理的结果(它声称两个相似的图像没有任何共同点,并且发现完全不同的其他两个图像之间的匹配).有人建议我应该如何使用openCV匹配器产生一些合理的结果?
这是我的图像比较代码
private static void compareImages(String path1, String path2) {
System.out.println(path1 + "-" + path2);
FeatureDetector detector = FeatureDetector.create(FeatureDetector.ORB);
DescriptorExtractor descriptor = DescriptorExtractor.create(DescriptorExtractor.ORB);
DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMING);
// first image
Mat img1 = Imgcodecs.imread(path1, Imgcodecs.CV_LOAD_IMAGE_GRAYSCALE);
Mat descriptors1 = new Mat();
MatOfKeyPoint keypoints1 = new MatOfKeyPoint();
detector.detect(img1, keypoints1);
descriptor.compute(img1, keypoints1, descriptors1);
// second image
Mat img2 = Imgcodecs.imread(path2, Imgcodecs.CV_LOAD_IMAGE_GRAYSCALE);
Mat descriptors2 = new Mat();
MatOfKeyPoint keypoints2 = new MatOfKeyPoint();
detector.detect(img2, keypoints2);
descriptor.compute(img2, keypoints2, descriptors2);
// match these two keypoints sets
MatOfDMatch matches = new MatOfDMatch();
matcher.match(descriptors1, descriptors2, matches);
for (DMatch m : matches.toArray()) {
// how to use these values to detect the similarity? They seem to be way off
// all of these values are in range 50-80 which seems wrong to me
System.out.println(m.distance);
}
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,像JSP包装器中没有像SURF和SIFT这样的算法,所以我使用的是ORB.我对计算机视觉几乎没有经验,我只是想让这个简单的比较算法工作以产生一些合理的结果.我很乐意提供任何帮助!
编辑:我的用例是针对从不同角度拍摄的图像运行此算法.我更新了我的代码以更好地格式化.
要比较的示例图片:
只是我的两分钱:
在java中可以访问SURF和SIFT:openCV DescriptorExtractor Reference.三年前我尝试了FREAK实现,发现当openCV将它们传递给Java时,二进制描述符会发生一些变化.ORB可能会遇到同样的问题.您是否将c或c ++中描述符的数据与java方面的数据进行了比较?
蛮力匹配器从查询图像中的每个特征的火车图像中找到最佳匹配特征.即使它看起来完全不同.你必须筛选比赛并丢掉不好的比赛.存在几种策略,一种简单的策略就是获得最好的20%的匹配(但这不会丢弃所有的异常值).Progressive Sample Consensus在我的设置中表现非常出色.
Calib3d.findHomography(obj, scene, CV_RANSAC);并使用重叠区域的标准化像素差异.