Incorrect image subtraction result

I would like to subtract two images by pixels to check how similar they are. Images have the same size, which is slightly darker, and next to the brightness they do not differ. But I get these little dots as a result. Have I read these two images? Both are BMP files.

import java.awt.image.BufferedImage;
import java.io.File;   
import javax.imageio.ImageIO;

public class Main2 {
    public static void main(String[] args) throws Exception {
        int[][][] ch = new int[4][4][4];
        BufferedImage image1 = ImageIO.read(new File("1.bmp"));
        BufferedImage image2 = ImageIO.read(new File("2.bmp"));
        BufferedImage image3 = new BufferedImage(image1.getWidth(), image1.getHeight(), image1.getType());
        int color;
        for(int x = 0; x < image1.getWidth(); x++)
            for(int y = 0; y < image1.getHeight(); y++) {
                color = Math.abs(image2.getRGB(x, y) - image1.getRGB(x, y));                
                image3.setRGB(x, y, color);
            }
        ImageIO.write(image3, "bmp",  new File("image.bmp"));


    }
}

Image 1 enter image description here

Image 2

enter image description here

Result enter image description here

+3
source share
3 answers

The problem is that you cannot subtract colors directly. Each pixel is represented by one value int. This value intconsists of 4 bytes. These 4 bytes represent the color components of ARGB, where

A = Alpha
R = Red
G = Green
B = Blue

(Alpha is the opacity of the pixel and is always 255 (i.e. the maximum value) in BMP images).

,

(255, 0, 254, 0)

, (255, 0, 255, 0), : -1. , -

(255, 0, 254, 0) - 
(255, 0, 255, 0) = 
(255, 255, 255, 0)

, , , .


, A, R, G B . :

int argb0 = image0.getRGB(x, y);
int argb1 = image1.getRGB(x, y);

int a0 = (argb0 >> 24) & 0xFF;
int r0 = (argb0 >> 16) & 0xFF;
int g0 = (argb0 >>  8) & 0xFF;
int b0 = (argb0      ) & 0xFF;

int a1 = (argb1 >> 24) & 0xFF;
int r1 = (argb1 >> 16) & 0xFF;
int g1 = (argb1 >>  8) & 0xFF;
int b1 = (argb1      ) & 0xFF;

int aDiff = Math.abs(a1 - a0);
int rDiff = Math.abs(r1 - r0);
int gDiff = Math.abs(g1 - g0);
int bDiff = Math.abs(b1 - b0);

int diff = 
    (aDiff << 24) | (rDiff << 16) | (gDiff << 8) | bDiff;
result.setRGB(x, y, diff);

, : R, G B . 255, . ,

int argb0 = image0.getRGB(x, y);
int argb1 = image1.getRGB(x, y);

// Here the 'b' stands for 'blue' as well
// as for 'brightness' :-)
int b0 = argb0 & 0xFF;
int b1 = argb1 & 0xFF;
int bDiff = Math.abs(b1 - b0);

int diff = 
    (255 << 24) | (bDiff << 16) | (bDiff << 8) | bDiff;
result.setRGB(x, y, diff);
+9

" " . getRGB " RGB (TYPE_INT_ARGB)". , , - "" , , .

, 804020 - 404120 - 3FFF00; G, 1 FF.

, getRGB , , , , ( , Math.abs ), RGB.

0

I found this that does what you want. It seems to be doing the exact same thing, and it might be more "correct" than your code. I guess you can extract the source code.

http://tutorial.simplecv.org/en/latest/examples/image-math.html

/ Fredrik Walgren

0
source

All Articles