我使用ORB特征检测器使用以下代码查找两个图像之间的匹配:
FeatureDetector detector = FeatureDetector.create(FeatureDetector.ORB);
DescriptorExtractor descriptor = DescriptorExtractor.create(DescriptorExtractor.ORB);;
DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMING);
// First photo
Imgproc.cvtColor(img1, img1, Imgproc.COLOR_RGB2GRAY);
Mat descriptors1 = new Mat();
MatOfKeyPoint keypoints1 = new MatOfKeyPoint();
detector.detect(img1, keypoints1);
descriptor.compute(img1, keypoints1, descriptors1);
// Second photo
Imgproc.cvtColor(img2, img2, Imgproc.COLOR_RGB2GRAY);
Mat descriptors2 = new Mat();
MatOfKeyPoint keypoints2 = new MatOfKeyPoint();
detector.detect(img2, keypoints2);
descriptor.compute(img2, keypoints2, descriptors2);
// Matching
MatOfDMatch matches = new MatOfDMatch();
MatOfDMatch filteredMatches = new MatOfDMatch();
matcher.match(descriptors1, descriptors2, matches);
// Linking
Scalar RED = new Scalar(255,0,0);
Scalar GREEN = new Scalar(0,255,0);
List<DMatch> matchesList = matches.toList();
Double max_dist = 0.0;
Double min_dist = 100.0;
for(int i = 0;i < matchesList.size(); i++){
Double dist = (double) matchesList.get(i).distance;
if (dist < min_dist)
min_dist = dist;
if ( dist > max_dist)
max_dist = dist;
}
LinkedList<DMatch> good_matches = new LinkedList<DMatch>();
for(int i = 0;i < matchesList.size(); i++){
if (matchesList.get(i).distance <= (1.5 * min_dist))
good_matches.addLast(matchesList.get(i));
}
// Printing
MatOfDMatch goodMatches = new MatOfDMatch();
goodMatches.fromList(good_matches);
System.out.println(matches.size() + " " + goodMatches.size());
Mat outputImg = new Mat();
MatOfByte drawnMatches = new MatOfByte();
Features2d.drawMatches(img1, keypoints1, img2, keypoints2, goodMatches, outputImg, GREEN, RED, drawnMatches, Features2d.NOT_DRAW_SINGLE_POINTS);
Highgui.imwrite("matches.png", outputImg);
我的问题是,我无法找到过滤匹配的方法,以便只有在照片中有相似位置时才匹配。我总是得到一个关键点的多个匹配,即使它们位置非常远。
有没有办法更好地过滤它们?
答案 0 :(得分:6)
要获得更好的匹配结果,您应该按给定的顺序包含这些过滤方法。
在两个方向上进行匹配,即对第一个图像中的每个点进行匹配 在第二张图片中找到最佳匹配,反之亦然。
进行比率测试(欧氏距离的比率测试) 匹配以消除模棱两可的匹配。
您可以在计算机视觉应用程序编程手册的第9章中获得上述方法的所有详细信息。它还有用于实现这些过滤技术的示例代码。这很容易理解。 (注意:本书中的代码是用C ++编写的,但是一旦理解,它也可以在JAVA中轻松实现)
答案 1 :(得分:1)
阅读了Rober Langaniere的书。我才知道有办法。这是为了删除更远距离的匹配。在java中,它如下所示
Collections.sort(bestMatches,new Comparator<DMatch>() {
@Override
public int compare(DMatch o1, DMatch o2) {
if(o1.distance<o2.distance)
return -1;
if(o1.distance>o2.distance)
return 1;
return 0;
}
});
if(bestMatches.size()>3){
bestMatches = bestMatches.subList(0,3);
}
答案 2 :(得分:0)
通过采用两个描述符之间的最短汉明距离来完成匹配。因此,您始终可以在检测到的功能之间找到匹配项。
您应该修改ORB检测器的阈值。这样,您将减少从背景检测特征(即噪声)的可能性,因此您检测到的大部分特征都将来自感兴趣的主题。