如何在OpenCV中将文本放入边框? [英] How to put text into a bounding box in OpenCV?

查看:109
本文介绍了如何在OpenCV中将文本放入边框?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道如何传递putText的位置和字体大小:

I know how to pass putText position and font size:

void TextBox( cv::Mat & img, const std::string & text, const cv::Rect & bbox )
{
    cv::Point position;
    double size;
    int face = CV_FONT_HERSHEY_PLAIN;
    Trick( /*in:*/ text, bbox, face /*out:*/ position, size );
    cv::putText( img, text, position, face, size, cv::Scalar( 100, 255, 100 ) );
}

该怎么做? 我想缩放文本以适合其边框. (字体可能没有被使用.)

How to do the trick? I would like to scale text to fit its bounding box. (Font face might be unused input to that.)

推荐答案

有点棘手,但是您可以使用

It's a bit tricky, but you can play with cv::getTextSize(). There is a sample code in the description of the function but it only renders some text, the tight box (surrounding the text), and the baseline of it.

如果您想以任意图像的ROI呈现文本,则首先需要将其呈现为另一幅图像(适合文本大小),将其调整为所需的ROI,然后将其放在图片,如下所示:

If you'd like to render the text in an arbitrary ROI of an image then you first need to render it into another image (which fits to the text size), resize it to the ROI desired and then put it over the image, such as below:

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;

    // Calculates the width and height of a text string
    cv::Size textSize = cv::getTextSize(text, fontFace, fontScale, thickness, &baseline);

    // Y-coordinate of the baseline relative to the bottom-most text point
    baseline += thickness;

    // Render the text over here (fits to the text size)
    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);

    // Estimating the resolution of bounding image
    cv::Point textOrg((textImg.cols - textSize.width) / 2, (textImg.rows + textSize.height - baseline) / 2);

    // TR and BL points of the bounding box
    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);

    // Resizing according to the ROI
    cv::resize(textImg, textImg, roi.size());

    cv::Mat textImgMask = textImg;
    if (textImgMask.type() == CV_8UC3)
        cv::cvtColor(textImgMask, textImgMask, cv::COLOR_BGR2GRAY);

    // Creating the mask
    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);

    // Put into the original image
    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上呈现任何文本,例如:

As a result of the PutText() function you can render any text over an arbitrary ROI of the image, such as:

希望它会有所帮助并起作用:)

Hope it helps and works :)

更新#1:

请记住,OpenCV中的文本渲染(带有或不带有此技巧)非常昂贵,并且会影响应用程序的运行时.其他库可能胜过OpenCVs渲染系统.

And keep in mind that text rendering (with or without this trick) in OpenCV is very expensive and can affect to the runtime of your applications. Other libraries may outperform the OpenCVs rendering system.

这篇关于如何在OpenCV中将文本放入边框?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆