OpenCV3 字体文字(putText()和 getTextSize())

 

 

 

文字绘制函数
函数名称描述
cv::putText()在图像中绘制指定文字
cv::getTextSize()获取一个文字的宽度和高度

1  cv::putText()函数

/** @brief Draws a text string.

The function putText renders the specified text string in the image. Symbols that cannot be rendered
using the specified font are replaced by question marks. See getTextSize for a text rendering code
example.

@param img Image.
@param text Text string to be drawn.
@param org Bottom-left corner of the text string in the image.
@param fontFace Font type, see cv::HersheyFonts.
@param fontScale Font scale factor that is multiplied by the font-specific base size.
@param color Text color.
@param thickness Thickness of the lines used to draw a text.
@param lineType Line type. See the line for details.
@param bottomLeftOrigin When true, the image data origin is at the bottom-left corner. Otherwise,
it is at the top-left corner.
 */
CV_EXPORTS_W void putText(
                         InputOutputArray img, 
                         const String& text, 
                         Point org,
                         int fontFace, 
                         double fontScale, 
                         Scalar color,
                         int thickness = 1, 
                         int lineType = LINE_8,
                         bool bottomLeftOrigin = false 
                        );

 

 这个函数是OpenCV的一个主要文字绘制方法,它可以简单地在图像上绘制一些文字,由text指定地文字将在以左上角为原点地文字框中以color指定地颜色绘制出来,除非bottomLeftOrigin标志设置为真,这种情况以左下角为原点,使用的字体由fontFace参数决定

可以使用的字体
标识符描述
 FONT_HERSHEY_SIMPLEX                   = 0!< normal size sans-serif font  普通大小无衬线字体
FONT_HERSHEY_PLAIN                         = 1!< small size sans-serif font     小号无衬线字体
FONT_HERSHEY_DUPLEX                     = 2!< normal size sans-serif font (more complex than FONT_HERSHEY_SIMPLEX)      普通大小无衬线字体
FONT_HERSHEY_COMPLEX                 = 3!< normal size serif font   普通大小无衬线字体比 FONT_HERSHEY_DUPLEX 更复杂
FONT_HERSHEY_TRIPLEX                    = 4 

!< normal size serif font (more complex than FONT_HERSHEY_COMPLEX  

普通大小无衬字体,比 FONT_HERSHEY_COMPLEX 更复杂

  FONT_HERSHEY_COMPLEX_SMALL = 5

!< smaller version of FONT_HERSHEY_COMPLEX

小号版本的  FONT_HERSHEY_COMPLEX

FONT_HERSHEY_SCRIPT_SIMPLEX   = 6!< hand-writing style font     手写字体
FONT_HERSHEY_SCRIPT_COMPLEX = 7

!< more complex variant of FONT_HERSHEY_SCRIPT_SIMPLEX

比 FONT_HERSHEY_SCRIPT_SIMPLEX  更复杂的变体

FONT_ITALIC                                          = 16!< flag for italic font  

 

表中列出来的任何一个字体都可以和CV::FONT_ITALIC 组合使用(通过或操作)来得到斜体。每种字体都有一个“自然”大小,当fontScale不是1.0时,在文字绘制之前字体大小将由这个数缩放。

#include<iostream>
#include<opencv2\core.hpp>
#include<opencv2\highgui.hpp>
#include<opencv2\imgproc.hpp>
const char *path1 = "D:/Coder/vs/1_OpenCV/3096.jpg";

int main()
{
	cv::Mat img = cv::imread(path1,cv::IMREAD_UNCHANGED);
	const std::string str1 = "Hello World!";
	cv::putText(img, str1, cv::Point2i(0, 0), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(0, 255, 230), 1, 8, false);
	cv::putText(img, str1, cv::Point2i(0, 30), cv::FONT_HERSHEY_PLAIN, 1, cv::Scalar(0, 255, 230), 1, 8, false);
	cv::putText(img, str1, cv::Point2i(0, 60), cv::FONT_HERSHEY_DUPLEX, 1, cv::Scalar(0, 255, 230), 1, 8, false);
	cv::putText(img, str1, cv::Point2i(0, 90), cv::FONT_HERSHEY_COMPLEX, 1, cv::Scalar(0, 255, 230), 1, 8, false);
	cv::putText(img, str1, cv::Point2i(0, 120), cv::FONT_HERSHEY_TRIPLEX, 1, cv::Scalar(0, 255, 230), 1, 8, false);
	cv::putText(img, str1, cv::Point2i(0, 150), cv::FONT_HERSHEY_COMPLEX_SMALL, 1, cv::Scalar(0, 255, 230), 1, 8, false);
	cv::putText(img, str1, cv::Point2i(0, 180), cv::FONT_HERSHEY_SCRIPT_SIMPLEX, 1, cv::Scalar(0, 255, 230), 1, 8, false);
	cv::putText(img, str1, cv::Point2i(0, 210), cv::FONT_HERSHEY_SCRIPT_COMPLEX, 1, cv::Scalar(0, 255, 230), 1, 8, false);
	cv::putText(img, str1, cv::Point2i(0, 250), cv::FONT_ITALIC|cv::FONT_HERSHEY_PLAIN, 1, cv::Scalar(0, 255, 230), 1, 8, false);

	cv::imshow("1", img);
	cv::waitKey(0);
	return 0;
}

 

衬线指的是字母结构笔画之外的装饰性笔画。有衬线的字体叫衬线体(serif);没有衬线的字体,则叫做无衬线体(sans-serif)。

衬线字体(serif)

特征:在字的笔画开始、结束的地方有额外的装饰,而且笔画的粗细会有所不同

用途:serif字体容易识别,它强调了每个字母笔画的开始和结束,因此易读性比较高。在整文阅读的情况下,适合使用serif字体进行排版,易于换行阅读的识别性,避免发生行间的阅读错误。

中文字体中的宋体就是一种最标准的serif字体,衬线的特征非常明显。字形结构也和手写的楷书一致。因此宋体一直被做为最适合的正文字体之一。

 

无衬线字体(sans-serif)

特征:sans serif是无衬线字体,没有这些额外的装饰,而且笔画的粗细差不多。该类字体通常是机械的和统一线条的,它们往往拥有相同的曲率,笔直的线条,锐利的转角。

用途:无衬线字体醒目,适合用于标题、DM、海报等,需要醒目但不需要长时间阅读的地方。但现在市场上很多app正文都开始采用无衬线字体,因为无衬线字体更简约、清新,比较有艺术感。

无衬线字体与汉字字体中的黑体相对应。为了起到醒目的作用,笔画比较粗,不适合长时间阅读,不适合用作正文字体。但是现代的 Macintosh、iOS、Android、Windows Vista 以上 等系统默认使用的无衬线字体基本上都是基于细黑体演化而来,不再像传统的无衬线字体那么重,因此用作正文字体时易读性也很高。

在传统的正文印刷中,普遍认为衬线体能带来更佳的可读性。尤其是在大段落的文章中,衬线增加了阅读时对字母的视觉参照。而无衬线体往往被用在标题、较短的文字段落或者一些通俗读物中。相比严肃正经的衬线体,无衬线体给人一种休闲轻松的感觉。随着现代生活和流行趋势的变化,如今的人们越来越喜欢用无衬线体,因为他们看上去“更干净”。

 2  cv::getTextSize() 函数

/** @brief Calculates the width and height of a text string.

The function getTextSize calculates and returns the size of a box that contains the specified text.
That is, the following code renders some text, the tight box surrounding it, and the baseline: :
@code
    String text = "Funny text inside the box";
    int fontFace = FONT_HERSHEY_SCRIPT_SIMPLEX;
    double fontScale = 2;
    int thickness = 3;

    Mat img(600, 800, CV_8UC3, Scalar::all(0));

    int baseline=0;
    Size textSize = getTextSize(text, fontFace,
                                fontScale, thickness, &baseline);
    baseline += thickness;

    // center the text
    Point textOrg((img.cols - textSize.width)/2,
                  (img.rows + textSize.height)/2);

    // draw the box
    rectangle(img, textOrg + Point(0, baseline),
              textOrg + Point(textSize.width, -textSize.height),
              Scalar(0,0,255));
    // ... and the baseline first
    line(img, textOrg + Point(0, thickness),
         textOrg + Point(textSize.width, thickness),
         Scalar(0, 0, 255));

    // then put the text itself
    putText(img, text, textOrg, fontFace, fontScale,
            Scalar::all(255), thickness, 8);
@endcode

@param text Input text string.
@param fontFace Font to use, see cv::HersheyFonts.
@param fontScale Font scale factor that is multiplied by the font-specific base size.
@param thickness Thickness of lines used to render the text. See putText for details.
@param[out] baseLine y-coordinate of the baseline relative to the bottom-most text
point.
@return The size of a box that contains the specified text.

@see cv::putText
 */
CV_EXPORTS_W Size getTextSize(const String& text, int fontFace,
                            double fontScale, int thickness,
                            CV_OUT int* baseLine);

参数意义

. const string& text: 输入的文本文字 
. int fontFace: 文字字体类型 
. double fontScale: 字体缩放系数 
. int thickness: 字体笔画线宽 
. CV_OUT int* baseLine: 文字最底部y坐标

cv::getTextSize()函数回答了如果把文字绘制出来将有多大的问题,而不用实际将文字绘制到图上,cv::getTextSize()唯一的新的参数就是baseLine,这实际上是一个输出参数,baseLine是和文字最低点相关的文字基线的y坐标值。

#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include<opencv2\imgproc.hpp>

using namespace std;
using namespace cv;

int main()
{
	string text = "Funny text inside the box";
	//int fontFace = FONT_HERSHEY_SCRIPT_SIMPLEX;     //手写风格字体
	int fontFace = FONT_HERSHEY_SCRIPT_COMPLEX;
	double fontScale =2;       //字体缩放比
	int thickness = 3;

	Mat img(600, 800, CV_8UC3, Scalar::all(0));

	int baseline = 0;

	Size textSize = getTextSize(text, fontFace, fontScale, thickness, &baseline);
	baseline += thickness;
	//center the text
	Point textOrg((img.cols - textSize.width) / 2, (img.rows - textSize.height) / 2);
	//draw the box
	rectangle(img, textOrg + Point(0, baseline), textOrg + Point(textSize.width, -textSize.height), Scalar(0, 0, 255));
	line(img, textOrg + Point(0, thickness), textOrg + Point(textSize.width, thickness), Scalar(0, 0, 255));
	putText(img, text, textOrg, fontFace, fontScale, Scalar::all(255), thickness, 8);
	imshow("text", img);
	waitKey(0);
	return 0;
}

 

  • 13
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

&小鹏鹏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值