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

发布于 2024-08-16 10:52:03 字数 568 浏览 4 评论 0原文

我有一个 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 还是通过我可能错过的第 3 方 API。

I have a BufferedImage of type TYPE_INT_BGR. I need to do a pixel-by-pixel comparison to another BufferedImage to compute the "distance" between the two images. I have something that works, but is slow. I get a pixel from the "reference" image, break it up into RGB bytes with:

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

I compare the r/g/b values to the corresponding pixel of the candidate image, and sum up the squares the differences.

Is there a faster way to do this kind of comparison? Peeking into the JRE source, I see that BufferedImage.getRGB() is actually ORing the constituent RGB values from the raster together, which is wasteful for my purposes, since I'm just breaking it down into bytes again.

I'm going to try doing that directly, but I wonder if there is not a better way of doing this, either via a Java or 3rd party API that I might have missed.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

情深已缘浅 2024-08-23 10:52:03

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

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

Reading data from a VolatileImage will not be faster. What makes VolatileImages "faster" is that they use accelerated (VRAM) memory instead of system (RAM) memory for drawing images. However, when doing a read, it may need to access memory over another bus and is slower than system memory for those operations.

The fastest way to compare BufferedImages would be to use integer comparisons the way you discuss in your post, but as you mention you can't use getRGB for performance reasons. You can get a batch of pixels into an array, but overall you should probably just peek into the Raster and DataBuffer for performance.

琴流音 2024-08-23 10:52:03

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

If both images use the same color model and sampling, you can perform your comparison on the DataBuffer of the raster, which will be a little faster.

笛声青案梦长安 2024-08-23 10:52:03

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

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

Have you considered using Java2D to create a new image being the difference between the two images you have, and then analyse the difference image instead?

My initial approach would be taking the negative of image A and add image B.

奶茶白久 2024-08-23 10:52:03

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

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

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

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

If breaking down to bytes + loading extra classes is the problem, try this:

Getting the BufferedImage value form a RGB pixel value

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

Getting a RGB value from a BufferedImage value 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));

I am not sure if this is a better/faster way to do it, but it is another alternative method that does not use any extra classes, and is a straight math process (or a hack)... This may become useful on some occasions (please double-check since it is my own method that I didn't have enough time to play with).

I don't know about the kind of comparison you needed between the pixel values, so this is how far this post goes... I hope someone actually finds this helpful!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文