我正在尝试对Java
中的图像执行feature matching
。我发现的代码示例是this one。我通过this的答案解决了FeatureDetector
弃用的问题。
但是,当我使用此代码时,当清晰可见时,它不会检测到子图像是较大图像的一部分。这是我改编的代码示例:
public static boolean performFeatureMatching(BufferedImage largeBufferedImage, BufferedImage smallBufferedImage) throws IOException
{
FastFeatureDetector fd = FastFeatureDetector.create();
final MatOfKeyPoint keyPointsLarge = new MatOfKeyPoint();
final MatOfKeyPoint keyPointsSmall = new MatOfKeyPoint();
Mat largeImage = bufferedImage2Mat(largeBufferedImage);
Mat smallImage = bufferedImage2Mat(smallBufferedImage);
fd.detect(largeImage, keyPointsLarge);
fd.detect(smallImage, keyPointsSmall);
System.out.println("keyPoints.size() : " + keyPointsLarge.size());
System.out.println("keyPoints2.size() : " + keyPointsSmall.size());
Mat descriptorsLarge = new Mat();
Mat descriptorsSmall = new Mat();
DescriptorExtractor extractor = DescriptorExtractor.create(DescriptorExtractor.BRISK);
extractor.compute(largeImage, keyPointsLarge, descriptorsLarge);
extractor.compute(smallImage, keyPointsSmall, descriptorsSmall);
System.out.println("descriptorsA.size() : " + descriptorsLarge.size());
System.out.println("descriptorsB.size() : " + descriptorsSmall.size());
MatOfDMatch matches = new MatOfDMatch();
DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMINGLUT);
matcher.match(descriptorsLarge, descriptorsSmall, matches);
System.out.println("matches.size() : " + matches.size());
MatOfDMatch matchesFiltered = new MatOfDMatch();
List<DMatch> matchesList = matches.toList();
List<DMatch> bestMatches = new ArrayList<>();
Double max_dist = 0.0;
Double min_dist = 100.0;
for (DMatch aMatchesList : matchesList)
{
Double dist = (double) aMatchesList.distance;
if (dist < min_dist && dist != 0)
{
min_dist = dist;
}
if (dist > max_dist)
{
max_dist = dist;
}
}
System.out.println("max_dist : " + max_dist);
System.out.println("min_dist : " + min_dist);
if (min_dist > 50)
{
System.out.println("No match found");
System.out.println("Just return ");
return false;
}
double threshold = 3 * min_dist;
double threshold2 = 2 * min_dist;
if (threshold > 75)
{
threshold = 75;
} else if (threshold2 >= max_dist)
{
threshold = min_dist * 1.1;
} else if (threshold >= max_dist)
{
threshold = threshold2 * 1.4;
}
System.out.println("Threshold : " + threshold);
for (int i = 0; i < matchesList.size(); i++)
{
double dist = (double) matchesList.get(i).distance;
if (dist < threshold)
{
bestMatches.add(matches.toList().get(i));
//System.out.println(String.format(i + " best match added : %s", dist));
}
}
matchesFiltered.fromList(bestMatches);
System.out.println("matchesFiltered.size() : " + matchesFiltered.size());
if (matchesFiltered.rows() >= 4)
{
System.out.println("match found");
return true;
} else
{
return false;
}
}
我的测试如下:
@Test
public void testFeatureMatching() throws IOException
{
BufferedImage completeImage = getBufferedImageFromClasspath("lena.png");
BufferedImage subImage = getBufferedImageFromClasspath("lips.png");
boolean matches = performFeatureMatching(completeImage, subImage);
assertTrue(matches);
}
示例图像如下:
由于下部图像是从上部图像中切出的,因此绝对可以找到它,但是匹配返回false
。
此外,代码(related question)中还剩下弃用的内容:
Warning:(7, 29) java: org.opencv.features2d.DescriptorExtractor in org.opencv.features2d has been deprecated
Warning:(37, 17) java: org.opencv.features2d.DescriptorExtractor in org.opencv.features2d has been deprecated
Warning:(37, 76) java: org.opencv.features2d.DescriptorExtractor in org.opencv.features2d has been deprecated
Warning:(37, 49) java: org.opencv.features2d.DescriptorExtractor in org.opencv.features2d has been deprecated
由于我无法正确检测到任何东西,有人可以修复不推荐使用的内容和/或常规代码本身以使其正常工作吗?