6

我有一个 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 或 3rd 方 API。

4

4 回答 4

3

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

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

于 2009-12-29T18:58:24.193 回答
2

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

于 2009-12-29T17:40:52.430 回答
2

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

我最初的方法是取图像 A 的负片并添加图像 B。

于 2009-12-29T22:11:24.630 回答
0

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

从 RGB 像素值中获取 BufferedImage 值

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

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

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

于 2012-09-30T17:01:56.013 回答