12

我正在寻找一种从大量图片中自动删除(=使透明)“绿屏”肖像背景的方法。

到目前为止,我自己的尝试都......嗯......不太成功。

我正在四处寻找有关该主题的任何提示或解决方案或论文。商业解决方案也很好。

在您发表评论并说不可能自动执行此操作之前:不,不是。实际上存在一家提供这种服务的公司,如果我无法提出不同的解决方案,我们将使用它们。问题是他们用生命保护他们的算法,因此不会出售/许可他们的软件。相反,我们必须在处理完成的地方将所有图片通过 FTP 传输给他们,然后我们将结果通过 FTP 传输回家。(不,他们没有隐藏在菲律宾的工资过低的员工来手动处理这个问题,因为我们每天要谈论几千张照片......)但是,这种方法由于几个原因限制了它的有用性。所以我真的很想要一个解决方案,它可以在从互联网离线时立即完成。

编辑:我的“肖像”描绘了确实有头发的人- 这是一个非常棘手的部分,因为绿色背景会渗入头发。另一个棘手的部分是是否可以区分背景中的绿色和人们衣服中的相同绿色。我在上面谈论的公司声称他们可以通过确定绿色区域是否在焦点上(清晰与模糊)来做到这一点。

4

5 回答 5

27

由于您没有提供任何图像,因此我从网络上选择了一个具有不同绿色阴影的色度键以及由于 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();
    }
}
于 2016-12-16T12:33:38.097 回答
2

Take a look at this thread: http://www.wizards-toolkit.org/discourse-server/viewtopic.php?f=2&t=14394&start=0

and the link within it to the tutorial at: http://tech.natemurray.com/2007/12/convert-white-to-transparent.html

Then it's just a matter of writing some scripts to look through the directory full of images. Pretty simple.

于 2010-05-11T13:23:42.750 回答
2

If you know the "green color" you may write a small program in opencv C/C++/Python to do extract that color and replace with transparent pixels.

于 2010-05-11T13:24:17.840 回答
2

123 Video Magic绿屏背景软件,还有一些只是为了去除绿屏背景希望这有帮助

于 2011-11-12T05:54:47.643 回答
1

PaintShop Pro allows you to remove backgrounds based on picking a color. They also have a Remove Background wand that will remove whatever you touch (converting those pixels to transparent). You can tweak the "tolerance" for the wand, such that it takes out pixels that are similar to the ones you are touching. This has worked pretty well for me in the past.

To automate it, you'd program a script in PSP that does what you want and then call it from your program. This might be a kludgy way to to do automatic replacement, but it would be the cheapest, fastest solution without having to write a bunch of C#/C++ imaging code or pay a commercial agency.

They being said, you pay for what you get.

于 2010-05-11T13:20:25.180 回答