Python+OpenCV实战:5分钟搞定图片中文标注(附完整代码与字体资源)

张开发
2026/4/19 14:43:40 15 分钟阅读

分享文章

Python+OpenCV实战:5分钟搞定图片中文标注(附完整代码与字体资源)
PythonOpenCV实战5分钟搞定图片中文标注附完整代码与字体资源在数据可视化、自媒体配图或机器学习数据标注场景中我们经常需要在图片上添加中文说明。但OpenCV原生putText函数仅支持ASCII字符集直接输出中文会导致乱码。本文将介绍三种跨平台解决方案并提供开箱即用的代码模板与字体资源。1. 为什么OpenCV无法直接输出中文OpenCV的文本渲染引擎基于FreeType库的简化版本默认未集成中文字体支持。当尝试以下代码时import cv2 img cv2.imread(background.jpg) cv2.putText(img, 你好OpenCV, (50,50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,0,255), 2) cv2.imshow(result, img) cv2.waitKey(0)输出结果将显示为乱码方块。这是因为编码冲突OpenCV内部使用Latin-1编码处理文本字体限制内置字体不含中文字形渲染管线差异底层图形接口未适配复杂文本布局提示该问题与操作系统无关在Windows/Linux/macOS上表现一致2. 解决方案一PIL桥接法推荐Python Imaging LibraryPIL具有完整的Unicode支持结合OpenCV的图像格式转换可实现中文渲染import cv2 import numpy as np from PIL import Image, ImageDraw, ImageFont def cv2_add_chinese_text(img, text, position, font_size, color): # 转换OpenCV格式到PIL格式 pil_img Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) draw ImageDraw.Draw(pil_img) # 加载中文字体需提前准备.ttf文件 font ImageFont.truetype(simhei.ttf, font_size, encodingutf-8) # 绘制中文文本 draw.text(position, text, fillcolor, fontfont) # 转换回OpenCV格式 return cv2.cvtColor(np.array(pil_img), cv2.COLOR_RGB2BGR) # 使用示例 img cv2.imread(input.jpg) result cv2_add_chinese_text(img, 人工智能实验室, (100,100), 40, (0,0,255)) cv2.imwrite(output.jpg, result)关键参数说明参数类型说明font_sizeint字号像素单位positiontuple(x,y)文本左上角坐标colortuple(B,G,R)颜色值字体资源推荐思源黑体Source Han Sans方正系列字体文泉驿微米黑3. 解决方案二FreeType原生集成对于需要高性能渲染的场景可编译支持FreeType的OpenCV版本import cv2 # 需安装opencv-contrib-python的完整版 ft2 cv2.freetype.createFreeType2() ft2.loadFontData(fontFileNamesimsun.ttc, id0) img np.zeros((300,500,3), dtypenp.uint8) ft2.putText(img, 深度学习, (50,150), 30, (255,0,0), -1, cv2.LINE_AA, True)性能对比渲染100次耗时方法平均耗时(ms)PIL桥接420FreeType2104. 解决方案三C扩展封装对于企业级应用可通过C扩展实现更高效的文本渲染// text_renderer.h #include opencv2/opencv.hpp class ChineseTextRenderer { public: void loadFont(const std::string fontPath); void render(cv::Mat image, const std::string text, cv::Point pos, int fontSize, cv::Scalar color); private: cv::Ptrcv::freetype::FreeType2 ft2_; };编译后通过Python绑定调用import cv2 import text_renderer renderer text_renderer.ChineseTextRenderer() renderer.loadFont(msyh.ttf) img cv2.imread(input.png) renderer.render(img, 模型训练进度, (100,50), 30, (0,255,0))5. 实战批量图片标注工具结合上述技术我们可以构建完整的图片批处理工具import os from concurrent.futures import ThreadPoolExecutor def batch_process_images(input_dir, output_dir, text_dict): font ImageFont.truetype(simhei.ttf, 24) def process_file(filename): img cv2.imread(os.path.join(input_dir, filename)) pil_img Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) draw ImageDraw.Draw(pil_img) # 从字典获取对应文本 text text_dict.get(filename, 默认标注) draw.text((10,10), text, fill(255,0,0), fontfont) output_path os.path.join(output_dir, filename) cv2.imwrite(output_path, cv2.cvtColor(np.array(pil_img), cv2.COLOR_RGB2BGR)) with ThreadPoolExecutor() as executor: executor.map(process_file, os.listdir(input_dir))功能扩展建议添加文本自动换行功能支持多行文本对齐集成文本阴影效果实现动态水印生成6. 常见问题排查Q1字体文件加载失败确保字体路径正确检查文件权限Linux/Mac需chmod ar验证字体格式file simhei.ttfQ2文字显示为方框确认字体包含目标字符集检查文本编码是否为UTF-8测试基础示例排除环境问题Q3性能瓶颈预加载字体对象避免重复初始化对大尺寸图片采用分块处理考虑使用C加速核心逻辑在实际项目中推荐优先采用PIL桥接方案它兼具开发效率与跨平台稳定性。对于需要处理大量图片的自动化场景可将字体预加载与多线程结合实现每秒处理100图片的吞吐量。

更多文章