如何为图像添加边框,根据图像边缘颜色动态选择颜色?

时间:2021-04-19 17:15:14

标签: python-3.x image python-imaging-library border

我需要为一组裁剪得很紧的徽标中的每个图像添加边框。边框颜色应该与边缘最常用的颜色相匹配,或者,如果不同的边缘颜色太多,则应该选择某种边缘颜色的平均值。

这是一个例子。在这种情况下,我希望添加的边框与图像“背景”的颜色相同(在外行意义上使用该术语)。沿边缘的大部分像素都是这种颜色,只有其他两种颜色,因此决策算法将能够为添加的边框选择那种相当沉闷的棕褐色(不会对徽标背后的组织说任何不好的地方) , 提个醒)。

COTAP.org logo

Pillow 是否有任何功能可以简化此任务?

我找到了显示如何use Pillow to add borders和如何determine the average color of an entire image的答案。但是我找不到任何仅查看图像边缘并找到主要颜色的代码,然后可以在边框添加例程中使用该颜色。以防万一有人已经完成了这项工作,请指点我。 (“边缘”是指沿图像顶部/底部/左侧/右侧边缘的像素带,其高度或宽度将指定为图像总大小的百分比。)

没有向我指出解决我的整个问题的要点,是否有 Pillow 例程可以查看边缘和/或计算像素范围内的颜色并将它们放入数组或其他什么?

我看到 here OpenCV 可以添加一个边框,沿所有四个边缘复制每个最外层像素的颜色,但这看起来很时髦——我想要一个纯色边框。而且我更愿意坚持使用 Pillow——除非另一个图书馆可以或多或少地一步完成整个边缘颜色分析和添加边框的过程,在这种情况下,请指出。

1 个答案:

答案 0 :(得分:1)

用一些固定颜色覆盖图像的中心部分,这很可能不会出现在边缘内。为此,可以使用具有特定 alpha 值的颜色。然后,有一个函数 getcolors,它完全符合您的要求。对结果列表进行排序,并获得计数最高的颜色。 (这通常是我们用来覆盖中心部分的颜色。因此请检查它,并在需要时获取第二个条目。)最后,使用 ImageOps.expand 添加实际边框。

这就是完整的代码:

from PIL import Image, ImageDraw, ImageOps

# Open image, enforce RGB with alpha channel
img = Image.open('path/to/your/image.png').convert('RGBA')
w, h = img.size

# Set up edge margin to look for dominant color
me = 3

# Set up border margin to be added in dominant color
mb = 30

# On an image copy, set non edge pixels to (0, 0, 0, 0)
img_copy = img.copy()
draw = ImageDraw.Draw(img_copy)
draw.rectangle((me, me, w - (me + 1), h - (me + 1)), (0, 0, 0, 0))

# Count colors, first entry most likely is color used to overwrite pixels
n_colors = sorted(img_copy.getcolors(2 * me * (w + h) + 1), reverse=True)
dom_color = n_colors[0][1] if n_colors[0][1] != (0, 0, 0, 0) else n_colors[1][1]

# Add border
img = ImageOps.expand(img, mb, dom_color).convert('RGB')

# Save image
img.save('with_border.png')

这就是您的示例的结果:

Output

而且,这是另一个图像的一些输出:

Other output

是否有几种主色是要混合还是平均由您决定。为此,您需要在几个方面适当地检查 n_colors。这是相当多的工作,这里省略了。

----------------------------------------
System information
----------------------------------------
Platform:      Windows-10-10.0.16299-SP0
Python:        3.9.1
PyCharm:       2021.1
Pillow:        8.2.0
----------------------------------------