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)
- 之所以做openCV转PIL再转回openCV,是由于在做CV任务的时候,openCV有丰富的算子和图像处理,只是在输出中文字符出现不适配
- 若在实际任务中,只需要输出如“你好世界”,就只有4个字符,可以通过FontCreator自定义一个字体文件,只把“你好世界”4个字形放进去就可以实现功能,因为如果每次都要加载全部的字符,可能在一些实际任务上由于文件IO的花销,影响实际的性能