c++ - 如何将文本放入 OpenCV 中的边界框?

标签 c++ opencv

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

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 ) );
}

如何做到这一点? 我想缩放文本以适合其边界框。 (字体可能是未使用的输入。)

最佳答案

这有点棘手,但你可以玩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;

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

enter image description here enter image description here

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


更新 #1:

请记住,在 OpenCV 中进行文本渲染(有或没有这个技巧)是非常昂贵的,并且会影响应用程序的运行时间。其他库的性能可能优于 OpenCVs 渲染系统。

关于c++ - 如何将文本放入 OpenCV 中的边界框?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32755439/

相关文章:

c# - 为什么 float.min 在 C++ 和 C# 之间不同?

c++ - 在 C++ 中终止函数的最简单方法

opencv - 找到轮廓属性

c++ - Gstreamer 的 OpenCV 3.0.0 错误

visual-studio - Visual Studio 上的 OpenCV 设置问题

c# - 保证CPU响应?

c++ - 测试 C++ 代码的字节序无关性

python - Tiff 中值滤波器导出为单帧 OpenCV Python

opencv - 立体视觉算法

C++/Linux - 是否可以将特定于上下文的数据注入(inject)到创建的每个线程中