【问题标题】:How to apply grayscale image mask to a rgb image in java如何在java中将灰度图像蒙版应用于rgb图像
【发布时间】:2016-08-31 23:30:43
【问题描述】:

有人建议我将此问题与另一个问题分开。这是原文:

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 图像,上层是灰度蒙版,然后在这一层中我们使用函数 color to alpha,使用白色作为目标。结果如下:

接下来是算法:

区别非常明显。这是用于测试的两个原始图像:


(来源:imgsafe.org)

【问题讨论】:

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


    【解决方案1】:

    您只需要将图像与蒙版进行 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 - 下午;

    输出 1:

    源代码:

    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)));
    

    【讨论】:

    • 你的算法似乎更线性地绘制了渐变,但仍然是一些灰色而不是黑色
    • 我正在尝试使用您的算法,但我选择了 factorMask,路径错误。这就是我要的。感谢您的宝贵时间。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-01
    • 2021-06-02
    • 2012-08-25
    • 2016-09-16
    • 1970-01-01
    相关资源
    最近更新 更多