非透明图像部分周围的轮廓

2024-06-06 10:38:17 发布

您现在位置:Python中文网/ 问答频道 /正文

我想用PIL做一个图像轮廓。我的目标是有一些额外的文字行,将在任何背景(包括图像,而不仅仅是纯色)上可见,有点像电影字幕概述

这里有很多答案,网上也有很多文章,但都不适合我。它们归结为:

  1. (通常用于文本)Dofor-循环将文本放置到dx(x+dx, y+dy)位置,range(-radius, radius + 1)中的dx

  2. 模糊图像

  3. 画一个等高线,用粗线画出来

  4. 边缘检测算法

我试过了,但效果不好。这是一个真正需要看起来专业的项目

如果我在Gimp中这样做,我可能会使用“按颜色选择”工具选择图像的透明部分,然后反转选择(选择所有不透明的内容),然后增加选择(在拐角处给我一个很好的圆角形状),然后对其进行一点修饰(获得更平滑的线条),然后用纯色绘制,在我的图像下面的一层

有没有可能在PIL中执行类似的操作,或者任何兼容的操作(基本上,任何可以拍摄NumPy数组“图像”的操作)


Tags: 答案图像文本目标pil电影文章轮廓
1条回答
网友
1楼 · 发布于 2024-06-06 10:38:17

不幸的是,你还没有展示你的任何试验,所以人们可以看到,你的结果是什么样的得到一个印象,什么你认为“不好”。所以,正如您提到的,存储为NumPy数组的图像,OpenCV可能是这里的一个选项

我将结合上述观点:

  • 生成一个与图像尺寸相同的空文本平面,并向0(不可见)添加一个额外的alpha通道集
  • 把文本轮廓:理想的背景色(比如说黄色),大厚度
  • 严重模糊整个文本平面,包括alpha通道。所以,你得到了你的羽毛轮廓
  • 放入实际文本:所需的前景色(比如说黑色),正常厚度
  • 稍微模糊整个文本平面,只是为了平滑生成的文本(漂亮的文字不是OpenCV的强项之一!)
  • 使用平面的alpha通道,通过图像和文本平面的线性组合生成输出

这就是代码:

import cv2
import numpy as np

# Open image, Attention: OpenCV uses BGR ordering by default!
image = cv2.imread('path/your/image.png', cv2.IMREAD_COLOR)

# Set up text properties
loc = (250, 500)
text = 'You were the chosen one!'
c_fg = (0, 255, 255, 255)
c_bg = (0, 0, 0, 255)

# Initialize overlay text plane
overlay = np.zeros((image.shape[0], image.shape[1], 4), np.uint8)

# Put text outline, larger thickness, color of outline (here: black)
cv2.putText(overlay, text, loc, cv2.FONT_HERSHEY_COMPLEX, 1.0, c_bg, 9, cv2.LINE_AA)

# Blur text plane (including alpha channel): Heavy blur
overlay = cv2.GaussianBlur(overlay, (21, 21), sigmaX=10, sigmaY=10)

# Put text, normal thickness, color of overlay (here: yellow)
cv2.putText(overlay, text, loc, cv2.FONT_HERSHEY_COMPLEX, 1.0, c_fg, 2, cv2.LINE_AA)

# Blur text plane (inclusing alpha channel): Very slight blur
overlay = cv2.GaussianBlur(overlay, (3, 3), sigmaX=0.5, sigmaY=0.5)

# Add overlay text plane to image (channel by channel)
output = np.zeros(image.shape, np.uint8)
for i in np.arange(3):
    output[:, :, i] = image[:, :, i] * ((255 - overlay[:, :, 3]) / 255) + overlay[:, :, i] * (overlay[:, :, 3] / 255)

cv2.imshow('output', output)
cv2.waitKey(0)
cv2.destroyAllWindows()

模糊的参数是手动设置的。不同的图像和文本大小需要进一步调整

下面是一个示例输出:

Output 1

即使使用与图像背景相似的前景色,文本仍然可读-至少在我看来:

Output 2

所以,现在的大问题是:这个结果被认为是“坏的”吗

希望有帮助

相关问题 更多 >