【问题标题】:How to remove white fuzziness from image in python如何从python中的图像中去除白色模糊
【发布时间】:2019-07-17 17:26:43
【问题描述】:

我正在尝试从产品图像中删除背景,将它们保存为透明 png,结果我无法弄清楚我是如何以及为什么会像模糊一样在产品周围出现白线(参见第二张图片) 不知道效果的真实含义。我也失去了白色的耐克旋风:(

from PIL import Image

img = Image.open('test.jpg')
img = img.convert("RGBA")
datas = img.getdata()


newData = []


for item in datas:
    if item[0] > 247 and item[1] > 247 and item[2] > 247:
        newData.append((255, 255, 255, 0))
    else:
        newData.append(item)

img.putdata(newData)
img.save("test.png", "PNG")

有什么想法可以解决这个问题,以便获得干净的选择和边缘?

【问题讨论】:

    标签: python image-processing python-imaging-library


    【解决方案1】:

    复制您的图像并使用 PIL/Pillow 的 ImageDraw.floodfill() 以合理的容差从左上角填充填充 - 这样您只会填充到衬衫的边缘并避免出现 Nike 标志.

    然后将背景轮廓设为白色,将其他所有部分设为黑色,并尝试应用一些形态学(可能来自 scikit-image)将白色放大一点以隐藏锯齿。

    最后,使用putalpha()将生成的新图层放入图像中。


    我真的很赶时间,但这里是它的骨头。只是缺少开头的原始图像副本和末尾的新 alpha 层的putalpha()...

    from PIL import Image, ImageDraw
    import numpy as np
    import skimage.morphology
    
    # Open the shirt
    im = Image.open('shirt.jpg')
    
    # Make all background pixels (not including Nike logo) into magenta (255,0,255)
    ImageDraw.floodfill(im,xy=(0,0),value=(255,0,255),thresh=10)
    
    # DEBUG
    im.show()
    

    在此处使用阈值 (thresh) 进行实验。如果你将它设为 50,它会更干净地工作,并且可能足以停止。

    # Make into Numpy array
    n = np.array(im)
    
    # Mask of magenta background pixels
    bgMask =(n[:, :, 0:3] == [255,0,255]).all(2)
    
    # DEBUG
    Image.fromarray((bgMask*255).astype(np.uint8)).show()
    

    # Make a disk-shaped structuring element
    strel = skimage.morphology.disk(13)
    
    # Perform a morphological closing with structuring element
    closed = skimage.morphology.binary_closing(bgMask,selem=strel)
    
    # DEBUG
    Image.fromarray((closed*255).astype(np.uint8)).show()
    

    如果您不熟悉形态学,Anthony Thyssen 有一些值得一读的优秀文章 here

    顺便说一句,您也可以使用potrace 稍微平滑轮廓。


    我今天有更多的时间,所以这里有一个更完整的版本。您可以根据自己的图像对形态盘大小和填充阈值进行试验,直到找到适合您需求的内容:

    #!/bin/env python3
    
    from PIL import Image, ImageDraw
    import numpy as np
    import skimage.morphology
    
    # Open the shirt and make a clean copy before we dink with it too much
    im = Image.open('shirt.jpg')
    orig = im.copy()
    
    # Make all background pixels (not including Nike logo) into magenta (255,0,255)
    ImageDraw.floodfill(im,xy=(0,0),value=(255,0,255),thresh=50)
    
    # DEBUG
    im.show()
    
    # Make into Numpy array
    n = np.array(im)
    
    # Mask of magenta background pixels
    bgMask =(n[:, :, 0:3] == [255,0,255]).all(2)
    
    # DEBUG
    Image.fromarray((bgMask*255).astype(np.uint8)).show()
    
    # Make a disk-shaped structuring element
    strel = skimage.morphology.disk(13)
    
    # Perform a morphological closing with structuring element to remove blobs
    newalpha = skimage.morphology.binary_closing(bgMask,selem=strel)
    
    # Perform a morphological dilation to expand mask right to edges of shirt
    newalpha = skimage.morphology.binary_dilation(newalpha, selem=strel)
    
    # Make a PIL representation of newalpha, converting from True/False to 0/255
    newalphaPIL = (newalpha*255).astype(np.uint8)
    newalphaPIL = Image.fromarray(255-newalphaPIL, mode='L')
    
    # DEBUG
    newalphaPIL.show()
    
    # Put new, cleaned up image into alpha layer of original image
    orig.putalpha(newalphaPIL)
    orig.save('result.png')
    


    关于使用potrace 来平滑轮廓,您可以将new alphaPIL 保存为PGM 格式的图像,因为这是potrace 喜欢的输入。那就是:

    newalphaPIL.save('newalpha.pgm')
    

    现在你可以玩了,哎呀,我的意思是 “仔细实验” 使用 potrace 来平滑 alpha 轮廓。基本命令是:

    potrace -b pgm newalpha.pgm -o smoothalpha.pgm
    

    然后,您可以将图像 smoothalpha.pgm 重新加载到您的 Python 中,并在 putalpha() 调用的最后一行使用它。这是原始未平滑 alpha 和平滑后 alpha 之间差异的动画:

    仔细观察边缘,看看有什么不同。您可能希望在平滑之前尝试将 alpha 的大小调整为两倍或一半,看看有什么效果。

    【讨论】:

    • 我添加了一些代码来帮助您入门。请注意,使用 JPEG 存储图像会导致丑陋。
    • 我在里面多放了一些debug语句,并穿插了对应的图片,这样更清晰。
    • @VasuDeo.S 对不起!我总是尝试包含我的 imports,但有时我会错过一些,因为我在 IPython 中以交互方式测试我的代码,有时我在最终确定答案时会错过一个步骤。我已经添加到import skimage.morphology
    • 我添加了更多的 cmets 和对我的答案的引用来帮助你,因为这对你来说是全新的。
    • 我有更多时间,所以我在答案的末尾添加了更多内容 - 请再看一下。
    猜你喜欢
    • 1970-01-01
    • 2015-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-22
    • 2021-10-12
    • 2020-01-05
    • 1970-01-01
    相关资源
    最近更新 更多