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

Python 非透明图像部分周围的轮廓,python,image-processing,python-imaging-library,Python,Image Processing,Python Imaging Library,我想用PIL做一个图像轮廓。我的目标是让文本有一些额外的线条,可以在任何背景上看到(包括图像,而不仅仅是纯色),有点像电影字幕 这里有很多答案,网上也有很多文章,但都不适合我。它们归结为: (通常用于文本)Dofor-循环将文本放置到(x+dx,y+dy)fordx,dx位于范围(-radius,radius+1)中 模糊图像 做一个等高线,用粗线画出来 边缘检测算法 我尝试了这些,但是结果的质量很差。这是一个真正需要看起来专业的项目 如果我在Gimp中执行此操作,我可能会使用“按颜色选择”工具

我想用PIL做一个图像轮廓。我的目标是让文本有一些额外的线条,可以在任何背景上看到(包括图像,而不仅仅是纯色),有点像电影字幕

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

  • (通常用于文本)Do
    for
    -循环将文本放置到
    (x+dx,y+dy)
    for
    dx
    dx
    位于
    范围(-radius,radius+1)

  • 模糊图像

  • 做一个等高线,用粗线画出来

  • 边缘检测算法

  • 我尝试了这些,但是结果的质量很差。这是一个真正需要看起来专业的项目

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


    P>是否有可能在PIL中做类似的事情,或者任何兼容的东西(基本上,任何能使数字阵列“图像”的东西)?

    < P>不幸的是,你还没有显示任何你的试验,所以你可以看到,你的结果看起来是什么样的印象,你认为什么是“坏的”。所以,正如您提到的存储为NumPy数组的图像,这里可能是一个选项

    我将遵循上述想法的组合:

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

    导入cv2
    将numpy作为np导入
    #打开图像,注意:OpenCV默认使用BGR排序!
    image=cv2.imread('path/your/image.png',cv2.imread\u COLOR)
    #设置文本属性
    loc=(250500)
    text=“你是被选中的人!”
    c_fg=(0,255,255,255)
    c_bg=(0,0,0,255)
    #初始化覆盖文本平面
    叠加=np.0((image.shape[0],image.shape[1],4),np.uint8)
    #放置文字轮廓,厚度较大,轮廓颜色(此处:黑色)
    cv2.putText(叠加、文本、loc、cv2.FONT\u HERSHEY\u复合体、1.0、c\u bg、9、cv2.LINE\u AA)
    #模糊文本平面(包括alpha通道):严重模糊
    叠加=cv2.GaussianBlur(叠加,(21,21),sigmaX=10,sigmaY=10)
    #放置文字、正常厚度、叠加颜色(此处:黄色)
    cv2.putText(叠加、文本、loc、cv2.FONT\U HERSHEY\U COMPLEX、1.0、c\U fg、2、cv2.LINE\U AA)
    #模糊文本平面(包括alpha通道):非常轻微的模糊
    叠加=cv2.GaussianBlur(叠加,(3,3),sigmaX=0.5,sigmaY=0.5)
    #将覆盖文本平面添加到图像(逐通道)
    输出=np.0(image.shape,np.uint8)
    对于np.arange(3)中的i:
    输出[:,:,i]=图像[:,:,i]*((255-覆盖[:,:,3])/255)+覆盖[:,:,i]*(覆盖[:,:,3]/255)
    cv2.imshow(“输出”,输出)
    cv2.等待键(0)
    cv2.destroyAllWindows()
    
    模糊的参数是手动设置的。不同的图像和文本大小需要进一步调整

    以下是一个示例输出:

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

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


    希望有帮助

    谢谢
    imshow
    在Fedora上对我不起作用,所以我用
    imwrite
    替换了它。我使用了一个随机的PNG从我的磁盘和其余的代码是你的,不变。结果是:正如您所看到的,模糊的背景有一个锐利的像素化边缘,而前景颜色不存在。知道为什么吗?它是Python 2下的OpenCV 3.2.0.7(不是我的选择,我现在无法移动到Python 3)。将OpenCV升级到4.1.1.26没有帮助。@VedranŠego一般性评论:请描述您在问题中使用的环境以防止此类问题。如果我知道您使用Python2,我可能不会回答。在阅读了Python2/3的不同之处之后,有一个想法:Python2中的整数除法似乎总是返回整数。因此,可以尝试显式强制转换来浮动循环内的计算。否则,恐怕我不能再帮你了。好样的!谢谢,很抱歉遗漏了。除了除法之外,Python 2/3的差异不应该真正影响到这样的事情,我完全忘记了除法。它现在可以工作了,我将尝试使它适应我的项目。