OpenCV: How to use other font than HERSHEY with cvPutText (like Arial)

后端 未结 2 670
别跟我提以往
别跟我提以往 2020-12-14 20:37

I want to write to an image a formatted text. OpenCV offers only a limited set of default fonts. Is it possible to use others? For example to read them from the *.ttf file (

相关标签:
2条回答
  • 2020-12-14 20:48

    If you cannot or don't want to use the Qt bindings, here is a way to do it with CAIRO:

    #include <opencv2/opencv.hpp>
    #include <cairo/cairo.h>
    #include <string>
    
    void putTextCairo(
            cv::Mat &targetImage,
            std::string const& text,
            cv::Point2d centerPoint,
            std::string const& fontFace,
            double fontSize,
            cv::Scalar textColor,
            bool fontItalic,
            bool fontBold)
    {
        // Create Cairo
        cairo_surface_t* surface =
                cairo_image_surface_create(
                    CAIRO_FORMAT_ARGB32,
                    targetImage.cols,
                    targetImage.rows);
    
        cairo_t* cairo = cairo_create(surface);
    
        // Wrap Cairo with a Mat
        cv::Mat cairoTarget(
                    cairo_image_surface_get_height(surface),
                    cairo_image_surface_get_width(surface),
                    CV_8UC4,
                    cairo_image_surface_get_data(surface),
                    cairo_image_surface_get_stride(surface));
    
        // Put image onto Cairo
        cv::cvtColor(targetImage, cairoTarget, cv::COLOR_BGR2BGRA);
    
        // Set font and write text
        cairo_select_font_face(
                    cairo,
                    fontFace.c_str(),
                    fontItalic ? CAIRO_FONT_SLANT_ITALIC : CAIRO_FONT_SLANT_NORMAL,
                    fontBold ? CAIRO_FONT_WEIGHT_BOLD : CAIRO_FONT_WEIGHT_NORMAL);
    
        cairo_set_font_size(cairo, fontSize);
        cairo_set_source_rgb(cairo, textColor[2], textColor[1], textColor[0]);
    
        cairo_text_extents_t extents;
        cairo_text_extents(cairo, text.c_str(), &extents);
    
        cairo_move_to(
                    cairo,
                    centerPoint.x - extents.width/2 - extents.x_bearing,
                    centerPoint.y - extents.height/2- extents.y_bearing);
        cairo_show_text(cairo, text.c_str());
    
        // Copy the data to the output image
        cv::cvtColor(cairoTarget, targetImage, cv::COLOR_BGRA2BGR);
    
        cairo_destroy(cairo);
        cairo_surface_destroy(surface);
    }
    

    Example call:

    putTextCairo(mat, "Hello World", cv::Point2d(50,50), "arial", 15, cv::Scalar(0,0,255), false, false);
    

    It assumes that the target image is BGR.

    It puts the text's center to the given point. If you want some different positioning, you have to modify the cairo_move_to call.

    0 讨论(0)
  • 2020-12-14 20:58

    It's possible to use other fonts but you need to link the Qt library to OpenCV and use the cvAddText function with a cvFontQt

    http://docs.opencv.org/modules/highgui/doc/qt_new_functions.html#addtext

    http://docs.opencv.org/modules/highgui/doc/qt_new_functions.html#fontqt

    There are other solutions you might try, with more or less the same performance as OpenCV. For instance, you can use CAIRO to write fonts into the image.

    0 讨论(0)
提交回复
热议问题