【Python】openCV.putText无法输出中文,使用PIL间接转换

openCV

使用openCV输出字符串,需要传入一个fontFace参数,openCV提供了很多关于英文数字的字体库,点进源码查看

...
FONT_HERSHEY_COMPLEX = 3

FONT_HERSHEY_COMPLEX_SMALL = 5

FONT_HERSHEY_DUPLEX = 2
FONT_HERSHEY_PLAIN = 1

FONT_HERSHEY_SCRIPT_COMPLEX = 7
FONT_HERSHEY_SCRIPT_SIMPLEX = 6

FONT_HERSHEY_SIMPLEX = 0
FONT_HERSHEY_TRIPLEX = 4
...

可以尝试一下openCV,到底能不能输出中文字符

import cv2


image = cv2.imread(r'...')
putText(image, '你好,世界!', (20, 20), cv2.FONT_HERSHEY_SCRIPT_SIMPLEX, 0.8, (255, 255, 255), thickness=1
cv2.imshow('t', image)
cv2.waitKey(0)

为什么显示英文数字正常,而中文字符错误,其原因是由于该字体文件中不存在中文的字形,所谓字形如下图所示:
在这里插入图片描述
上图就是字体文件就可以支持中文输出,理论上说只要openCV能够调用自定义的字体文件,就可以输出中文,但是再在源码中发现openCV的字体文件定义都是整型数,无法知道如何调用自定义的字体文件(或许在c++源码能够实现吧)

PIL

由于PIL(pillow)库在图片的操作可以显示中文,故在openCV转PIL再转回openCV

import numpy as np
import PIL
import cv2


def putChText(image, text, pos, color, size, font='微软雅黑.ttf'):
    if isinstance(image, np.ndarray):
        image = np.fromarray(cv2.cvtColor(image, 4))
        mode = 'cv2'
    else:
    	mode = 'pil'
    font = PIL.ImageFont.truetype(font, size, encoding="utf-8")
    canvas = PIL.ImageDraw.Draw(image)
    canvas.text(pos, text, color, font=font)
    if mode == 'cv2':
        return cv2.cvtColor(np.asarray(image), 4)
    else:
        return image

除了自定义坐标,还可以实现居中显示,关键的函数是PIL.ImageFont.truetype,可以拿到字体的相关信息

font = PIL.ImageFont.truetype(font, size, encoding="utf-8")
w, h = font.getsize(text)
x, y = round((x - (w / 2))), round((y - (h / 2)))

可以尝试一下,查看一下效果

image = cv2.imread(r'...')
image = putChText(image, '你好,世界!', (20, 20), (255, 255, 255), 50)
cv2.imshow('t', image)
cv2.waitKey(0)

  1. 之所以做openCV转PIL再转回openCV,是由于在做CV任务的时候,openCV有丰富的算子和图像处理,只是在输出中文字符出现不适配
  2. 若在实际任务中,只需要输出如“你好世界”,就只有4个字符,可以通过FontCreator自定义一个字体文件,只把“你好世界”4个字形放进去就可以实现功能,因为如果每次都要加载全部的字符,可能在一些实际任务上由于文件IO的花销,影响实际的性能
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值