这有点棘手,但你可以使用
cv::getTextSize()
进行操作。函数说明中有一些示例代码,但它只呈现一些文本、紧密的框(围绕文本)和其基线。
如果你想在图像的任意ROI中呈现文本,则首先需要将其呈现到另一个图像中(适合于文本大小),将其调整为所需的ROI大小,然后将其放置在图像上方,如下所示:
void PutText(cv::Mat& img, const std::string& text, const cv::Rect& roi, const cv::Scalar& color, int fontFace, double fontScale, int thickness = 1, int lineType = 8)
{
CV_Assert(!img.empty() && (img.type() == CV_8UC3 || img.type() == CV_8UC1));
CV_Assert(roi.area() > 0);
CV_Assert(!text.empty());
int baseline = 0;
cv::Size textSize = cv::getTextSize(text, fontFace, fontScale, thickness, &baseline);
baseline += thickness;
cv::Mat textImg(textSize.height + baseline, textSize.width, img.type());
if (color == cv::Scalar::all(0)) textImg = cv::Scalar::all(255);
else textImg = cv::Scalar::all(0);
cv::Point textOrg((textImg.cols - textSize.width) / 2, (textImg.rows + textSize.height - baseline) / 2);
cv::Point tr(textOrg.x, textOrg.y + baseline);
cv::Point bl(textOrg.x + textSize.width, textOrg.y - textSize.height);
cv::putText(textImg, text, textOrg, fontFace, fontScale, color, thickness);
cv::resize(textImg, textImg, roi.size());
cv::Mat textImgMask = textImg;
if (textImgMask.type() == CV_8UC3)
cv::cvtColor(textImgMask, textImgMask, cv::COLOR_BGR2GRAY);
cv::equalizeHist(textImgMask, textImgMask);
if (color == cv::Scalar::all(0)) cv::threshold(textImgMask, textImgMask, 1, 255, cv::THRESH_BINARY_INV);
else cv::threshold(textImgMask, textImgMask, 254, 255, cv::THRESH_BINARY);
cv::Mat destRoi = img(roi);
textImg.copyTo(destRoi, textImgMask);
}
然后像这样调用:
cv::Mat image = cv::imread("C:/opencv_logo.png");
cv::Rect roi(5, 5, image.cols - 5, image.rows - 5);
cv::Scalar color(255, 0, 0);
int fontFace = cv::FONT_HERSHEY_SCRIPT_SIMPLEX;
double fontScale = 2.5;
int thickness = 2;
PutText(image, "OpenCV", roi, color, fontFace, fontScale, thickness);
由于
PutText()
函数的作用,您可以在图像的任意ROI上渲染任何文本,例如:
希望这对您有所帮助并能够正常工作 :)
更新 #1:
请记住,在OpenCV中进行文本渲染(无论是否使用此技巧)非常昂贵,可能会影响到您的应用程序运行时间。其他库可能会优于OpenCV的渲染系统。