复制您的图像并使用 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 的大小调整为两倍或一半,看看有什么效果。