简体   繁体   中英

Combining greyscale images through averaging

I have a program which uses getRed() , getGreen() and getBlue() which works fine. Im looking to see if I can find some other algorithms which also color greyscale images, whether it be more or less accurate it doesnt matter, its just something im looking into to compare the methods and their accuracy. I decided to use a similar method, just by using getRed() for image 1, 2 and 3 (as opposed to just 1) and dividing by 3 for each colour, in theory achieving the average red, green and blue values across the 3 images and creating a new image from it.

The resulting image is quite strange; the colors arent uniform ie random colours for each pixel, you can barely make out any characteristics of the image as its so grainy, I suppose is the best way to describe it. It looks like a normal photograph but with colour noise everywhere. Just wondering if anyone knew why this is happening? It wasnt my intentions and was expecting much more normal, quite similar to the original method but maybe more subdued/brighter colors for each.

Anyone know why this is happening? It doesnt seem right. Are there any other methods I could use to colour the images apart from the standard getRGB() ways?

BufferedImage combinedImage = new BufferedImage(image1.getWidth(), image1.getHeight(), image1.getType());
        for(int x = 0; x < combinedImage.getWidth(); x++)
            for(int y = 0; y < combinedImage.getHeight(); y++)
                combinedImage.setRGB(x, y, new Color(
                new Color((image1.getRGB(x, y) + image2.getRGB(x, y) + image3.getRGB(x, y))/3).getRed(), 
                new Color((image1.getRGB(x, y) + image2.getRGB(x, y) + image3.getRGB(x, y))/3).getGreen(), 
                new Color((image1.getRGB(x, y) + image2.getRGB(x, y) + image3.getRGB(x, y))/3).getBlue()).
                getRGB());

Thanks in advance

getRGB() returns the int representations of a pixel, including the alpha channel. Since a int is 4-byte (32 bits), this int will be like this:

01010101 11111111 10101010 11111111
  Alpha     Red     Green    Blue

When you add the three values, this is using the alpha channel too, so I guess this is making you get strange results. Also, adding ints this way can cause "overflow" in one of the channels. For example, if one pixel has a blue value of 255 and another one has a value of 2, the sum will have a value 1 for green and value 1 for blue.

To extract each color channel from the int you can do this.

red = (rgb >> 16) & 0xFF;
green = (rgb >>8 ) & 0xFF;
blue = (rgb) & 0xFF;

(This is what Color class does internally inside getRed(), getBlue() and getGreen() http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/awt/Color.java#Color.getRed%28%29 )

Then, combine the colors like this:

combinedImage.setRGB(x, y, new Color(
((image1.getRGB(x, y) >> 16 & 0xFF) + (image1.getRGB(x, y) >> 16 & 0xFF) + (image1.getRGB(x, y) >> 16 & 0xFF))/3, 
((image1.getRGB(x, y) >> 8 & 0xFF) + (image1.getRGB(x, y) >> 8 & 0xFF) + (image1.getRGB(x, y) >> 8 & 0xFF))/3, 
((image1.getRGB(x, y) & 0xFF) + (image1.getRGB(x, y) & 0xFF) + (image1.getRGB(x, y) & 0xFF))/3).
getRGB());

Or use new Color(image1.getRGB(x, y)).getRed() each time for each image.

combinedImage.setRGB(x, y, new Color(
    (new Color(image1.getRGB(x, y)).getRed() + new Color(image2.getRGB(x, y)).getRed() + new Color(image3.getRGB(x, y)).getRed())/3, 
    (new Color(image1.getRGB(x, y)).getGreen() + new Color(image2.getRGB(x, y)).getGreen() + new Color(image3.getRGB(x, y)).getGreen())/3, 
    (new Color(image1.getRGB(x, y)).getBlue() + new Color(image2.getRGB(x, y)).getBlue() + new Color(image3.getRGB(x, y)).getBlue())/3).
    getRGB());

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM