如何将灰度图像蒙版应用于java

时间:2016-05-06 02:05:26

标签: java image-processing mask grayscale marvin-framework

我被建议将这个问题与另一个问题分开。这是原始的:

How to change white background for black

在一些图像处理后,我得到一个二进制图像,但边界是如此的硬,所以我应用高斯滤波器来获得一个软的。结果是灰度图像。我需要将此图像应用为另一个图像的掩模,它们都没有alpha通道,因此需要在没有此值的情况下进行颜色混合。我正在使用Marvin Framework来完成这项工作,但Marvin没有插件,所以我编码一个,就是这样:

@Override public void process(MarvinImage _imageIn, MarvinImage _imageOut, MarvinAttributes attrOut, MarvinImageMask _mask, boolean previewMode) {

    MarvinImage mask = _imageIn;
    MarvinImage image = _imageOut;

    for(int y=0; y<mask.getHeight(); y++){
        for(int x=0; x<mask.getWidth(); x++){

            //ya que está en grayscale, los 3 valores son los mismos
            int r1 = mask.getIntComponent0(x, y);
            int g1 = mask.getIntComponent1(x, y);
            int b1 = mask.getIntComponent2(x, y);

            int r2 = image.getIntComponent0(x, y);
            int g2 = image.getIntComponent1(x, y);
            int b2 = image.getIntComponent2(x, y);

            //al color de salida, le asignamos la luminicencia de la imagen mascara
            int r = 0, g = 0, b = 0;
            if(r1 > 0 || r2 > 0){
                r = r1*r2/Math.max(r1, r2);
            }

            if(g1 > 0 || g2 > 0){
                g = g1*g2/Math.max(g1, g2);
            }

            if(b1 > 0 || b2 > 0){
                b = b1*b2/Math.max(b1, b2);
            }

            image.setIntColor(x, y, r, g, b);
        }
    }
}

但是这段代码有一个我无法解决的小错误。当rgb图像为白色时,颜色结果不能很好地组合,它不会变暗。我正在寻找的是使用gimp可以实现的东西,其中有一个2层图像,底部是rgb图像,上面一个是灰度蒙版,然后在这一层我们使用函数颜色到alpha,使用白色作为目标。结果是下一个:

Gimp mix

惠特算法是下一个:

Algorithm mix

差异非常明显。以下是两个用于测试的原始图像:

Color image Grayscale mask

1 个答案:

答案 0 :(得分:0)

您只需要将图像与蒙版进行Alpha组合。基本上输出图像像素是:

output_image(x,y)= input_image(x,y)* PI + mask_image(x,y)* PM

其中PI和PM分别是输出像素中输入和掩模图像的百分比。 PI + PM = 1(100%)

示例:

对于蒙版中的黑色像素:

PM = 1 - (灰度像素/ 255)→1 - (0/255)= 1

对于白色像素:

PM = 1 - (灰度像素/ 255)→1 - (255/255)= 0

对于灰色像素:

PM = 1 - (灰度像素/ 255)→1 - (127/255)= 0.5

最后:

PI = 1 - PM;

输出1:

enter image description here

源代码:

public class GrayScaleMask {

    public GrayScaleMask(){

        MarvinImage image = MarvinImageIO.loadImage("./res/grayscaleMask_input.png");
        MarvinImage mask = MarvinImageIO.loadImage("./res/grayscaleMask_mask.png");
        grayscaleMask(image.clone(), image, mask);
        MarvinImageIO.saveImage(image, "./res/grayscaleMask_output.png");
    }

    private void grayscaleMask(MarvinImage image, MarvinImage imageOut, MarvinImage mask){
        int r1,r2,g1,g2,b1,b2;
        double maskGray, factorMask, factorImage;
        for(int y=0; y<image.getHeight(); y++){
            for(int x=0; x<image.getWidth(); x++){
                r1 = image.getIntComponent0(x, y);
                g1 = image.getIntComponent1(x, y);
                b1 = image.getIntComponent2(x, y);
                r2 = mask.getIntComponent0(x, y);
                g2 = mask.getIntComponent1(x, y);
                b2 = mask.getIntComponent2(x, y);
                maskGray = (r2*0.21)+(g2*0.72)+(b2*0.07);
                factorMask = 1-(maskGray/255);
                factorImage = 1-factorMask;
                imageOut.setIntColor(x, y,  (int)(r1*factorImage+r2*factorMask),
                                            (int)(g1*factorImage+g2*factorMask),
                                            (int)(b1*factorImage+b2*factorMask));

            }
        }
    }

    public static void main(String[] args) {
        new GrayScaleMask(); System.exit(0);
    }
}

输出2:

你可以在组合之前使面具变暗:

    r2 = (int)(r2*0.3);
    g2 = (int)(g2*0.3);
    b2 = (int)(b2*0.3);
    imageOut.setIntColor(x, y,  (int)((r1*factorImage+r2*factorMask)),
                                (int)((g1*factorImage+g2*factorMask)),
                                (int)((b1*factorImage+b2*factorMask)));

enter image description here