我正在寻找一种从很多照片中自动删除(=透明)“绿色屏幕”肖像背景的方法。
我自己的尝试到目前为止......呃...不太成功。
我正在寻找关于此主题的任何提示或解决方案或论文。商业解决方案也很好。
在您发表评论之前,并说不可能自动执行此操作:不,不是。实际上有一家公司提供这种服务,如果我没有提出不同的解决方案,我们就会使用它们。问题是他们用自己的生命保护算法,因此不会出售/许可他们的软件。相反,我们必须将所有图片FTP到处理完成的地方,然后我们将结果FTP回家。 (不,他们没有隐藏在菲律宾的工资过低的工作人员手动处理这个问题,因为我们每天都在谈论数千张图片 ...)但是,这种做法限制了它的用处有几个原因。所以我真的很喜欢这样一个解决方案,可以在互联网离线时立即完成。
编辑:我的“肖像”描绘的人有头发 - 这是一个非常棘手的部分,因为绿色背景会流入头发。另一个棘手的部分是,如果有可能在背景中的绿色和人们衣服中的相同绿色之间进行distingush。我上面谈到的公司声称,他们可以通过弄清楚绿色区域是否在焦点(锐利与模糊)来做到这一点。
答案 0 :(得分:18)
由于您没有提供任何图像,我选择了网络中的一个色度键,具有不同的绿色阴影和由于JPEG压缩而产生的大量噪点。
没有技术规范,因此我使用了Java和Marvin Framework。
输入图片:
步骤 1 只是将绿色像素转换为透明度。基本上它在HSV颜色空间中使用过滤规则。
正如您所提到的,头发和一些边界像素呈现出与绿色混合的颜色。要减少此问题,请在步骤 2 中对这些像素进行过滤和平衡,以降低其绿色比例。
<强>之前:强>
<强>后:强>
最后,在 3 步骤中,渐变透明度应用于所有边界像素。高质量图像的效果会更好。
最终输出:
源代码:
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();
}
}
答案 1 :(得分:3)
如果您知道“绿色”,您可以在opencv C / C ++ / Python中编写一个小程序来提取该颜色并替换为透明像素。
答案 2 :(得分:2)
看一下这个帖子: http://www.wizards-toolkit.org/discourse-server/viewtopic.php?f=2&t=14394&start=0
以及其中的教程链接: http://tech.natemurray.com/2007/12/convert-white-to-transparent.html
然后,只需编写一些脚本来查看完整的图像目录。很简单。
答案 3 :(得分:2)
123视频魔术绿屏背景软件还有一些刚刚删除绿屏的背景希望这有帮助
答案 4 :(得分:1)
PaintShop Pro允许您根据拾取颜色删除背景。他们还有一个删除背景棒,可以删除你触摸的任何东西(将这些像素转换为透明)。您可以调整魔杖的“容差”,使其取出与您正在触摸的像素类似的像素。这在过去对我来说非常有效。
要自动化它,您可以在PSP中编写一个脚本,它可以执行您想要的操作,然后从您的程序中调用它。这可能是一种自动替换的方法,但它是最便宜,最快的解决方案,无需编写大量C#/ C ++映像代码或支付商业代理费。
他们说,你付出的代价是什么。