OpenCV putText不能直接显示中文是因为默认字体不包含汉字字形;需用cv::freetype::createFreeType2加载中文字体文件(如simhei.ttf)并调用其putText方法,注意字体大小单位为像素且line_type设为-1启用抗锯齿。

OpenCV putText 为什么不能直接显示中文
因为 putText 底层依赖 FreeType 或 Hershey 字体,而默认的 cv::FONT_HERSHEY_SIMPLEX 等字体是 ASCII-only 的矢量字形,不包含汉字字形数据。直接传入中文字符串(如 "你好")会显示为方块、问号或空白——这不是编码问题(UTF-8 没错),是字体资源缺失。
用 cv::putText + 自定义字体文件(推荐方案)
核心思路:绕过 OpenCV 内置字体,用 FreeType 渲染文字到图像内存,再贴回 OpenCV Mat。OpenCV 4.8+ 原生支持 cv::freetype::createFreeType2,无需额外编译 FreeType。
- 确保 OpenCV 编译时启用了
freetype支持(CMake 输出中含FreeType: YES;若为预编译包,需确认版本 ≥ 4.8.0) - 准备一个支持中文的 TrueType 字体文件(如
"simhei.ttf"、"NotoSansCJKsc-Regular.otf"),路径不能含中文或空格 - 代码中先创建
cv::freetype::FreeType2对象,再调用putText方法(注意:不是cv::putText!)
cv::Ptr<:freetype::freetype2> ft = cv::freetype::createFreeType2();
ft->loadFontData("simhei.ttf", 0); // 第二个参数是字体索引,通常为 0
ft->putText(img, "测试中文", cv::Point(50, 100), 32, cv::Scalar(0, 255, 0), -1, cv::LINE_AA, true);
</:freetype::freetype2>
⚠️ 注意:putText 的字体大小单位是像素(非 pt),且 line_type 设为 -1 才启用抗锯齿;bottomLeftOrigin=false(默认)表示 y 向下增长。
Windows 下用 GDI 绘制中文(兼容旧版 OpenCV)
若 OpenCV 版本 Mat。本质是“借系统 API 渲染”,不依赖 OpenCV 字体能力。
- 需包含
和,链接Gdiplus.lib - 创建
Gdiplus::Graphics对象,用DrawString绘制 UTF-16 字符串(需MultiByteToWideChar(CP_UTF8, ...)转换) - 将 GDI+ 位图
LockBits数据 memcpy 到cv::Mat,注意 BGR/RGB 顺序和步长对齐
该方法稳定但平台限定,且易因 DPI 缩放、Alpha 通道处理不当导致边缘发虚或颜色偏移。
常见错误与性能提醒
加载字体文件失败时,loadFontData 不报异常,但后续 putText 会静默失效——务必检查返回值或用 cv::error 日志确认路径可读;频繁创建 FreeType2 实例(如每帧都 new)会导致明显性能下降,应复用对象。
多线程环境下,FreeType2 实例非线程安全,需加锁或为每个线程分配独立实例。
字体文件体积大(常 > 10MB),不要在循环内反复 loadFontData;如果只显示少量固定中文(如“OK”“错误”),建议预先渲染成小图再用 cv::addWeighted 贴图,更快更可控。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











