zoukankan      html  css  js  c++  java
  • 利用OpenCV给图像添加中文标注

     利用OpenCV给图像添加中文标注 :

    参考:
    http://blog.sina.com.cn/s/blog_6bbd2dd101012dbh.html  和
    https://blog.csdn.net/ubunfans/article/details/45719009

    OpenCV不支持汉字输出,参考了网上的相关内容,将解决步骤简要记录如下:
    1、从 http://download.savannah.gnu.org/releases/freetype/ 下载FreeType库,windows下,根据自己用的编译器版本,打开相应的工程文件。比如,我用的VS2008,则打开目录 uildswin32vc2008 下的工程文件,编译成功,关闭工程退出。
    2、编译成功后,在工具->选项->C++目录中添加freetype下的include文件夹以及lib文件夹,将objswin32vc2008中的库文件添加到当前工程的附加依赖项中。
    3、参考opencv中文论坛这篇帖子: http://www.opencv.org.cn/forum/viewtopic.php?f=1&t=2083&hilit=汉字 直接copy前两个源码文件,保存为CvxText.h和CvxText.cpp,分别添加到当前工程中。
    4、接下来就可以直接调用函数了,最简单的例子:

           IplImage *img = cvLoadImage("test.jpg", 1);      
           CvxText text("simsun.ttf");//这个是系统自带的宋体字体文件,可以选别的
           const char *msg = "汉字";
           float p = 0.5;
           text.setFont(NULL, NULL, NULL, &p);   // 透明处理(第二个参数可以设置字体大小旋转等)
           text.putText(img, msg, cvPoint(100, 150), CV_RGB(255,0,0));
    这样就可以往图像test.jpg中坐标为(100,150)的位置添加红色的“汉字”二字啦。

    //-----------------------------------------------------------------------------
    注意:需要显示的图片一定是IplImage的 下面是Opencv Mat与Iplimage的相互转换:
    1、将Mat转换为IplImage
    //! converts header to IplImage; no data is copied
        operator IplImage() const;
    举例:Mat img;
                IplImage *src;
                 src=&IplImage(img);


    2、将IplImage转换为Mat
    //! converts old-style IplImage to the new matrix; the data is not copied by default
        Mat(const IplImage* img, bool copyData=false);
    //-----------------------------------------------------------------------------------------------
    CvxText.h 代码:
    // CvxText.h
    #ifndef OPENCV_CVX_TEXT_2007_08_31_H
    #define OPENCV_CVX_TEXT_2007_08_31_H
    #include <ft2build.h>
    #include FT_FREETYPE_H
    #include<opencv.hpp>
     
    class CvxText  
    {
       CvxText& operator=(const CvxText&);
    public:
       CvxText(const char *freeType);
       virtual ~CvxText();
       void getFont(int *type,
          CvScalar *size=NULL, bool *underline=NULL, float *diaphaneity=NULL);
       void setFont(int *type,
          CvScalar *size=NULL, bool *underline=NULL, float *diaphaneity=NULL);
       void restoreFont();

       int putText(IplImage *img, const char    *text, CvPoint pos);
       int putText(IplImage *img, const wchar_t *text, CvPoint pos);
       int putText(IplImage *img, const char    *text, CvPoint pos, CvScalar color);
       int putText(IplImage *img, const wchar_t *text, CvPoint pos, CvScalar color);
    private:
       void putWChar(IplImage *img, wchar_t wc, CvPoint &pos, CvScalar color);
    private:
       FT_Library   m_library;   // 字á?库a
       FT_Face      m_face;      // 字á?体??
       int         m_fontType;
       CvScalar   m_fontSize;
       bool      m_fontUnderline;
       float      m_fontDiaphaneity;
    };


    CvxText.cpp 代码:
        #include <wchar.h>
        #include <assert.h>
        #include <locale.h>
        #include <ctype.h>
        #include "CvxText.h"

        // 打开字库
        CvxText::CvxText(const char *freeType)
        {
           assert(freeType != NULL);
           // 打开字库文件, 创建一个字体
           if(FT_Init_FreeType(&m_library)) throw;
           if(FT_New_Face(m_library, freeType, 0, &m_face)) throw;
           // 设置字体输出参数 
           restoreFont();
          // 设置C语言的字符集环境
           setlocale(LC_ALL, "");
        }
        // 释放FreeType资源
        CvxText::~CvxText()
        {
           FT_Done_Face    (m_face);
           FT_Done_FreeType(m_library);
        }
         
        // 设置字体参数:
        // font         - 字体类型, 目前不支持
        // size         - 字体大小/空白比例/间隔比例/旋转角度
        // underline   - 下画线
        // diaphaneity   - 透明度
        void CvxText::getFont(int *type, CvScalar *size, bool *underline, float *diaphaneity)
        {
           if(type) *type = m_fontType;
           if(size) *size = m_fontSize;
           if(underline) *underline = m_fontUnderline;
           if(diaphaneity) *diaphaneity = m_fontDiaphaneity;
        }
         
        void CvxText::setFont(int *type, CvScalar *size, bool *underline, float *diaphaneity)
        {
           // 参数合法性检查
           if(type)
           {
              if(type >= 0) m_fontType = *type;
           }
           if(size)
           {
              m_fontSize.val[0] = fabs(size->val[0]);
              m_fontSize.val[1] = fabs(size->val[1]);
              m_fontSize.val[2] = fabs(size->val[2]);
              m_fontSize.val[3] = fabs(size->val[3]);
           }
           if(underline)
           {
              m_fontUnderline   = *underline;
           }
           if(diaphaneity)
           {
              m_fontDiaphaneity = *diaphaneity;
           }
        FT_Set_Pixel_Sizes(m_face, (int)m_fontSize.val[0], 0);
        }
         
        // 恢复原始的字体设置
        void CvxText::restoreFont()
        {
           m_fontType = 0;            // 字体类型(不支持)
           m_fontSize.val[0] = 20;      // 字体大小
           m_fontSize.val[1] = 0.5;   // 空白字符大小比例
           m_fontSize.val[2] = 0.1;   // 间隔大小比例
           m_fontSize.val[3] = 0;      // 旋转角度(不支持)
           m_fontUnderline   = false;   // 下画线(不支持)
           m_fontDiaphaneity = 1.0;   // 色彩比例(可产生透明效果)
           // 设置字符大小
           FT_Set_Pixel_Sizes(m_face, (int)m_fontSize.val[0], 0);
        }
         
        // 输出函数(颜色默认为黑色)
        int CvxText::putText(IplImage *img, const char    *text, CvPoint pos)
        {
           return putText(img, text, pos, CV_RGB(255,255,255));
        }
        int CvxText::putText(IplImage *img, const wchar_t *text, CvPoint pos)
        {
           return putText(img, text, pos, CV_RGB(255,255,255));
        }
        
        int CvxText::putText(IplImage *img, const char    *text, CvPoint pos, CvScalar color)
        {
           if(img == NULL) return -1;
           if(text == NULL) return -1;
        
           int i;
           for(i = 0; text[i] != ''; ++i)
           {
              wchar_t wc = text[i];
              // 解析双字节符号
              if(!isascii(wc)) mbtowc(&wc, &text[i++], 2);
              // 输出当前的字符
              putWChar(img, wc, pos, color);
           }
           return i;
        }
        int CvxText::putText(IplImage *img, const wchar_t *text, CvPoint pos, CvScalar color)
        {
           if(img == NULL) return -1;
           if(text == NULL) return -1;
           int i;
           for(i = 0; text[i] != ''; ++i)
           {
              // 输出当前的字符
              putWChar(img, text[i], pos, color);
           }
           return i;
        }
         
        // 输出当前字符, 更新m_pos位置
        void CvxText::putWChar(IplImage *img, wchar_t wc, CvPoint &pos, CvScalar color)
        {
           // 根据unicode生成字体的二值位图
           FT_UInt glyph_index = FT_Get_Char_Index(m_face, wc);
           FT_Load_Glyph(m_face, glyph_index, FT_LOAD_DEFAULT);
           FT_Render_Glyph(m_face->glyph, FT_RENDER_MODE_MONO);
           FT_GlyphSlot slot = m_face->glyph;
         
           // 行列数
           int rows = slot->bitmap.rows;
           int cols = slot->bitmap.width;
           for(int i = 0; i < rows; ++i)
           {
              for(int j = 0; j < cols; ++j)
              {
                 int off  = ((img->origin==0)? i: (rows-1-i))
                    * slot->bitmap.pitch + j/8;
                 if(slot->bitmap.buffer[off] & (0xC0 >> (j%8)))
                 {
                    int r = (img->origin==0)? pos.y - (rows-1-i): pos.y + i;;
                    int c = pos.x + j;
                    if(r >= 0 && r < img->height
                       && c >= 0 && c < img->width)
                    {
                       CvScalar scalar = cvGet2D(img, r, c);
                       // 进行色彩融合
                       float p = m_fontDiaphaneity;
                       for(int k = 0; k < 4; ++k)
                       {
                          scalar.val[k] = scalar.val[k]*(1-p) + color.val[k]*p;
                       }
                       cvSet2D(img, r, c, scalar);
                    }
                 }
              }
           }
         
           // 修改下一个字的输出位置
           double space = m_fontSize.val[0]*m_fontSize.val[1];
           double sep   = m_fontSize.val[0]*m_fontSize.val[2];
           pos.x += (int)((cols? cols: space) + sep);
        }

    //-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    freetype下载和配置
    https://blog.csdn.net/xufeng0991/article/details/40735651
    一 下载编译freetype库

    1 下载
    地址:http://www.freetype.org/
    得到压缩文件:freetype-2.5.3.tar.gz

    2 解压:
    直接解压,得到目录freetype-2.5.3

    3 编译:
    用vs2010打开:(路径)freetype-2.5.3uildswindowsvc2010freetype.sln

    二 将freetype库添加到工程
    1 添加包含目录
    依次点击:Project->properties->VC++directories->Include Directories
    添加:(路径)freetype-2.5.3include

    2 添加库目录
    依次点击:Project->properties->VC++directories->Library Directories
    添加:(路径)freetype-2.5.3objswin32vc2010

    3 添加附加依赖项
    依次点击:Project->properties->Linker->Input->Additional Dependencies
    添加:(路径)freetype253.lib;freetype253_D.lib

    三 测试
    运行以下代码:

        #include <ft2build.h>
        #include FT_FREETYPE_H
        #include <iostream>
        using namespace std;
         
        int main()
        {
            FT_Library library;
            FT_Init_FreeType(&library);
        
            FT_Face face;
            FT_New_Face(library, "msyh.ttf", 0, &face);
        
            cout<<"num_glyphs:"<<face->num_glyphs<<endl;
            cout<<"num_faces:"<<face->num_faces<<endl;
            system("Pause");
            return 0;
        }
    能编译运行,就一切ok了

    //---------------------------------------------------------------------
    Opencv310图片Mat中叠加汉字(freetype+VS2015)
    https://blog.csdn.net/zmdsjtu/article/details/53133223

  • 相关阅读:
    MVC各部分技术体现
    SSM框架——详细整合教程(Spring+SpringMVC+MyBatis)
    my SQL Workbench创建数据库
    哪些素质很重要,却是读书学不来
    给程序员最好的18个忠告!
    互联网协议入门(二)
    互联网协议入门(一)
    div+css命名规范大全
    javascript中this的用法
    XHTML 相对路径与绝对路径
  • 原文地址:https://www.cnblogs.com/qiantao/p/9441328.html
Copyright © 2011-2022 走看看