比较两个BufferedImages之间像素值的最快方法?

时间:2009-12-29 17:31:28

标签: java rgb bufferedimage java-2d

我有一个TYPE_INT_BGR类型的BufferedImage。我需要与另一个BufferedImage进行逐像素比较,以计算两个图像之间的“距离”。我有一些有用的东西,但很慢。我从“参考”图像中获取一个像素,然后将其分解为RGB字节:

    int pixel = referenceImage.getRGB(col, row);
    int red   = (pixel >> 16) & 0xff;
    int green = (pixel >> 8) & 0xff;
    int blue  = (pixel) & 0xff;

我将r / g / b值与候选图像的相应像素进行比较,并将差值总结为正方形。

有没有更快的方法来进行这种比较?窥视JRE源代码,我看到BufferedImage.getRGB()实际上是将光栅中的RGB值组合在一起,这对我来说是浪费的,因为我只是将其分解为字节。

我将尝试直接尝试,但我想知道是否有更好的方法可以通过我可能错过的Java或第三方API。

4 个答案:

答案 0 :(得分:3)

从VolatileImage读取数据不会更快。使VolatileImages“更快”的原因是它们使用加速(VRAM)内存而不是系统(RAM)内存来绘制图像。但是,在执行读操作时,可能需要通过另一条总线访问内存,并且比这些操作的系统内存慢。

比较BufferedImages的最快方法是使用您在帖子中讨论的方式进行整数比较,但正如您所提到的,出于性能原因,您无法使用getRGB。您可以将一批像素放入一个数组中,但总的来说,您应该只是查看Raster和DataBuffer的性能。

答案 1 :(得分:2)

如果两个图像使用相同的颜色模型和采样,您可以在栅格的DataBuffer上执行比较,这会更快一些。

答案 2 :(得分:2)

您是否考虑过使用Java2D在您拥有的两个图像之间创建一个新的图像差异,然后分析差异图像?

我的初步方法是采用图像A的负片并添加图像B.

答案 3 :(得分:1)

如果分解为字节+加载额外的类是问题,请尝试:

获取BufferedImage值形成RGB像素值

img = 65536*R + 256*G + B - 16777216;  

从BufferedImage值获取RGB值img

R=  Math.round((((371*img)+24576000000) / 96000000)
G=  Math.round((65536 + 0.003906*img - 256*R));
B=  Math.round((65536*R + 256*G -img - 16777216));

我不确定这是否是更好/更快的方法,但它是另一种不使用任何额外类的替代方法,并且是一个简单的数学过程(或黑客)......这可能会变成在某些情况下有用(请仔细检查,因为这是我自己的方法,我没有足够的时间玩)。

我不知道你需要在像素值之间进行哪种比较,所以这篇文章的内容有多远......我希望有人真的觉得这很有帮助!