如何从python中的图像中删除白色模糊

And*_*e31 3 python image-processing python-imaging-library

我正在尝试从产品图片中删除背景,将它们另存为透明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")
Run Code Online (Sandbox Code Playgroud)

有什么想法可以解决这个问题,让我得到干净的选择吗?

Mar*_*ell 5

复制图像并使用PIL / Pillow的ImageDraw.floodfill()以合理的公差从左上角进行填充-这样,您将只填充到衬衫的边缘并避免使用Nike徽标。

然后将背景轮廓设为白色,将其他所有颜色设为黑色,然后尝试应用某种形态(可能来自scikit图像)以将白色放大一些,以隐藏锯齿。

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


我真的很想争取时间,但这是关键。只是在开始时缺少原始图像的副本,而putalpha()在结尾处则缺少新的alpha层的副本...

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()
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

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()
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

# 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()
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

如果您不熟悉形态学,那么安东尼·蒂森(Anthony Thyssen)的一些出色观点值得在这里阅读。

顺便说一句,您也可以使用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')
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明


至于potrace用于平滑轮廓,您将另存new alphaPIL为PGM格式的图像,因为这potrace就像输入一样。因此将是:

newalphaPIL.save('newalpha.pgm')
Run Code Online (Sandbox Code Playgroud)

现在,你可以玩,哎呀我的意思是“小心实验”与potrace平滑阿尔法轮廓。基本命令是:

potrace -b pgm newalpha.pgm -o smoothalpha.pgm
Run Code Online (Sandbox Code Playgroud)

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

在此处输入图片说明

仔细查看边缘以发现差异。您可能需要尝试将alpha大小调整为两倍大小或一半大小,然后再进行平滑处理以查看效果如何。