28
votes

I am using opencv 2.1. In my code I have a few images stored as Mat objects initialized like this:

Mat img1 = imread("img/stuff.pgm", CV_LOAD_IMAGE_GRAYSCALE);

I can display them properly using imshow() after my matrix operations are done. Now I want to add some text on the image to describe what has happened. Looking at the documentation it seems like cvPutText() would be the function I need. But when I try something like this:

cvPutText(result, "Differencing the two images.", cvPoint(30,30), &font, GREEN);

I get the following compile error: error: cannot convert ‘cv::Mat’ to ‘CvArr*’ for argument ‘1’ to ‘void cvPutText(CvArr*, const char*, CvPoint, const CvFont*, CvScalar)’

What do I need to do to be able to add some text when displaying this image?

7

7 Answers

67
votes

I was looking at the wrong place. I found the answer in the newer OpenCV documentation for cpp. There is a new function called putText() that accepts cv::Mat objects. So I tried this line and it works:

putText(result, "Differencing the two images.", cvPoint(30,30), 
    FONT_HERSHEY_COMPLEX_SMALL, 0.8, cvScalar(200,200,250), 1, CV_AA);

Hope this helps someone.

27
votes

For C++ basic use in OpenCV 3 or greater:

cv::putText(yourImageMat, 
            "Text to add",
            cv::Point(5,5), // Coordinates (Bottom-left corner of the text string in the image)
            cv::FONT_HERSHEY_COMPLEX_SMALL, // Font
            1.0, // Scale. 2.0 = 2x bigger
            cv::Scalar(255,255,255), // BGR Color
            1, // Line Thickness (Optional)
            cv:: LINE_AA); // Anti-alias (Optional, see version note)
    

See putText() in OpenCV 4 docs, or old 2.x docs .

Note: Versions before OpenCV 2.x use CV_AA instead of LINE_AA

8
votes
putText(result, "Differencing the two images.", cvPoint(30,30), 
    FONT_HERSHEY_COMPLEX_SMALL, 0.8, cvScalar(200,200,250), 1, CV_AA);

In the above line "result" should be a cvArr* or an IplImage*. but from the code provided here, I guess you are passing a cv::Mat object. So, you either need to convert it using cvarrToMat() or pass &result instead of result.

Hope it helps

2
votes

You can also do the following to print text and variables.

    std::ostringstream str;
    str << "Here is some text:" << myVariable;
    cv::putText(image, cv::Point(10,10), str.str(), CV_FONT_HERSHEY_PLAIN, CV_RGB(0,0,250));
2
votes

One nasty detail that I saw into my test code: pay attention into the import stament - it is not displayed into most examples and it needs to be the right import.

My test code used only the putText sample above and I did included the imgproc.h just as I did into some of my oldcode. The code compiled and linked fine however I was facing one weirdy behaviour with the putText (some garbage into my image).

It was a PITA until I figured out that the import was messing up with my social life ...

imageText.cpp

#include "Imaging/imageText.h"
#include "Commons/xLog.h"
#include "opencv2/imgproc.hpp" // << Seems to work right?
using namespace cv;

namespace imaging
{
   inline Mat image2mat( SmartImage image ) NOEXCEPTION
   {
      //TODO: hard coded to work only with CV_8UC3, see the other cases ...
      Mat mat(
         Size( image->WIDTH, image->HEIGHT ),
         CV_8UC3,
         image->buffer,
         Mat::AUTO_STEP
      );

      return mat;
   }

   inline void _writeText_( SmartImage image, const string TEXT )
   {
      Mat mat( image2mat( image ) );

      string text = "Funny text inside the box";
      int fontFace = FONT_HERSHEY_SCRIPT_SIMPLEX;
      double fontScale = 2;
      int thickness = 3;  
      Point textOrg( 10, 130 );
      putText( mat, text, textOrg, fontFace, fontScale, Scalar::all( 255 ), thickness, 8 );
   }

   const bool writeText( SmartImage image, const string text )  NOEXCEPTION
   {
      try
      {
         _writeText_( image, text );
         return true;
      }
      catch( cv::Exception& e )
      {
         LOG_ERROR( "writeText OpenCV ERROR: " << e.what() << "!" );
      }
      catch( ... )
      {
         LOG_ERROR( "writeText ERROR!" );
      }
      return false;
   }
}

Then I just changed the imgproc import above to

#include <opencv2/opencv.hpp> // << It does includes ALL opencv stuff

My 5 cents.

1
votes

If you are using OpenCV 3.x or 4.0, you have to replace CV_AA by LINE_AA. So, the complete call would be:

cv::putText(yourImageMat, 
            "Text to add",
            cv::Point(5,5), // Coordinates
            cv::FONT_HERSHEY_COMPLEX_SMALL, // Font
            1.0, // Scale. 2.0 = 2x bigger
            cv::Scalar(255,255,255), // BGR Color
            1, // Line Thickness (Optional)
            cv::LINE_AA); // Anti-alias (Optional)

This was posted in this forum.

-1
votes

putText(img1, "TextString123", cvPoint(50,200), FONT_HERSHEY_SCRIPT_SIMPLEX, 2.5, cvScalar(255,0,0,255), 3, CV_AA);

You can find more information here: http://docs.opencv.org/2.4.9/modules/core/doc/drawing_functions.html

The main diference between this answer and the answers from above is the value of the 7-th parameter, the thickness level. With thickness==1 this function have not worked for me.