2009-12-29 80 views
6

我有一个TYPE_INT_BGR类型的BufferedImage。我需要对另一个BufferedImage进行逐像素比较来计算两个图像之间的“距离”。我有一些工作,但很慢。我从“参考”图像的像素时,它分解成RGB与字节:最快的方法来比较两个BufferedImages之间的像素值?

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。

回答

3

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

比较BufferedImages的最快方法是按照您在文章中讨论的方式使用整数比较,但正如您所提及的,出于性能原因无法使用getRGB。您可以将一批像素获取到一个数组中,但总体而言,您应该只是查看Raster和DataBuffer的性能。

+0

你是对的;挥发性是一个不好的建议。我已经编辑出来了。可悲的是我不能倒下我的答案。 – Mikeb 2009-12-29 21:00:49

+1

你的答案对DataBuffer比较好:) – 2009-12-30 03:12:06

2

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

+1

是的,这两个图像使用相同的颜色模型和采样。推测与DataBuffer我仍然需要做位移,但也许至少避免OR值回到一起。 – 2009-12-29 17:43:56

+0

如果它有帮助,我正在使用的所有图像都是“屏幕外”;一个是从JPG读入的,另一个是从绘制到Graphics2D的结构。我从来没有使用过VolatileImage,我会检查出来。 – 2009-12-29 18:07:47

2

你有没有考虑过使用Java2D创建一个新图像差异你有两个图像,然后分析差异图像呢?

我最初的做法将采取图像A的负面,并添加图像B.

+0

这是一个很棒的主意:) – 2009-12-30 10:59:39

+0

这似乎是一个好主意,但我没有找到很多好运的例子。我假设我需要实现java.awt.CompositeContext。我看到的唯一的实现是SunCompositeContext,不幸的是没有提供源代码。 – 2009-12-31 04:34:13

1

如果打破以字节+加载额外的类的问题,试试这个:

获取BufferedImage的价值形态一个RGB像素值

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

从一个BufferedImage值IMG获得一个RGB值

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

我不知道这是否是一种更好/更快的方法来做到这一点,但它是另一种不使用任何额外类的替代方法,并且是一个直接的数学过程(或者黑客)...这可能会在某些场合变得有用(请仔细检查,因为我没有足够的时间玩我自己的方法)。

我不知道像素值之间需要进行哪种比较,所以这是本文的用处......我希望有人真的觉得这有帮助!