Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fastest way to compare pixel values between two BufferedImages?

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.

like image 623
George Armhold Avatar asked Dec 29 '09 17:12

George Armhold


People also ask

How are pixel values calculated?

Each pixel correspond to any one value. In an 8-bit gray scale image, the value of the pixel between 0 and 255. The value of a pixel at any point correspond to the intensity of the light photons striking at that point. Each pixel store a value proportional to the light intensity at that particular location.

How to compare two png files in java?

Read Both of them using the Image. Get the height and width of both of them to make sure they are equal. Get the pixel values and, get the RGB values of both of the images. Get the sum of the differences between the RGB values of these two images.


2 Answers

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.

like image 165
Kristopher Ives Avatar answered Sep 21 '22 03:09

Kristopher Ives


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.

like image 35
Mikeb Avatar answered Sep 24 '22 03:09

Mikeb