用Java执行图像的特征匹配

时间:2018-08-17 08:50:51

标签: java opencv feature-extraction feature-detection

我正在尝试对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

由于我无法正确检测到任何东西,有人可以修复不推荐使用的内容和/或常规代码本身以使其正常工作吗?

0 个答案:

没有答案