3

I'm trying to perform feature matching on images in Java. The code example for this I found is this one. I fixed the FeatureDetector deprecation via this answer.

However, when I use this code, it does not detect a sub image being part of the bigger image when they clearly are. Here is my adapted code example:

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;
    }
}

My test is the following:

@Test
public void testFeatureMatching() throws IOException
{
    BufferedImage completeImage = getBufferedImageFromClasspath("lena.png");
    BufferedImage subImage = getBufferedImageFromClasspath("lips.png");
    boolean matches = performFeatureMatching(completeImage, subImage);
    assertTrue(matches);
}

The example images are the following:

Since the lower image is cut out of the upper one it should definitely be found but the match returns false.

Furthermore there are still deprecations left in the code (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

Can someone fix the deprecations and/or the general code itself to make feature detection work properly because I can't get it to detect anything correctly?

BullyWiiPlaza
  • 17,329
  • 10
  • 113
  • 185

0 Answers0