由于您没有提供任何图像,因此我从网络上选择了一个具有不同绿色阴影的色度键以及由于 JPEG 压缩而产生的大量噪声。
没有技术规范,所以我使用了 Java 和Marvin Framework。
输入图像:
![在此处输入图像描述](https://i.stack.imgur.com/TY78Y.jpg)
步骤1只是将绿色像素转换为透明度。基本上它使用 HSV 颜色空间中的过滤规则。
![在此处输入图像描述](https://i.stack.imgur.com/9tcQ6.png)
正如您所提到的,头发和一些边界像素呈现出混合了绿色的颜色。为了减少这个问题,在步骤2中,这些像素被过滤和平衡以减少其绿色比例。
前:
![在此处输入图像描述](https://i.stack.imgur.com/26neu.png)
后:
![在此处输入图像描述](https://i.stack.imgur.com/OhEVB.png)
最后,在步骤3中,对所有边界像素应用渐变透明度。使用高质量的图像效果会更好。
最终输出:
![在此处输入图像描述](https://i.stack.imgur.com/FkshY.png)
源代码:
import static marvin.MarvinPluginCollection.*;
public class ChromaToTransparency {
public ChromaToTransparency(){
MarvinImage image = MarvinImageIO.loadImage("./res/person_chroma.jpg");
MarvinImage imageOut = new MarvinImage(image.getWidth(), image.getHeight());
// 1. Convert green to transparency
greenToTransparency(image, imageOut);
MarvinImageIO.saveImage(imageOut, "./res/person_chroma_out1.png");
// 2. Reduce remaining green pixels
reduceGreen(imageOut);
MarvinImageIO.saveImage(imageOut, "./res/person_chroma_out2.png");
// 3. Apply alpha to the boundary
alphaBoundary(imageOut, 6);
MarvinImageIO.saveImage(imageOut, "./res/person_chroma_out3.png");
}
private void greenToTransparency(MarvinImage imageIn, MarvinImage imageOut){
for(int y=0; y<imageIn.getHeight(); y++){
for(int x=0; x<imageIn.getWidth(); x++){
int color = imageIn.getIntColor(x, y);
int r = imageIn.getIntComponent0(x, y);
int g = imageIn.getIntComponent1(x, y);
int b = imageIn.getIntComponent2(x, y);
double[] hsv = MarvinColorModelConverter.rgbToHsv(new int[]{color});
if(hsv[0] >= 60 && hsv[0] <= 130 && hsv[1] >= 0.4 && hsv[2] >= 0.3){
imageOut.setIntColor(x, y, 0, 127, 127, 127);
}
else{
imageOut.setIntColor(x, y, color);
}
}
}
}
private void reduceGreen(MarvinImage image){
for(int y=0; y<image.getHeight(); y++){
for(int x=0; x<image.getWidth(); x++){
int r = image.getIntComponent0(x, y);
int g = image.getIntComponent1(x, y);
int b = image.getIntComponent2(x, y);
int color = image.getIntColor(x, y);
double[] hsv = MarvinColorModelConverter.rgbToHsv(new int[]{color});
if(hsv[0] >= 60 && hsv[0] <= 130 && hsv[1] >= 0.15 && hsv[2] > 0.15){
if((r*b) !=0 && (g*g) / (r*b) >= 1.5){
image.setIntColor(x, y, 255, (int)(r*1.4), (int)g, (int)(b*1.4));
} else{
image.setIntColor(x, y, 255, (int)(r*1.2), g, (int)(b*1.2));
}
}
}
}
}
public static void main(String[] args) {
new ChromaToTransparency();
}
}