在数字图像处理中,有的时候便于标注图片信息,需要我们在图片上做一些文字标注.opencv提供了一套比较通用简单的写文字的函数接口:

 void cv::putText(cv::Mat& img, // 待绘制的图像const string& text, // 待绘制的文字cv::Point origin, // 文本框的左下角int fontFace, // 字体 (如cv::FONT_HERSHEY_PLAIN)double fontScale, // 尺寸因子,值越大文字越大cv::Scalar color, // 线条的颜色(RGB)int thickness = 1, // 线条宽度int lineType = 8, // 线型(4邻域或8邻域,默认8邻域)bool bottomLeftOrigin = false // true='origin at lower left');

根据上述接口我们可以很简单地在图片上进行一些文字的标注.

其中 该函数接受的字体包含以下几种:

其中 sans-serif表示无衬线字体 serif表示有衬线字体  handwritingstyle表示手写字体

putText函数虽然好用但是也有其致命缺点:

1.只能支持上述几种字体

2.只能支持英文

为了解决显示中文的问题的.我们可以用如下的方式.

1.创建CvxText.cpp

#include <wchar.h>
#include <assert.h>
#include <locale.h>
#include <ctype.h>
#include <cmath>
#include <stdio.h>
#include "../hpp/CvxText.h"// 打开字库
CvxText::CvxText()
{}
void CvxText::LoadType(const char* freeType){assert(freeType != NULL);// 打开字库文件, 创建一个字体if(FT_Init_FreeType(&m_library)) ;//throw;if(FT_New_Face(m_library, freeType, 0, &m_face));// 设置字体输出参数restoreFont();// 设置C语言的字符集环境setlocale(LC_ALL, "");}// 释放FreeType资源
CvxText::~CvxText()
{// FT_Done_Face(m_face);FT_Done_FreeType(m_library);
}// 设置字体参数:
//
// font         - 字体类型, 目前不支持
// size         - 字体大小/空白比例/间隔比例/旋转角度
// underline   - 下画线
// diaphaneity   - 透明度
void CvxText::getFont(int* type, cv::Scalar* size, bool* underline, float* diaphaneity)
{if (type) *type = m_fontType;if (size) *size = m_fontSize;if (underline) *underline = m_fontUnderline;if (diaphaneity) *diaphaneity = m_fontDiaphaneity;
}void CvxText::setFont(int* type, cv::Scalar* size, bool* underline, float* diaphaneity)
{// 参数合法性检查if (type) {if(*type >= 0) m_fontType = *type;}if (size) {m_fontSize.val[0] = std::fabs(size->val[0]);m_fontSize.val[1] = std::fabs(size->val[1]);m_fontSize.val[2] = std::fabs(size->val[2]);m_fontSize.val[3] = std::fabs(size->val[3]);//旋转比例}if (underline) {m_fontUnderline   = *underline;}if (diaphaneity) {m_fontDiaphaneity = *diaphaneity;}FT_Matrix matrix;//旋转矩阵FT_Vector     pen;//平移向量pen.x = 10 * 64;int target_height=1080;pen.y = ( target_height - 40 ) * 6;float angle=m_fontSize.val[3];matrix.xx = (FT_Fixed)( cos( angle ) * 0x10000L );matrix.xy = (FT_Fixed)(-sin( angle ) * 0x10000L );matrix.yx = (FT_Fixed)( sin( angle ) * 0x10000L );matrix.yy = (FT_Fixed)( cos( angle ) * 0x10000L );FT_Set_Pixel_Sizes(m_face, (int)m_fontSize.val[0], 0);FT_Set_Transform(m_face,&matrix,&pen);
}// 恢复原始的字体设置
void CvxText::restoreFont()
{m_fontType = 0;            // 字体类型(不支持)m_fontSize.val[0] = 20;      // 字体大小m_fontSize.val[1] = 0.5;   // 空白字符大小比例m_fontSize.val[2] = 0.1;   // 间隔大小比例m_fontSize.val[3] = 0;      // 旋转角度(不支持)m_fontUnderline   = true;   // 下画线(不支持)m_fontDiaphaneity = 1.0;   // 色彩比例(可产生透明效果)// 设置字符大小FT_Set_Pixel_Sizes(m_face, (int)m_fontSize.val[0], 2);//  FT_Set_Transform(m_face,)
}// 输出函数(颜色默认为白色)
int CvxText::putText(cv::Mat& img, char* text, cv::Point pos)
{return putText(img, text, pos, CV_RGB(255, 255, 255));
}int CvxText::putText(cv::Mat& img, const wchar_t* text, cv::Point pos)
{return putText(img, text, pos, CV_RGB(255,255,255));
}int CvxText::putText(cv::Mat& img, const char* text, cv::Point pos, cv::Scalar color)
{if (img.data == nullptr) return -1;if (text == nullptr) return -1;int i;for (i = 0; text[i] != '\0'; ++i) {wchar_t wc = text[i];// 解析双字节符号if(!isascii(wc)) mbtowc(&wc, &text[i++], 2);// 输出当前的字符putWChar(img, wc, pos, color);}return i;
}int CvxText::putText(cv::Mat& img, const wchar_t* text, cv::Point pos, cv::Scalar color)
{if (img.data == nullptr) return -1;if (text == nullptr) return -1;int i;for(i = 0; text[i] != '\0'; ++i) {// 输出当前的字符putWChar(img, text[i], pos, color);}return i;
}// 输出当前字符, 更新m_pos位置
void CvxText::putWChar(cv::Mat& img, wchar_t wc, cv::Point& pos, cv::Scalar color)
{// 根据unicode生成字体的二值位图FT_UInt glyph_index = FT_Get_Char_Index(m_face, wc);FT_Load_Glyph(m_face, glyph_index, FT_LOAD_DEFAULT);FT_Render_Glyph(m_face->glyph, FT_RENDER_MODE_MONO);FT_GlyphSlot slot = m_face->glyph;// 行列数int rows = slot->bitmap.rows;int cols = slot->bitmap.width;for (int i = 0; i < rows; ++i) {for(int j = 0; j < cols; ++j) {int off  = i * slot->bitmap.pitch + j/8;if (slot->bitmap.buffer[off] & (0xC0 >> (j%8))) {int r = pos.y - (rows-1-i);int c = pos.x + j;if(r >= 0 && r < img.rows && c >= 0 && c < img.cols) {cv::Vec3b pixel = img.at<cv::Vec3b>(cv::Point(c, r));cv::Scalar scalar = cv::Scalar(pixel.val[0], pixel.val[1], pixel.val[2]);// 进行色彩融合float p = m_fontDiaphaneity;for (int k = 0; k < 4; ++k) {scalar.val[k] = scalar.val[k]*(1-p) + color.val[k]*p;}img.at<cv::Vec3b>(cv::Point(c, r))[0] = (unsigned char)(scalar.val[0]);img.at<cv::Vec3b>(cv::Point(c, r))[1] = (unsigned char)(scalar.val[1]);img.at<cv::Vec3b>(cv::Point(c, r))[2] = (unsigned char)(scalar.val[2]);}}}}// 修改下一个字的输出位置double space = m_fontSize.val[0]*m_fontSize.val[1];double sep   = m_fontSize.val[0]*m_fontSize.val[2];pos.x += (int)((cols? cols: space) + sep);
}

其中 CvxText.h

#ifndef OPENCV_CVX_TEXT_HPP_
#define OPENCV_CVX_TEXT_HPP_// 支持OpenCV中文汉字输入
#include <ft2build.h>
#include FT_FREETYPE_H
#include <opencv2/opencv.hpp>class CvxText {
public:/*** 装载字库文件*/CvxText();virtual ~CvxText();void LoadType(const char* freeType);/*** 获取字体.目前有些参数尚不支持.** \param font        字体类型, 目前不支持* \param size        字体大小/空白比例/间隔比例/旋转角度* \param underline   下画线* \param diaphaneity 透明度** \sa setFont, restoreFont*/void getFont(int* type, cv::Scalar* size=nullptr, bool* underline=nullptr, float* diaphaneity=nullptr);/*** 设置字体.目前有些参数尚不支持.** \param font        字体类型, 目前不支持* \param size        字体大小/空白比例/间隔比例/旋转角度* \param underline   下画线* \param diaphaneity 透明度** \sa getFont, restoreFont*/void setFont(int* type, cv::Scalar* size=nullptr, bool* underline=nullptr, float* diaphaneity=nullptr);/*** 恢复原始的字体设置.** \sa getFont, setFont*/void restoreFont();/*** 输出汉字(颜色默认为黑色).遇到不能输出的字符将停止.** \param img  输出的影象* \param text 文本内容* \param pos  文本位置** \return 返回成功输出的字符长度,失败返回-1.*/int putText(cv::Mat& img, char* text, cv::Point pos);/*** 输出汉字(颜色默认为黑色).遇到不能输出的字符将停止.** \param img  输出的影象* \param text 文本内容* \param pos  文本位置** \return 返回成功输出的字符长度,失败返回-1.*/int putText(cv::Mat& img, const wchar_t* text, cv::Point pos);/*** 输出汉字.遇到不能输出的字符将停止.** \param img   输出的影象* \param text  文本内容* \param pos   文本位置* \param color 文本颜色** \return 返回成功输出的字符长度,失败返回-1.*/int putText(cv::Mat& img, const char* text, cv::Point pos, cv::Scalar color);/*** 输出汉字.遇到不能输出的字符将停止.** \param img   输出的影象* \param text  文本内容* \param pos   文本位置* \param color 文本颜色** \return 返回成功输出的字符长度,失败返回-1.*/int putText(cv::Mat& img, const wchar_t* text, cv::Point pos, cv::Scalar color);private:// 禁止copyCvxText& operator=(const CvxText&);// 输出当前字符, 更新m_pos位置void putWChar(cv::Mat& img, wchar_t wc, cv::Point& pos, cv::Scalar color);FT_Library   m_library;   // 字库FT_Face      m_face;      // 字体// 默认的字体输出参数int         m_fontType;cv::Scalar   m_fontSize;bool      m_fontUnderline;float      m_fontDiaphaneity;
};#endif // OPENCV_CVX_TEXT_HPP_

我们可以通过下面的方式调用文件

CvxText text; //指定字体
Scalar size1{1000, 0.1, 0.2, 0 };
text.setFont(nullptr, &size1, nullptr, 0);
wchar_t* w_str=NULL;
string ss="我是谁";
ToWchar((ss.c_str()),w_str);
Mat Input;
Scalar Texcolor{0,255,0,0};
text.putText(Input,w_str,Point(0,0),TexColor);
cv::imshow("ADS",Input);

主要为了做点小笔记.写的很粗糙,请大家指正!

图像处理中,在图片上写字,包括中文与英文!相关推荐

  1. 图像处理中,SIFT,FAST,MSER,STAR等特征提取算法的比较与分析(利用openCV实现)

    图像处理中,SIFT,FAST,MSER,STAR等特征提取算法的比较与分析(利用openCV实现) 本文实验为自己原创,转载请注明出处. 本人为研究生,最近的研究方向是物体识别.所以就将常用的几种特 ...

  2. java制作海报一:java使用Graphics2D 在图片上写字,文字换行算法详解

    文章目录 前言 一.直接上代码 1. 写字方法 2. 换行算法 二. 叙述换行算法 前言 代码都上传到GitHub了,这里仅仅是贴出来主要部分,GitHub传送门:https://github.com ...

  3. . net core在图片上写字

    . net core在图片上写字 using (System.Drawing.Image bitmap = System.Drawing.Image.FromFile("../../../图 ...

  4. python怎么在图片上写字的软件_python 实现PIL模块在图片画线写字

    图片上画线条 import sys from PIL import Image,ImageDraw im = Image.open("th.png") draw = ImageDr ...

  5. 在一个图片上写字并保存

    在一个图片上写字然后在保存出来可以先将图片导入,然后利用setpen在图上写字然后导出图片 下面提供源代码 void Widget::SaveImage() {QImage image = QPixm ...

  6. 怎么用html把字写到图片上,用HTML代码在图片上写字

    一.以图片作为背景.在图片上写字,主要是在 里用到了(Spacer)空白. type="horizontal" align=#> 水平空白 align=center(居中), ...

  7. 在自行下载的背景图片上写字

    在背景图片上写字 1 下载并修改图片 2 代码 3 其它例子 3.1 不用空格分行 3.2 竖行 主要是参考了 写对联的代码,发散思维,联想到换成自己随便从网页上下载一张图片作为背景,在上面写字是不是 ...

  8. php如何在图片上写字,php在图片上写字并生成图片

    http://www.doczj.com/doc/db4fbed65022aaea988f0f0c.html涮涮网 用php在图片上写字(文字或数字),并生成新图片 下面是自己封装的一个函数: //调 ...

  9. php写字本写,php在图片上写字的类

    php在图片上写字的类 class showChinaText { var $text = 'php网站程序开发'; var $font = 'fonts/simsun.ttc'; //如果没有要自己 ...

最新文章

  1. java jdbc 表存在_使用JDBC查询是否存在某表或视图,按月动态生成表
  2. ThreadPool原理介绍
  3. Red Hat Enterprise Linux 5---system-config-*管理工具
  4. linux系统开机报错,linux开机报错故障
  5. 开发日记-20190914 关键词 汇编语言王爽版 第七章第八章
  6. chromium 源码下载地址
  7. Linux-重装系统之静态ip配置
  8. paip.哈米架构CAO.txt
  9. BEC translation exercise 4
  10. Citrix XenDesktop如何发布LocalApp
  11. dockerfile 多端口映射 expose
  12. Linux CentOS 7安装Tomcat7的完整步骤。
  13. JXLS (excel报表生成/导出工具)的配置与使用
  14. 【最优化基础】惩罚和障碍函数
  15. 如何给 PDF 文档批量添加页眉页脚?如何给 PDF 文档批量添加页码?
  16. 如何让百度收录你的网站
  17. 微信分享之分享图片/分享图标不能显示
  18. 基于Android的股票交易软件,基于android的股票交易系统的融资融券交易子系统的设计与实现-软件工程专业论文.docx...
  19. 谷歌网页自动翻译,赞一个
  20. 浏览器是怎么对html5的离线资源进行加载的呢

热门文章

  1. 最全zabbix安装部署
  2. Android 12 Watchdog(4) Trace生成过程
  3. L1-002打印沙漏C语言,沙漏
  4. 知识分享 | Oracle的官方ACE是个啥 and如何搞定一个ACE!
  5. 数据分析师就业前景怎么样?零基础能成为数据分析师吗?
  6. 换网站服务器需要备案吗,换服务器要重新备案吗?
  7. Python——解一元二次方程
  8. axure中备注线_axure 备注怎么写
  9. 联想g400从u盘启动计算机,联想g400笔记本设置U盘启动的图文步骤
  10. 我国成功研制出巨型计算机,1989年11月17日 我国首台小巨型电子计算机研制成功...