使用Python和Pillow(PIL)填充空心形状

6
我正在尝试编写一个方法,该方法将填充给定形状,使其变成纯黑色。
例如: 这个八边形最初只是一个轮廓,将变成一个纯黑色的实心八边形,但只要所有边缘都关闭,这应该适用于任何形状。 八边形
def img_filled(im_1, im_2):
    img_fill_neg = ImageChops.subtract(im_1, im_2)
    img_fill = ImageOps.invert(img_fill_neg)
    img_fill.show()

我已经仔细阅读了文档十遍,并找到了几种其他的操作图像的方法,但是我找不到一个例子来填充图像中预先存在的形状。我看到使用floodfill()是一种选择,但我不确定如何抓取我想要填充的形状。
注意:我在这个任务中没有访问任何其他的图像处理库。

你可能没有用“泛洪填充”这个术语进行搜索,但这似乎是你想要做的,即如何使用所选颜色泛洪填充由黑色边框包围的位图的一部分? - Nick T
感谢你的建议,Nick T。我也看过那个页面。使用那种方法遇到的问题是,我不知道怎么获取我要填充的形状。floodfill(img, (x,y), value, border)需要4个参数,我在(x,y)上遇到了麻烦,因为我不想选定特定的像素,而是想要整个形状。谢谢任何建议。 - Thomas Eggenberger
我会重新阐述问题,即“如何找到形状内部的一个点”或类似的问题。 - Nick T
1
您可以通过查找轮廓来找到形状。在您的图像中,您将有一个轮廓。完成后,您可以找到轮廓的质心,并使用该点执行泛洪填充操作。 - Jeru Luke
1个回答

1
有几种方法可以做到这一点。您可以像我在这里做的那样,用品红色填充轮廓线外的所有区域,然后将不是品红色的所有内容变为黑色,最后将所有人工制造的品红色像素恢复为白色。
我在代码中插入了中间图像,但您可以只获取所有代码片段并将它们按顺序收集在一起,以获得一个可工作的代码块。
#!/usr/bin/env python3

from PIL import Image, ImageDraw
import numpy as np

# Open the image
im = Image.open('octagon.png').convert('RGB')

# Make all background (exterior to octagon) pixels magenta (255,0,255)
ImageDraw.floodfill(im,xy=(0,0),value=(255,0,255),thresh=200)
# DEBUG
im.save('intermediate.png')

enter image description here

# Make everything not magenta black
n  = np.array(im)
n[(n[:, :, 0:3] != [255,0,255]).any(2)] = [0,0,0]

# Revert all artifically filled magenta pixels to white
n[(n[:, :, 0:3] == [255,0,255]).all(2)] = [255,255,255]

Image.fromarray(n).save('result.png')

enter image description here

或者,您可以将整个背景填充为洋红色,然后找到一个白色像素并使用该白色像素作为种子进行泛洪填充黑色。您选择的方法取决于您图像中预期的颜色以及您希望保留抗锯齿等程度。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接