这几天有研究下,怎么在gstreamer中通过opencv来向视频中写入中文;下面就写一下实现过程吧。
原本OpenCV只能向视频画面中写入英文字符,本文结合第三方工具freetype2
安装freetype2与中文环境
sudo add-apt-repository ppa:glasen/freetype2
sudo apt update
sudo apt install freetype2-demos
安装完成后,还需要安装本地中文环境信息
Ubuntu默认安装的中文环境为zh_CN.utf8,然后很多windows的文档还是以GB2312或GBK编码保存的,因此十分有必要在Ubuntu下生成GBK或GB2312的locale否则还是不能写入中文字符:
- 修改/var/lib/locales/supported.d/local文件,在文件中添加以下内容,若无此文件,则先创建文件
zh_CN.GBK GBK
zh_CN.GB2312 GB2312 - 执行 sudo dpkg-reconfigure --force locales ,执行命令后出现图形界面,选择最后的中文字库
确认后在输出的结果中会出现以下信息,耐心等待
zh_CN.GB2312 done
zh_CN.GBK done
zh_CN.UTF8 done
基本上选择这三种就可以了
makefile编写
CC =g++ -std=c++11 -pthread
CFLAGS = -g -Wall
SRCS = CvText.cpp tools.cpp show_chinese.cpp
PROG = test
FREETYPE_INCLUDE = -I /usr/include/freetype2
OPENCV = `pkg-config opencv --cflags --libs`
LIBS = $(OPENCV)
$(PROG):$(SRCS)
$(CC) $(CFLAGS) $(FREETYPE_INCLUDE) -o $(PROG) $(SRCS) $(LIBS) -lfreetype
makefile主要需要链接freetype库,添加freetype2库的头文件目录,以及opencv相关目录
网上找了很多关于用Opencv洗中文字符的问题,结合freetype大都需要CvText.cpp,CvText.h,tools.cpp这三个文件。
CvText.cpp
#include <cwchar>
#include <clocale>
#include <cctype>
#include <utility>
#include "tools.h"
#include "CvText.h"
using namespace Utils;
CvText::CvText(const char *fontName,TextEncoding encoding) {
ASSERT(fontName != nullptr, "字体名称为空");
// 打开字库文件, 创建一个字体
ASSERT(FT_Init_FreeType(&m_library) == 0,
"初始化字库失败,请检查freetype库配置是否正确");
ASSERT(FT_New_Face(m_library, fontName, 0, &m_face) == 0,
"载入字体失败,请检查字体文件是否存在");
//选择字符编码
switch (encoding){
case UTF8:
FT_Select_Charmap(m_face,FT_ENCODING_UNICODE);
m_textEncoding = "zh_CN.utf8";
break;
case GB2312:
FT_Select_Charmap(m_face,FT_ENCODING_GB2312);
m_textEncoding = "zh_CN.gb2312";
break;
default:
ASSERT(false, "不支持的文本编码");
}
// 设置字体输出参数
resetTextStyle();
}
// 释放FreeType资源
CvText::~CvText() {
FT_Done_Face(m_face);
FT_Done_FreeType(m_library);
}
// 设置文本属性
void CvText::setTextStyle(int fontSize, float spaceSize, float separatorSize, float fontDiaphaneity) {
if(fontSize>0)
m_fontSize = fontSize;
if(spaceSize>0)
m_spaceRatio = spaceSize;
if(separatorSize>0)
m_separatorRatio = separatorSize;
if(fontDiaphaneity>0)
m_fontDiaphaneity = fontDiaphaneity;
}
// 恢复默认的文本设置
void CvText::resetTextStyle() {
m_fontSize = 20; // 字体大小
m_spaceRatio = 0.5; // 空白字符大小比例
m_separatorRatio = 0.1; // 间隔大小比例
m_fontDiaphaneity = 1.0; // 透明度
}
int CvText::putText(cv::Mat &frame, std::string text, cv::Point pos, cv::Scalar color) {
return putText(frame,text.c_str(),pos, std::move(color));
}
int CvText::putText(cv::Mat &frame, const