java 如何将灰度图像蒙版应用于 rgb 图像
How to apply grayscale image mask to a rgb image in java
有人建议我将这个问题与另一个问题分开。原文如下:
How to change white background for black
经过一些图像处理后,我得到了一个二值图像,但是边界太硬了,所以我应用了一个高斯滤波器来得到一个柔和的图像。结果是灰度图像。我需要将此图像用作另一个图像的蒙版,其中 none 个图像具有 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)
您只需要对图像和蒙版进行 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:
源代码:
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)));
有人建议我将这个问题与另一个问题分开。原文如下:
How to change white background for black
经过一些图像处理后,我得到了一个二值图像,但是边界太硬了,所以我应用了一个高斯滤波器来得到一个柔和的图像。结果是灰度图像。我需要将此图像用作另一个图像的蒙版,其中 none 个图像具有 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)
您只需要对图像和蒙版进行 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:
源代码:
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)));