2015-09-24 57 views
2

我知道如何通過putText位置和字體大小:如何將文本放入OpenCV中的邊界框?

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

如何做的伎倆? 我想縮放文本以適合其邊界框。 (字體臉可能是未使用的輸入)

+0

爲什麼首先使用OpenCV呢? –

+0

我有一個視頻,需要OSD .. – renonsz

+0

..一個視頻及其處理基礎架構已經在OpenCV! – renonsz

回答

4

這有點棘手,但你可以玩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中是非常昂貴,可能會影響應用程序的運行時間。其他庫可能優於OpenCV渲染系統。

+0

你能推薦任何文本渲染庫嗎? – Micka

+0

我從來沒有用過,但我的一些隊友讚美[開羅圖書館](http://cairographics.org/manual/cairo-text.html),或OpenGL ofcourse。 – Kornel