2016-10-04 96 views
1

我有一套气象RGB类型BufferedImage s。我想获得他们的平均形象。由此,我的意思是获得每个像素的平均值,并从这些值中创建一个新图像。我试过的是:在java中获取一组图像的平均图像

public void getWaveImage(BufferedImage input1, BufferedImage input2){ 
    // images are of same size that's why i'll use first one's width and height 
    int width = input1.getWidth(), height = input1.getHeight(); 

    BufferedImage output = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); 

    int[] rgb1 = input1.getRGB(0, 0, width, height, new int[width * height], 0, width); 
    int[] rgb2 = input2.getRGB(0, 0, width, height, new int[width * height], 0, width); 
    for(int i=0; i<width; i++){ 
     for(int j=0; j<height; j++){ 
     int rgbIndex = i * width + j; 
     rgb1[rgbIndex] = (rgb1[rgbIndex] + rgb2[rgbIndex])/2; 
     } 
    } 

    output.setRGB(0, 0, width, height, rgb1, 0, width); 
    return output; 
} 

我在做什么错了?先谢谢你。

输入1:

enter image description here

输入2:

enter image description here

输出:

enter image description here

+0

首先定义你的平均含义...... – Tschallacka

+1

我不认为使用''rgb1 [rgbIndex] + rgb2 [rgbIndex])/ 2''会给你两种输入颜色之间的颜色。 – f1sh

+0

@Tschallacka对不起,我现在添加了。 – halil

回答

5

希望每个平均COM颜色的分量,平均红色,平均绿色,平均蓝色。

相反,你正在平均整个int。

Color c1 = new Color(rgb1[rgbIndex]); 
Color c2 = new Color(rgb2[rgbIndex]); 
Color cA = new Color((c1.getRed() + c2.getRed())/2, 
        (c1.getGreen() + c2.getGreen())/2, 
        (c1.getBlue() + c2.getBlue())/2); 
rgb1[rgbIndex] = cA.getRGB(); 

这可能不是最有效的,由于创造这么多的对象,这样更直接的方式是像这样:

public static int average(int argb1, int argb2){ 
    return (((argb1  & 0xFF) + (argb2  & 0xFF)) >> 1)  | //b 
      (((argb1 >> 8 & 0xFF) + (argb2 >> 8 & 0xFF)) >> 1) << 8 | //g 
      (((argb1 >> 16 & 0xFF) + (argb2 >> 16 & 0xFF)) >> 1) << 16 | //r 
      (((argb1 >> 24 & 0xFF) + (argb2 >> 24 & 0xFF)) >> 1) << 24; //a 
} 

用法:

rgb1[rgbIndex] = average(rgb1[rgbIndex], rgb2[rgbIndex]); 
3

如果您有:

int rgb1, rgb2; //the rgb value of a pixel in image 1 and 2 respectively 

“平均”颜色是:

int r = (r(rgb1) + r(rgb2))/2; 
int g = (g(rgb1) + g(rgb2))/2; 
int b = (b(rgb1) + b(rgb2))/2; 

int rgb = ((r & 0xFF) << 16) | ((g & 0xFF) << 8) | ((b & 0xFF) << 0); 

与下面的“帮手”的方法:

private static int r(int rgb) { return (rgb >> 16) & 0xFF; } 
private static int g(int rgb) { return (rgb >> 8) & 0xFF; } 
private static int b(int rgb) { return (rgb >> 0) & 0xFF; } 

或者您可以使用Color类,如果你不希望处理位操作。

1

另一种解决方案可以是具有

rgb1[rgbIndex] = ((rgb1[rgbIndex]>>1)&0x7f7f7f7f)+((rgb2[rgbIndex]>>1)&0x7f7f7f7f)+(rgb1[rgbIndex]&rgb2[rgbIndex]&0x01010101); 

二进制右移位,以取代

rgb1[rgbIndex] = (rgb1[rgbIndex] + rgb2[rgbIndex])/2; 

除以2,总和的最后一个成员来处理两个奇数的情况下。

+0

好点儿 - 扭曲! – weston