利用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,則打開目錄 \builds\win32\vc2008 下的工程文件,編譯成功,關閉工程退出。
2、編譯成功后,在工具->選項->C++目錄中添加freetype下的include文件夾以及lib文件夾,將objs\win32\vc2008中的庫文件添加到當前工程的附加依賴項中。
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] != '\0'; ++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] != '\0'; ++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.3\builds\windows\vc2010\freetype.sln

二 將freetype庫添加到工程
1 添加包含目錄
依次點擊:Project->properties->VC++directories->Include Directories
添加:(路徑)\freetype-2.5.3\include

2 添加庫目錄
依次點擊:Project->properties->VC++directories->Library Directories
添加:(路徑)\freetype-2.5.3\objs\win32\vc2010

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM