首页 > 编程笔记 > C++笔记 阅读:2

OpenCV putText()函数的用法(附带实例)

OpenCV 中除了提供绘制各种图形的函数外,还提供了一个特殊的绘制函数,用于在图像上绘制文字。这个函数是 putText(),它是命名空间 cv 中的函数,其声明如下:
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 bottomLeftToOrigin = false // true='origin at lower left'
);
这个函数可以简单地在图像上绘制一些文字,由 text 指定的文字将在以左上角为原点的文字框中以 color 指定的颜色绘制出来,除非 bottomLeftOrigin 标志设置为真,这种情况以左下角为原点,使用的字体由 fontFace 参数决定。

常用的字体宏是 FONT_HERSHEY_SIMPLEX(普通大小无衬线字体)和 FONT_HERSHEY_PLAIN(小号无衬线字体)。任何一个字体都可以和 CV::FONT_ITALIC 组合使用(通过“或”操作,或操作符号是|)来得到斜体。每种字体都有一个“自然”大小,当 fontScale 不是 1.0 时,在文字绘制之前字体大小将由这个数来缩放。

这里解释一下衬线。衬线指的是字母结构笔画之外的装饰性笔画。有衬线的字体叫衬线体(Serif),没有衬线的字体叫无衬线体(Sans-Serif)。

衬线体的特征是在字的笔画开始、结束的地方有额外的装饰,而且笔画的粗细会有所不同。衬线体很容易识别,它强调了每个字母笔画的开始和结束,因此易读性比较高。中文字体中的宋体就是一种标准的衬线体。

无衬线体(Sans-Serif Font)没有额外的装饰,而且笔画的粗细差不多。这类字体通常是机械的和统一线条的,它们往往拥有相同的曲率、笔直的线条和锐利的转角。无衬线体与汉字字体中的黑体相对应。

另外,在实际绘制文字之前,还可以使用 cv::getTextSize() 接口先获取待绘制文本框的大小,以方便放置文本框。getTextSize() 函数可以获取字符串的宽度和高度,该函数声明如下:
Size cv::getTextSize(const string& text,cv::Point origin,int fontFace,double fontScale,int thickness,int* baseLine);
各个参数的含义如下:
函数返回值中包含文本框的大小。

【实例】绘制文字。
1) 新建一个控制台工程,工程名是 test。

2) 打开 main.cpp,输入如下代码:
#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;
}
在上述代码中,我们通过 getTextSize 函数获取包含字体的文本框的大小,并画线显示在矩形中。最后通过文本绘制函数 putText 画出一段字符串“Funny text inside the box”。

3) 保存工程并运行,结果如下图所示:

相关文章