1. 简述
我们使用OpenCV时,有时会在图像的某个位置绘制OSD信息,如绘制一些字符串作为指示信息。
本文将简要介绍在图像(cv::Mat)上绘制固定的字符串信息。
2. 使用的API
(1)cv::getTextSize()
CV_EXPORTS_W Size getTextSize(const String& text,
int fontFace,
double fontScale,
int thickness,
CV_OUT int* baseLine);
一般情况下,我们可以直接指定绘制文本的原点信息(默认为左下角坐标),但为了防止出现字符串溢出的问题,还是建议首先通过该API获得在图像上的大小信息。
参数解释:
text:要绘制的文本字符串
fontFace:字体的类型参照HersheyFonts
fontScale:字体放大倍数
thicknes:用于绘制文本的线条的粗细
baseLine:相对于最底部文本的基线y坐标指向
baseLine是文本最低点对应的Y坐标,如下,蓝色线条的Y坐标即是baseLine。
(baseLine指示信息)
(2)cv::putText
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 );
参数解释:
img: 图像;
text: 要绘制的文本字符串;
org: 所绘制文本字符串的原点(默认是左下角,由bottomLeftOrigin控制);
fontFace: 字体的类型参照HersheyFonts;
fontScale: 乘以特定于字体的基本大小的字体比例因子(放大倍数);
color: 字体的颜色;
thickness: 用于绘制文本的线条的粗细;
lineType: 线条的类型参照LineTypes;
bottomLeftOrigin: 如果为true,则图像数据原点位于左下角。否则,它在左上角;
fontFace的取值如下:
FONT_HERSHEY_SIMPLEX = 0 普通大小无衬线字体
FONT_HERSHEY_PLAIN = 1 小号无衬线字体
FONT_HERSHEY_DUPLEX = 2 普通大小无衬线字体
FONT_HERSHEY_COMPLEX = 3 普通大小无衬线字体比 FONT_HERSHEY_DUPLEX 更复杂
FONT_HERSHEY_TRIPLEX = 4 普通大小无衬字体,比 FONT_HERSHEY_COMPLEX 更复杂
FONT_HERSHEY_COMPLEX_SMALL = 5 小号版本的 FONT_HERSHEY_COMPLEX
FONT_HERSHEY_SCRIPT_SIMPLEX = 6 手写字体
FONT_HERSHEY_SCRIPT_COMPLEX = 7 比 FONT_HERSHEY_SCRIPT_SIMPLEX 更复杂的变体
FONT_ITALIC =16 斜体(上面的字体都可以和斜体一起使用)
3. 参考例程
#include <opencv2/opencv.hpp>
#include <iostream>
int main(int argc, char* argv[])
{
/** 读取图像. */
cv::Mat image = cv::imread("demo.jpg"); ///< 替换为你的图片路径
if (image.empty()) {
std::cerr << "Loading image failed!" << std::endl;
return -1;
}
/** 设置OSD文本. */
std::string osdText = "OSD Info";
cv::Point org(50, 50); ///< 文本开始的坐标
int fontFace = cv::FONT_HERSHEY_SIMPLEX;
double fontScale = 1.0;
int thickness = 2;
/** 获取文本尺寸. */
int baseLine;
cv::Size textSize = cv::getTextSize(osdText, fontFace, fontScale, thickness, &baseLine);
/** 确保文本在图像范围内. */
if (org.x + textSize.width > image.cols) {
org.x = image.cols - textSize.width - 10; ///< 留出10个像素的边距
}
if (org.y - baseLine < 0) {
org.y = baseLine + 10; ///< 留出10个像素的边距
}
/** 设置文本颜色. */
cv::Scalar color(0, 0, 255); ///< 红色
/** 绘制OSD文本. */
cv::putText(image, osdText, org, fontFace, fontScale, color, thickness, cv::LINE_AA);
/** 显示和保存图像. */
cv::imwrite("demo_osd.jpg", image); ///< 保存图像
sleep(1);
return 0;
}