OSD(文字叠加)
1.1. OSD 概述
在某些应用场景(例如 IP 摄像头)中,需要在图像上添加水印,尤其需要绘制【日语等多字节字符的水印】。但是,OpenCV 本身默认不支持绘制这些亚洲语言字符。为应对这种情况,EASY EAI API 封装并提供了专门用于在图像上绘制文字的字体引擎。

1.1. OSD 概述 图 10
1.2. 快速入门
1.2.1 开发环境准备
在 PC 上的 Ubuntu 系统中执行 run 脚本,进入 EASY-EAI 编译环境。具体如下。
cd ~/develop_environment./run.sh 22041.2.2 下载源码并编译示例
在 EASY-EAI 编译环境中,创建用于管理源码仓库的目录。
cd /optmkdir EASY-EAI-Toolkitcd EASY-EAI-Toolkithttps://dl.dragonwake.com/download/rv1126b/embedded/EASY-EAI-Toolkit-1126B/Demos.zip 从上述链接下载 Demos.zip 压缩文件,将其上传到虚拟机的 /opt/EASY-EAI-Toolkit 目录并解压。 进入对应示例目录,执行编译操作。具体命令如下。
cd EASY-EAI-Toolkit-1126B/Demos/common-font_engine/./build.sh cpres💡 注意:由于依赖库放置在开发板上,因此交叉编译过程中请务必保持 /mnt 挂载。

1.2.2 下载源码并编译示例 图 12
1.2.3 运行示例
通过串口调试或 SSH 调试进入开发板后台,并切换到示例所在位置。如下所示。
cd /userdata/Demo/common-font_engine
1.2.3 运行示例 图 13
示例运行命令如下。
./test-font_engine1.2.4 运行结果
运行结果如下。
运行测试程序后,会生成名为“result.jpg”的图像。

1.2.4 运行结果 图 14
返回【编译窗口】,使用 eog 命令直接打开图像。
eog /mnt/userdata/Demo/common-font_engine/result.jpg &eog /mnt/userdata/Demo/common-font_engine/testPic.png &
1.2.4 运行结果 图 15
由此可以确认文字已叠加到原始图像上。 如果 EASY-EAI 编译环境提示找不到 eog 命令,请通过以下操作进行安装。
sudo apt-get updatesudo apt-get install eog也可以将图像从开发板复制到 PC。
cp /mnt/userdata/Demo/common-font_engine/result.jpg ./Release关于 API 的详细说明以及 API 调用(本示例的源码),请参考以下说明。
1.3. 字符串操作 API 说明
1.3.1 包含/引用方法
EASY EAI API 库位于本仓库的 easyeai-api 目录中。为便于用户在本地项目中直接调用 EASY EAI API 库,下面列出了项目中需要链接的库、头文件等内容。
| 说明 | CMake 中的写法 | Makefile 中的写法 |
|---|---|---|
| api.cmake | ${common_root}/font_engine/api.cmake | 无 |
| 头文件目录 | ${FONT_ENGINE_INCLUDE_DIRS} | -I ../../easyeai-api/common/font_engine |
| 源文件目录 | ${FONT_ENGINE_SOURCE_DIRS} | ../../easyeai-api/common/font_engine |
| 库文件目录 | 无 | 无 |
| 库链接参数 | ${FONT_ENGINE_LIBS} | 无 |
API 源码路径为 EASY-EAI-Toolkit-1126B/easyeai-api/common/font_engine/。用户可以通过源码查看接口实现,也可以直接修改源码。
1.3.2 创建全局字体对象
函数原型如下。
int32_t global_font_create(const char \*fontLib, const char \*codec);具体说明如下。
| 函数名:global_font_create() | 详细说明 |
|---|---|
| 头文件 | easyeai-api/common/font_engine/font_engine.h |
| 输入参数 | fontLib:要加载的字体库文件(例如:”./simhei.ttf”) codec:写入图像的文字编码格式(例如:utf-8 或 gbk 等) |
| 返回值 | 创建成功:0 创建失败:-1 |
| 注意事项 | 如果当前进程中已经创建了全局字体对象,再次调用时一定会 返回 -1。 |
1.3.3 设置全局字体对象的字符编码
函数原型如下。
int32_t global_font_set_textCodec(const char \*codec);具体说明如下。
| 函数名:global_font_set_textCodec() | 详细说明 |
|---|---|
| 头文件 | easyeai-api/common/font_engine/font_engine.h |
| 输入参数 | codec:写入图像的文字编码格式(例如:utf-8 或 gbk 等) |
| 返回值 | 设置成功:0 设置失败:-1 |
| 注意事项 | 需要预先创建全局字体对象。 |
1.3.4 设置全局字体对象的字体大小
函数原型如下。
int32_t global_font_set_fontSize(uint32_t fontSize);具体说明如下。
| 函数名:global_font_set_fontSize() | 详细说明 |
|---|---|
| 头文件 | easyeai-api/common/font_engine/font_engine.h |
| 输入参数 | fontSize:要设置的目标字体大小 |
| 返回值 | 设置成功:0 设置失败:-1 |
| 注意事项 | 需要预先创建全局字体对象。 |
1.3.5 向图像写入指定文字
函数原型如下。
int32_t putText(uint8_t \*imgData, uint32_t imgWidth, uint32_t imgHeight, const char \*text, uint32_t posX, uint32_t posY, FontColor color);具体说明如下。
| 函数名:putText() | 详细说明 |
|---|---|
| 头文件 | easyeai-api/common/font_engine/font_engine.h |
| 输入参数 | imgData:图像数据的首地址。数据格式为 BGR888。 imgWidth:图像分辨率尺寸(宽度)。 imgHeight:图像分辨率尺寸(高度)。 text:要写入的字符串。 posX:要写入字符串左上角的 X 坐标(相对于图像的位置)。图像坐标原点为左上角。 posY:要写入字符串左上角的 Y 坐标(相对于图像的位置)。图像坐标原点为左上角。 color:字体颜色值。结构体将在后文说明。 |
| 返回值 | 写入成功:0 写入失败:-1 |
| 注意事项 | 需要预先创建全局字体对象。 |
FontColor 结构体:
typedef struct {uint8_t Alpha; // 透明度(Alpha)通道的颜色值uint8_t Red; // 红色通道的颜色值uint8_t Green; // 绿色通道的颜色值uint8_t Bule; // 蓝色通道的颜色值(原文如此)} FontColor;1.3.6 销毁全局字体对象
函数原型如下。
int32_t global_font_destory();具体说明如下。
| 函数名:global_font_destory() | 详细说明 |
|---|---|
| 头文件 | easyeai-api/common/font_engine/font_engine.h |
| 输入参数 | 无 |
| 返回值 | 销毁成功:0 销毁失败:-1 |
| 注意事项 | 需要预先创建全局字体对象。 |
1.4. API 测试用例
示例代码路径为 EASY-EAI-Toolkit-1126B/Demos/common-font_engine/test-font_engine.cpp。
以下是各 API 的实际使用示例。
int main(void){// 初始化字体透明度和颜色FontColor color = {200, 135, 189, 67}; // {A, R, G, B};// 创建全局字体global_font_create("./simhei.ttf", CODE_UTF8);// 读取背景图像cv::Mat img = cv::imread("./testPic.png");// 写入文字global_font_set_fontSize(80);putText(img.data, img.cols, img.rows, "欢迎使用", 210, 940,color);global_font_set_fontSize(40);putText(img.data, img.cols, img.rows, "欢迎使用", 290, 1020,color);// 保存写入文字后的图像cv::imwrite("./res.jpg", img);// 销毁全局字体global_font_destory();return 0;}