【问题标题】:How to overlay text on image when working with cv::Mat type使用 cv::Mat 类型时如何在图像上覆盖文本
【发布时间】:2011-07-07 17:35:11
【问题描述】:

我正在使用 opencv 2.1。在我的代码中,我将一些图像存储为 Mat 对象,初始化如下:

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

矩阵运算完成后,我可以使用 imshow() 正确显示它们。现在我想在图像上添加一些文字来描述发生了什么。查看文档似乎cvPutText() 将是我需要的功能。但是当我尝试这样的事情时:

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

我收到以下编译错误: error: cannot convert ‘cv::Mat’ to ‘CvArr*’ for argument ‘1’ to ‘void cvPutText(CvArr*, const char*, CvPoint, const CvFont*, CvScalar)’

我需要做什么才能在显示此图像时添加一些文本?

【问题讨论】:

    标签: c++ opencv computer-vision


    【解决方案1】:

    用于 OpenCV 3 或更高版本中的 C++ 基本用途:

    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)
        
    

    请参阅 OpenCV 4 文档中的 putText(),或旧的 2.x docs

    注意:OpenCV 2.x 之前的版本使用CV_AA 而不是LINE_AA

    【讨论】:

    • 对于未来的读者:请注意,在cv::putText 中,通过cv::Point 提及的坐标对应于文本的左下角图片中的字符串
    【解决方案2】:

    如果您使用的是 OpenCV 3.x 或 4.0,则必须将 CV_AA 替换为 LINE_AA。因此,完整的调用将是:

    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 forum

    【讨论】:

      【解决方案3】:

      我在测试代码中看到的一个令人讨厌的细节:注意导入语句 - 大多数示例中都没有显示它,它需要是正确的导入。

      我的测试代码只使用了上面的 putText 示例,并且我确实包含了 imgproc.h,就像我在一些旧代码中所做的一样。代码编译和链接很好,但是我遇到了 putText 的一种奇怪行为(我的图像中有一些垃圾)。

      这是一个 PITA,直到我发现导入扰乱了我的社交生活......

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

      那我只是把上面的imgproc导入改成

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

      我的 5 美分。

      【讨论】:

        【解决方案4】:

        您还可以执行以下操作来打印文本和变量。

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

        【讨论】:

        • 这似乎不起作用。为什么你的标量中有is?为什么&lt;&lt; "Here..." 在括号外?我无法编译此示例。
        • 我知道运算符是什么。你的答案没有按原样编译,你没有解释发生了什么。我希望你能编辑你对实际编译的 MWE 的答案。
        • 我更新了答案。感谢您的指正。 &lt;&lt; 重载需要另一个默认情况下不属于 openCV 分发的库。
        【解决方案5】:

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

        您可以在这里找到更多信息:http://docs.opencv.org/2.4.9/modules/core/doc/drawing_functions.html

        此答案与上述答案的主要区别在于第 7 个参数的值,即厚度级别。厚度==1 这个函数对我不起作用。

        【讨论】:

        • 这个问题已经得到了令人满意的回答,所以你真的需要一些解释来证明你的答案有什么不同/更好。从您的回答中也不清楚matImg1 是什么(它没有出现在问题中)。
        • 这使用了openCV(vs c++)的C接口,真的很老了。
        【解决方案6】:

        我看错地方了。我在较新的OpenCV documentation for cpp 中找到了答案。有一个名为 putText() 的新函数接受 cv::Mat 对象。所以我尝试了这条线并且它有效:

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

        希望这对某人有所帮助。

        【讨论】:

        • 不幸的是,这仅适用于 ASCII 字符......如果有人有更好的解决方案,我会接受!
        • @Eliyahu-Shmuel 它是“putText”而不是“PutText”。我像这样使用它cv::putText
        • 它不会在我的图像上打印任何东西。我的代码: Mat fre = imread("1.jpg", 0); putText(fre, "区分两个图像。", cvPoint(30, 30), FONT_HERSHEY_COMPLEX_SMALL, 0.8, cvScalar(200, 200, 250), 1, CV_AA);
        【解决方案7】:
        putText(result, "Differencing the two images.", cvPoint(30,30), 
            FONT_HERSHEY_COMPLEX_SMALL, 0.8, cvScalar(200,200,250), 1, CV_AA);
        

        在上述行中,“结果”应该是 cvArr* 或 IplImage*。但从这里提供的代码来看,我猜你正在传递一个 cv::Mat 对象。 因此,您要么需要使用 cvarrToMat() 进行转换,要么通过 &result 而不是 result。

        希望对你有帮助

        【讨论】:

        • 很好,我不知道这种转换 - 我将它与 Mat 对象一起使用但没有成功。
        猜你喜欢
        • 1970-01-01
        • 2013-12-28
        • 2015-01-13
        • 1970-01-01
        • 1970-01-01
        • 2018-02-13
        • 2015-10-17
        • 1970-01-01
        • 2017-11-20
        相关资源
        最近更新 更多