Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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 (in Ubuntu)?

like image 590
user1592546 Avatar asked Aug 11 '12 19:08

user1592546


2 Answers

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.

like image 65
isarandi Avatar answered Sep 18 '22 13:09

isarandi


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.

like image 36
Nikko Avatar answered Sep 19 '22 13:09

Nikko