前言
OpenCV自身不支持中文字符渲染,导致在图像上绘制中文文本时出现乱码。可通过PIL的ImageDraw配合中文字体文件绘制文本,再将PIL图像转换为OpenCV格式,确保在任何环境下都能正确显示中文,完美解决中文乱码问题。
一、解决思路
- 使用 PIL.ImageFont.truetype(“simhei.ttf”, size) 加载字体。
- 用PIL的 ImageDraw.Draw().text() 绘制中文。
- 通过 np.array(pil_image) 和 cv2.cvtColor 将PIL图像转换为OpenCV可用的BGR格式。
二、获取中文字体文件
simhei.ttf字库文件是系统最原始的黑体字体,兼容性非常好,不管是win7还是win10、win11里面都可以使用的。常用于需要显示中文的场景,特别是在matplotlib等Python绘图库中显示中文时需要配置支持中文的字体文件。
三、代码实现
代码如下:
import os
import cv2
import numpy as np
from PIL import Image, ImageDraw, ImageFont
font = None
font_size = 40 # 统一字体大小
font_path = "./simhei.ttf"
try:
font = ImageFont.truetype(font_path, font_size)
print(f"成功加载字体:{font_path}")
except Exception as e:
print(f"加载字体 {font_path} 失败: {e}")
# 确保font是ImageFont对象
if not isinstance(font, (ImageFont.FreeTypeFont, ImageFont.ImageFont)):
raise TypeError(f"font必须是ImageFont对象,当前类型:{type(font)}")
img = cv2.imread("test.jpg")
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
pil_img = Image.fromarray(img_rgb)
draw = ImageDraw.Draw(pil_img)
img_width, img_height = pil_img.size
color=(255, 255, 0)
text = "OpenCV 中文文本绘制功能!!!"
# 使用self.font(ImageFont对象)而非其他字符串变量
text_bbox = draw.textbbox((0, 0), text, font=font)
text_width = text_bbox[2] - text_bbox[0]
text_height = text_bbox[3] - text_bbox[1]
x = (img_width - text_width) // 2
y = (img_height - text_height) // 2
# 转换BGR颜色为RGB(OpenCV用BGR,PIL用RGB)
rgb_color = (color[2], color[1], color[0])
draw.text((x, y), text, font=font, fill=rgb_color)
# 转换回OpenCV的BGR格式
img_bgr = cv2.cvtColor(np.array(pil_img), cv2.COLOR_RGB2BGR)
cv2.imwrite("res.jpg", img_bgr)
确保simhei.ttf字库文件存在,在linux操作系统下同样适用,绘制效果如下:
总结
这种"PIL渲染 + OpenCV处理"的组合方案,不仅解决了中文乱码问题,还带来了更好的文本渲染效果和更大的灵活性。无论是图像标注、数据可视化还是视频处理,都能获得完美的中文显示效果。