【问题标题】:How to remove a "green screen" portrait background如何删除“绿屏”肖像背景
【发布时间】:2010-05-11 13:16:07
【问题描述】:

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

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

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

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

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

【问题讨论】:

  • “头发”要求到底是从哪里来的?它出现在您的 cmets 中,但在原始规范中没有。我认为您可能应该更详细地扩展您的问题。如果是你对这些答案投了反对票,那是很糟糕的形式,因为它是你的不充分说明问题的不足。
  • 好吧,很抱歉造成混乱,但对我来说,无论如何,肖像描绘了一个人?我错了吗?而且很多人确实有头发......
  • 啊,现在说得通了。当您谈论我和我的同类周围的“绿屏”时,这与大型机 3270 终端会话 (upload.wikimedia.org/wikipedia/commons/a/a8/IBM-3279.jpg) 有关,而不是电影中的“超人在空中飞翔”。
  • danbystrom 你有没有解决过这个问题。我查看了@k00k 发布的链接,我将尝试为我们的访问者提供他们旅行的免费照片。我想和你一起工作。
  • 嗨@Kelbizzle,我有一个相当不错的解决方案,我从头开始实施。它是不是总部,但如果我将它应用到高分辨率图片上,然后将其缩小到 384x512 像素,那么几乎所有的瑕疵都会变得不可见。

标签: image-processing chromakey


【解决方案1】:

由于您没有提供任何图片,我从网络上选择了一张具有色度键的具有不同深浅的绿色以及由于 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();
    }
}

【讨论】:

  • 嗨,加布里埃尔,我六年前写了这个问题,但显然有人对此给予了赏金 - 我希望他会对你的努力发表评论。对于这个在生产环境中运行多年的问题,我已经有了一个可以接受的解决方案。您提供了一个带有大量压缩伪影的 lores 图像,因此它无法代表我正在工作的域,但有一天我会在我的测试图像上运行您的代码以查看差异。然而,我现在想解决的问题是如何区分同色的背景和布料,但那是另一回事了。干得好 - 干杯!
  • 丹,你有没有人穿同色布的画框?发给我:garchanjo dot com 的 gabriel。让我看一看。也许我可以帮忙。
  • 我看看能不能挖点东西。 PS。我暂时接受了你的答案,因为它是迄今为止最好的 - 所以你会得到你的 100 赏金。圣诞快乐。
  • 我们可以使用类似的代码从视频中删除背景吗?这段代码的性能如何?我认为将视频转换为单独的相框,对其进行处理,然后重新组合以减少背景视频会占用大量资源。
  • 是的,你可以!您甚至可以在更复杂的情况下移除背景,例如:youtube.com/watch?v=bwEGeI7E0n0
【解决方案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

然后只需编写一些脚本来查看充满图像的目录即可。很简单。

【讨论】:

  • 我应该注意,我没有尝试过这个,YMMV。尤其是在抗锯齿和柔和边缘方面。
  • 这将花费我相当多的时间来完成,但这似乎正是我想要学习的东西!虽然我严重怀疑“相当简单”的部分! :-)
  • 嘿,我的意思是脚本部分是简单的部分。 :)
【解决方案3】:

如果你知道“绿色”,你可以在opencvC/C++/Python 中编写一个小程序来提取该颜色并替换为透明像素。

【讨论】:

  • 我可以通过检查我知道应该主要包含绿色的区域并计算中值来找到绿色......但问题是头发,头发,头发......绿色渗入头发并与之混合......然后我们遇到相同绿色衣服的问题......
  • 根据您上面的描述,我的回答是正确的。根据您的评论,它不是。但是我为什么要提前知道它值得否决呢?祝您搜索愉快。
  • 是的,我也这么认为。我不是那个反对你的人。我认为您的回答完全有效(尽管不适用 - 如前所述)。
  • 赞成,因为我认为反对票是不公平的,无论来源如何。我误解了这个问题,所以小人物可能也有 :-) 如果您同意答案与问题不匹配,您可能需要考虑在前面删除答案。
【解决方案4】:

123 Video Magic Green Screen Background Software,还有一些刚刚制作的去除绿屏背景希望对您有所帮助

【讨论】:

  • 我看不到他们提供了我可以自己使用的 API? “FXhome”有支持“hotfolder”的软件,但不幸的是这还不够好。幸运的是 - 我自己已经取得了巨大的进步,但我还不完全在那里......但是......
【解决方案5】:

PaintShop Pro 允许您根据选择颜色来移除背景。他们还有一个移除背景棒,可以移除你触摸的任何东西(将这些像素转换为透明)。您可以调整魔杖的“容差”,使其去除与您触摸的像素相似的像素。过去这对我来说效果很好。

要使其自动化,您可以在 PSP 中编写一个脚本,该脚本可以执行您想要的操作,然后从您的程序中调用它。这可能是一种进行自动替换的笨拙方式,但它是最便宜、最快的解决方案,无需编写一堆 C#/C++ 成像代码或向商业机构付费。

他们说,你付出你所得到的。

【讨论】:

  • 我相信他正在寻找一种自动化的“服务器端”解决方案。
  • 首先我说的是自动。这不可能解决绿色通过(尤其是金色)头发反射和闪耀的问题。这需要相当多的手工工作。每天需要多少人才能处理 5000 张图片...?
  • PSP 可以自动化。它可能很笨拙,但您可以编写通过命令运行的脚本。
  • 赞成,因为我认为反对票是不公平的,无论来源如何。我误解了这个问题,所以小人物可能也有 :-) 如果您同意答案与问题不匹配,您可能需要考虑在前面删除答案。
  • 在阅读了这个帖子之后(并且使用了 Paint Shop Pro 多年),我意识到编写自己的基本“绿屏去除器”网页非常容易,然后您可以保存结果到 .png 文件。这比使用 PSP 容易很多mikesknowledgebase.com/pages/Other/ImageBackgroundRemover.htm
猜你喜欢
  • 2019-01-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-30
相关资源
最近更新 更多