2011-12-19 123 views
13

最近我有机会与图像处理技术合作,作为我的一个项目的一部分,我的任务是在给出新图像时从图像存储库中找到匹配的图像。我开始使用Google搜索“如何使用Java比较图像”来开始我的项目,并且我找到了一些关于找到两幅图像相似性的好文章。几乎所有的人都是基于四个基本步骤,它们分别是:如何使用java比较图像的相似性

1.Locating the Region of Interest (Where the Objects appear in the given image), 
2.Re-sizing the ROIs in to a common size, 
3.Substracting ROIs, 
4.Calculating the Black and White Ratio of the resultant image after subtraction. 

虽然这听起来是一个很好的算法来比较图像,它需要在我的项目中使用JAI实施之后相当长的时间。因此我必须找到一种替代方法。

有什么建议吗?

+0

你有没有想过使用的OpenCV的百分比是多少? http://stackoverflow.com/questions/2037579/java-opencv-bindings – 2011-12-19 21:43:58

回答

5

根据不同的图像,你可以做这样的事情(伪代码)。这是非常原始的,但应该是非常有效的。你可以通过采用随机或图案像素而不是每个像素来加速它。

for x = 0 to image.size: 
    for y = 0 to image.size: 
     diff += abs(image1.get(x,y).red - image2.get(x,y).red) 
     diff += abs(image1.get(x,y).blue - image2.get(x,y).blue) 
     diff += abs(image1.get(x,y).green - image2.get(x,y).green) 
    end 
end 

return ((float)(diff))/(x * y * 3) 
+0

这是否真的有足够的精度? – sum2000 2011-12-19 21:45:46

+0

嗯,我不认为它是你正在寻找的精度,但准确性。例如,如果您拍摄图像并向左和向下偏移3个像素,则这将显示图像几乎没有任何相似之处。但是,那么你必须问自己,应该吗? – corsiKa 2011-12-19 21:50:17

+0

此方法适用于黑白图像吗? – manu 2014-05-08 09:09:20

10
**// This API will compare two image file // 
// return true if both image files are equal else return false//** 
public static boolean compareImage(File fileA, File fileB) {   
    try { 
     // take buffer data from botm image files // 
     BufferedImage biA = ImageIO.read(fileA); 
     DataBuffer dbA = biA.getData().getDataBuffer(); 
     int sizeA = dbA.getSize();      
     BufferedImage biB = ImageIO.read(fileB); 
     DataBuffer dbB = biB.getData().getDataBuffer(); 
     int sizeB = dbB.getSize(); 
     // compare data-buffer objects // 
     if(sizeA == sizeB) { 
      for(int i=0; i<sizeA; i++) { 
       if(dbA.getElem(i) != dbB.getElem(i)) { 
        return false; 
       } 
      } 
      return true; 
     } 
     else { 
      return false; 
     } 
    } 
    catch (Exception e) { 
     System.out.println("Failed to compare image files ..."); 
     return false; 
    } 
} 
+0

这将比较两幅图像是否相同,我要求找出两幅图像之间的相似度。 – sum2000 2012-06-22 07:24:31

+0

只是想检查,如果两个不同的图像符合相同的大小,会返回什么? – ChanGan 2013-01-18 11:31:11

+0

嗨Sandip,如何通过两个传递两个图像到位fileA和fileB ...都是文件的位置?你能给我简短的一点吗? – ChanGan 2013-01-18 12:10:12

3

这个API将比较两个图像文件,并返回相似的

public float compareImage(File fileA, File fileB) { 

    float percentage = 0; 
    try { 
     // take buffer data from both image files // 
     BufferedImage biA = ImageIO.read(fileA); 
     DataBuffer dbA = biA.getData().getDataBuffer(); 
     int sizeA = dbA.getSize(); 
     BufferedImage biB = ImageIO.read(fileB); 
     DataBuffer dbB = biB.getData().getDataBuffer(); 
     int sizeB = dbB.getSize(); 
     int count = 0; 
     // compare data-buffer objects // 
     if (sizeA == sizeB) { 

      for (int i = 0; i < sizeA; i++) { 

       if (dbA.getElem(i) == dbB.getElem(i)) { 
        count = count + 1; 
       } 

      } 
      percentage = (count * 100)/sizeA; 
     } else { 
      System.out.println("Both the images are not of same size"); 
     } 

    } catch (Exception e) { 
     System.out.println("Failed to compare image files ..."); 
    } 
    return percentage; 
} 
+0

请在代码中找到带有第一行顶端参数的方法名,在那里我们可以传递两个带有文件路径的图像(例如:C://Documents//image1.jpg) – 2015-12-11 05:59:47

+2

您应该提到这是基于Sandip甘古利的回答。 – 2017-06-15 17:17:54