在Java中使用OpenCV比较两个图像

时间:2016-01-13 09:29:57

标签: java opencv

我正在尝试使用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);
    }
  }

不幸的是,在java包装器中没有像SURF和SIFT这样的算法,所以我使用的是ORB。我对计算机视觉几乎没有经验,我只是想让这个简单的比较算法工作以产生一些合理的结果。我很乐意提供任何帮助!

编辑:我的用例是针对从不同角度拍摄的图像运行此算法。我更新了我的代码以更好地格式化。

要比较的样本图片:

enter image description here enter image description here

2 个答案:

答案 0 :(得分:5)

只是我的两分钱:

  1. 可以在java中访问SURF和SIFT:openCV DescriptorExtractor Reference。三年前我尝试了FREAK实现,发现当openCV将它们传递给Java时,二进制描述符会发生一些变化。 ORB可能会遇到同样的问题。您是否将c或c ++描述符的数据与java端的数据进行比较?

  2. 强力匹配器从查询图像中的每个要素的火车图像中找到最佳匹配特征。即使它看起来完全不同。你必须筛选比赛并丢掉不好的比赛。存在几种策略,一种简单的策略就是获得最好的20%的匹配(但这不会丢弃所有的异常值)。 Progressive Sample Consensus在我的设置中表现非常出色。

  3. 使用功能来比较图像的相似性有它的缺陷。特征数量和质量随图像大小和内容而变化,这使得难以全局比较图像(如果您想知道两个图像中的哪一个与参考图像中的哪一个比另一图像更相似)。您可以使用equals估算从一个图像到另一个图像的变换,并使用重叠区域的标准化像素差异。

答案 1 :(得分:0)

正如this SO Question所述,最简单,最直接的方法是比较直方图。如果您的算法仅需要针对特定​​数据集工作,请尝试使用不同的颜色通道来查看集合中的图像共享最相似的位置。

直方图方法似乎不切实际,但考虑到图像的颜色相似性,我相信这可能会有所帮助。

在Photoshop中比较两个图像的直方图后:

histogram comparison