【问题标题】:Background removal/masking in Python using edge detection and scikit-image使用边缘检测和 scikit-image 在 Python 中去除背景/遮罩
【发布时间】:2016-09-11 02:11:54
【问题描述】:

我想从源 RAW 图像(在本例中为 Canon CR2)创建两个图像。我已经对 RAW 转换进行了排序和一些处理。我的最终图像需要是带有 alpha 蒙版的 PNG 和 95% 质量的 JPG,其中 alpha 区域用黑色填充。我在这里设置了一张测试图像,显示了我在检测主题方面取得的进展:

http://imgur.com/a/Q8k3w/all

所以基本上,如您所见,我想将主体与灰色背景隔离开来。我还想尽可能多地屏蔽掉灰色背景上的任何阴影,最好是完全屏蔽掉。我正在使用我编写的 Python2 脚本,到目前为止主要是 scikit-image。如果需要,我会换成另一个 Python 兼容的图像处理库。此外,我需要在内存中执行所有步骤,以便在使用 PNG 和 JPG 进行所有图像处理结束时只保存一次。所以没有 subprocess.Popen 等。

您会从示例图片中看到,至少我认为我已经找到了解决方案。对于您在我的示例中看到的图像,我使用了 scikit-image 及其 Canny 边缘算法。

我现在需要做的是弄清楚如何用白色填充 Canny 图像中的主题,以便我可以获得合适的纯白色蒙版。在我的大多数示例图像中,应用 Canny 过滤器后,似乎可以对主体本身进行良好的边缘检测,通常具有主要的完整边界。但是,我猜我将来可能会得到一些不会发生这种情况的图像,并且主要边界可能会有小中断。如果它看起来会成为以后处理步骤的问题,我需要处理这种情况。

另外,我想知道是否需要将整体边框增加一个像素并将其设置为与我的 0,0 像素相同的颜色(即背景中的第一个像素顶部/左侧),然后运行我的 Canny 过滤器和然后再次将我的边框缩小 1px?这应该允许检测到底部边缘以及主体何时打破框架的顶部或侧面?

所以说真的,我只是在寻找建议,想知道下一步该去哪里买一个漂亮的纯色面具。它需要保持二进制作为二进制掩码,(即主体之外的所有内容都需要完全掩码为 0)。这意味着我需要运行一些东西,在某个时候寻找低于某个像素体积的孤立像素岛 - 可能是最后一步并将它们添加到蒙版(例如 50 像素左右)。

此外,总体而言,经验法则是,最好遮盖一点主体,而不是遮盖更少的背景(即,我希望所有或尽可能多的背景/阴影区域被掩盖。)

我已经尝试了一些事情,但还没有达到目标。我在想一些类似于 sci_kit 中 find_contours 的东西可能会有所帮助。但是我不能从 scikit-image 示例中完全看到我将如何选择然后将检测到的轮廓变成蒙版。我今天花了很多时间进行实验但没有成功,所以我想我会在这里问一下,看看是否有人有更好的想法。

这是一种看起来很有前途的基于 OpenCV 的方法:

http://funcvis.org/blog/?p=44

如果可能的话,我想坚持使用 scikit-image 或其他一些可互换的 Python numty 图像库。但是,如果使用 OpenCV 或其他库更容易、更快捷,那么只要我能坚持使用 Python,我就会对想法持开放态度。

另外值得记住的是,对于我的应用程序,我将始终拥有没有主题的背景图像。所以也许我应该走这条路。问题是我认为简单的差异方法不能很好地处理阴影。在我看来,在某些时候需要某种边缘检测才能获得更好的掩蔽方法。

“来源1”

“来源 2”

“源 3”

“结果1”

“结果 2”

“结果 3”

【问题讨论】:

    标签: python opencv imagemagick scikit-image mahotas


    【解决方案1】:

    根据有限的经验,我会提供一些想法来尝试。

    Canny 边缘检测结果无法区分孔(在结果 2 对象中)和纯色区域(在结果 3 中)。这对你的目的来说可以吗?对这些边缘进行斑点检测并填充斑点是否符合您的需要,从而消除结果 2 中的漏洞?

    假设您要遮盖的部分是原始灰色背景区域以及该灰色背景上的较深灰色阴影。此外,一些最小化尺寸的灰色区域有资格作为“洞”而不是对象上的灰色像素或灰色噪声。 (有什么方法可以区分对象中看起来像灰色背景的部分吗?)

    所以考虑一下这个计划:

    1. 将图像转换为 HSV(或 HSL)色彩空间。
    2. 计算 8 位/像素灰度“阈值掩码”图像,其中每个像素指示相应的输入像素是可能背景还是可能前景:如果输入像素的饱和度低于阈值 ts(灰色或接近灰色)并且它的值(或亮度)在阈值范围[tv1 .. tv2](深阴影背景灰色到背景灰色),那么它很可能是背景,所以使输出像素为0(黑色),否则它可能是前景,因此将其设为 255(白色)。
    3. Dilate白色像素填补空白,然后Erode他们恢复原来的大小。这对操作也称为Closing 形态。 [请注意,该页面上的示例图片是一个令人困惑的示例。它会膨胀然后侵蚀样本图像的白色像素,这些像素很难不被视为黑白笔画!]

    以上假设原始背景是统一的灰色,实际样本中没有斑点。您可以通过使阈值参数成为原始背景颜色的函数来优化此计划以考虑背景变化。

    第 2 步和第 3 步会生成全有或全无的 Alpha 通道(蒙版)。在这些步骤中使用多个灰度级可能会更好(模糊逻辑),但如何做到这一点并不明显。

    注意:如果您使用 JPEG 2000 作为最终输出图像格式,则单个文件可以包含有损压缩图像及其 alpha 通道。它还可以保持原始 RAW 文件的全色深度。

    【讨论】:

      【解决方案2】:

      我要试一试。

      如果你想要干净的对象蒙版,有一种叫做自适应阈值(一种局部阈值方案)的东西,我认为它对你来说可能是可行的,特别是因为它可能会消除阴影的影响,以及尝试 Otsu 的阈值(另一种自动但全局的阈值方案)。

      看看哪一种效果更好,然后实施你想要的。

      我这样说是因为您的查询与经典的阈值问题(相同背景下的对象)非常相似。

      当然使用形态学操作来清洁你的面具(正如另一个用户所指出的那样,关闭就足以去除小的散斑噪声)。

      【讨论】:

        猜你喜欢
        • 2021-04-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-10-18
        • 1970-01-01
        • 2011-09-26
        • 1970-01-01
        • 2019-03-20
        相关资源
        最近更新 更多