OpenCV putText():绘制文字(附带实例)
OpenCV 中除了提供绘制各种图形的函数外,还提供了一个特殊的绘制函数,用于在图像上绘制文字。这个函数是 putText(),它是命名空间 cv2 中的函数,其声明如下:
需要注意的是,putText() 函数的 text 参数只能接收特定字符,也就是说并不是所有的字符串都能顺利绘制。例如,当 text 参数内容中包含中文时,运行结果中的中文会被“?”等字符替换,原因就是 putText() 函数无法识别中文。如果想在图像中绘制中文文字,就需要借助其他模块或第三方库(PIL 库和 freetype 库)。
putText() 函数可以简单地在图像上绘制一些文字,由 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() 函数用于获取一个文字的宽度和高度,函数声明如下:
函数返回包含指定文本框的大小。
【实例】绘制文字。
运行工程,结果如下图所示:
putText(img, text, org, fontFace, fontScale, color[, thickness[, lineType[, bottomLeftOrigin]]]) -> None各个参数的含义如下:
- img 表示待绘制的图像;
- text 表示待绘制的文字;
- org 表示文本框的左下角;
- fontFace 表示字体;
- fontScale 表示尺寸因子,值越大文字越大;
- color 表示字体的颜色(RGB);
- thickness 表示线条宽度;
- lineType 表示线型(4 邻域或 8 邻域,默认是 8 邻域);
- bottomLeftOrigin 如果为 True,那么图像数据原点位于左下角,否则位于左上角。
需要注意的是,putText() 函数的 text 参数只能接收特定字符,也就是说并不是所有的字符串都能顺利绘制。例如,当 text 参数内容中包含中文时,运行结果中的中文会被“?”等字符替换,原因就是 putText() 函数无法识别中文。如果想在图像中绘制中文文字,就需要借助其他模块或第三方库(PIL 库和 freetype 库)。
putText() 函数可以简单地在图像上绘制一些文字,由 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() 函数用于获取一个文字的宽度和高度,函数声明如下:
getTextSize(text, fontFace, fontScale, thickness) -> retval, baseLine各个参数的含义如下:
- text 表示输入的文本文字;
- fontFace 表示文字字体类型;
- fontScale 表示字体缩放系数;
- thickness 表示字体笔画线宽;
- baseLine 是一个返回值,表示文字最底部的 y 坐标。
函数返回包含指定文本框的大小。
【实例】绘制文字。
import cv2 import numpy as np img = np.zeros([512, 512, 3], dtype=np.uint8) for i in range(512): for j in range(512): img[i, j, :] = [i % 256, j % 256, (i + j) % 256] info = 'Hello World' font_face = cv2.FONT_HERSHEY_COMPLEX font_scale = 2 thickness = 2 text_size = cv2.getTextSize(info, font_face, font_scale, thickness) print(text_size) p_center = (int(512 / 2 - text_size[0][0] / 2), int(512 / 2 - text_size[0][1] / 2)) cv2.putText(img, info, p_center, font_face, font_scale, (255,255,255), thickness) cv2.imshow('res', img) cv2.waitKey(0) cv2.destroyAllWindows()首先通过两个 for 循环有规律地改变了像素值,这样可以模拟实现色彩渐变的效果。然后通过函数 getTextSize() 得到要画文字的大小,这样可以计算出显示文字的位置。最后通过文本绘制函数 putText() 画出字符串“Hello World”。
运行工程,结果如下图所示:
