(1)FreeType下載與編譯;
(2)OpenCV工程demo中須添加代碼資源;
(3)OpenCV中添加FreeType庫及配置;
(4)遇到的問題與解決;
由於OpenCV自帶的cvInitFont和cvPutText函數不支持向圖像中寫入中文,需要使用FreeType庫來進行漢字顯示。
FreeType庫是一個完全免費(開源)的、高質量的且可移植的字體引擎,它提供統一的接口來訪問多種字體格式文件,包括TrueType, OpenType, Type1, CID, CFF, Windows FON/FNT, X11 PCF等。
OpenCV+FreeType顯示漢字的中步驟如下:
(1)VS2013+OpenCV配置;
(2)FreeType下載;
(3)FreeType重編譯;
(4)OpenCV工程demo中添加代碼資源等;
(5)OpenCV中添加FreeType庫及配置。
(6)OpenCV工程demo編譯、運行工程。
VS + CV的配置已介紹過多次,這裏不再贅述。詳細見:Win7 64位+VS2013 OpenCV 2.4.9安裝配置,Win7 64位+VS2013 OpenCV 3.1.0安裝配置
本工程中系統版本爲:Win7 64位,平臺爲:VS2013,OpenCV採用:
OpenCV 2.4.9及OpenCV 3.1.0,其中OpenCV 2.4.9在VS2013中調試平臺爲
Win 32(32位:x86),OpenCV 3.1.0在VS2013中調試平臺爲x64(64位:x64)。
首先,我們下載 FreeType 的源代碼。從官網(https://www.freetype.org/)的sourceforge:https://sourceforge.net/projects/freetype/files/freetype2上獲得 FreeType 的源碼工程,(這裏最新版本爲2.7,本工程中採用較爲穩定的2.6.2)。
圖 2.2.1 FreeType 下載
STEP 1:
將下載下來的ft262.zip文件解壓後得到freetype-2.6.2文件夾,把 freetype-2.6.2這個目錄拷貝到這個目錄下:D:\opencv lib\。
圖 2.3.1 freeyype-2.6.2 文件夾
注意:[1] 如果電腦上並不存在這個目錄,需要自己創建。[2] 亦可使用電腦中的其他路徑,但如果在後面的步驟中涉及到這個路徑,需要自行轉換成自己所用的路徑。
STEP 2:
在系統變量中,增加:FreeType : D:\opencv lib\\freetype-2.6.2
圖 2.3.2 freeyype-2.6.2 環境變量配置
這麼做的好處是:
[1]以後當我們需要用到 D:\opencv lib\\freetype-2.6.2這個路徑的時候,可以用%FreeType%或者$(FreeType)來代替它;
[2]如果我們以後更換了 FreeType的版本,只需要更新FreeType系統變量,就可以用%FreeType%或者$(FreeType)來指向最新版本的路徑了。
STEP 3:
在 %FreeType%\builds\windows 這個目錄下,我們能看到 visualc(這是給VC6用的)、vc2005、vc2008、vc2010,沒有vs2013。這裏我們直接把vs2010複製出一份重命名爲vs2013。
圖 2.3.3 將 vs2010 複製出一份重命名爲vs2013
STEP 4:
在 %FreeType%\builds\windows\vs2013中,用Visual Studio 2013打開freetype.sln。右鍵freetype工程打開屬性頁。
圖 2.3.4 freetype屬性頁
[1]將配置屬性→常規中的配置(C)選爲所有配置,平臺(P)選爲所有平臺;
[2]將輸出目錄及中間目錄中的vc2010字樣修改爲MSVC;
(注意:爲什麼改成 MSVC 呢?是爲了跟 FreeType for Windows Binary Download下載得到的文件路徑保持一致。)
[3]將字符集中的使用多字節字符集(也就是 MBCS,MBCS的存在是爲了兼容Windows NT、Windows 98、Windows 2000等舊操作系統,對於較新Windows系統儘量使用Unicode字符集。)修改爲使用Unicode字符集。
[4]將配置類型中的靜態庫 (.lib),其實像這種公共的庫我們最好使用動態鏈接庫。我們把它改成動態庫 (.dll)。
修改之後的屬性頁如下圖所示:
圖 2.3.5 修改後的屬性頁
[5]此時如果去編譯,雖然可以得到動態鏈接庫(DLLs),但不會得到LIB。此時程序只能顯式地調用動態鏈接庫,卻無法隱式地調用動態鏈接庫(需要LIB)。
在 %FreeType%/include/freetype/config/ftconfig.h的找到這一段(第387行):
1
2
3
4
5
6
7
8
9
|
#ifndef FT_EXPORT
#ifdef __cplusplus
#define FT_EXPORT( x ) extern
"C"
x
#
else
#define FT_EXPORT( x ) extern x
#endif
#endif
/* !FT_EXPORT */
|
修改爲:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
#ifdef DLL_EXPORT
#undef DLL_EXPORT
#define DLL_EXPORT __declspec(dllexport)
#
else
#define DLL_EXPORT __declspec(dllimport)
#endif
/* !DLL_EXPORT */
#ifndef FT_EXPORT
#ifdef __cplusplus
#define FT_EXPORT( x ) extern
"C"
DLL_EXPORT x
#
else
#define FT_EXPORT( x ) extern DLL_EXPORT x
#endif
#endif
/* !FT_EXPORT */
|
STEP 5:進行編譯
點擊 Visual Studio 2013菜單生成→批生成,點擊全選然後點擊生成。
圖 2.3.6 編譯菜單
編譯結果如下,至此FreeType 2.6.2 VS2013下重編譯完成。
圖 2.3.7 編譯結果
STEP 1:
新建一個VS C++工程,配置好OpenCV(重新配置或者添加原來工程配置好的OpenCV項目屬性表,本項目中採用添加現有項目屬性表的方式)。
STEP 2:
項目中添加頭文件CvxText.h和源文件CvxText.cpp。源代碼如下。
CvxText.h:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
|
//====================================================================
//====================================================================
//
// 文件: CvxText.h
//
// 說明: OpenCV漢字輸出
//
// 時間:
//
// 作者: chaishushan#gmail.com
//
//====================================================================
//====================================================================
#ifndef OPENCV_CVX_TEXT_2007_08_31_H
#define OPENCV_CVX_TEXT_2007_08_31_H
/**
* \file CvxText.h
* \brief OpenCV漢字輸出接口
*
* 實現了漢字輸出功能。
*/
#include <ft2build.h>
#include FT_FREETYPE_H
#include<opencv2 opencv.hpp=
""
>
/**
* \class CvxText
* \brief OpenCV中輸出漢字
*
* OpenCV中輸出漢字。字庫提取採用了開源的FreeFype庫。由於FreeFype是
* GPL版權發佈的庫,和OpenCV版權並不一致,因此目前還沒有合併到OpenCV
* 擴展庫中。
*
* 顯示漢字的時候需要一個漢字字庫文件,字庫文件系統一般都自帶了。
* 這裏採用的是一個開源的字庫:「文泉驛正黑體」。
*
* 關於"OpenCV擴展庫"的細節請訪問
*
* 關於FreeType的細節請訪問
*/
class
CvxText
{
// 禁止copy
CvxText& operator=(
const
CvxText&);
//================================================================
//================================================================
public
:
/**
* 裝載字庫文件
*/
CvxText(
const
char
*freeType);
virtual ~CvxText();
//================================================================
//================================================================
/**
* 獲取字體。目前有些參數尚不支持。
*
* \param font 字體類型, 目前不支持
* \param size 字體大小/空白比例/間隔比例/旋轉角度
* \param underline 下畫線
* \param diaphaneity 透明度
*
* \sa setFont, restoreFont
*/
void
getFont(
int
*type,
CvScalar *size = NULL, bool *underline = NULL,
float
*diaphaneity = NULL);
/**
* 設置字體。目前有些參數尚不支持。
*
* \param font 字體類型, 目前不支持
* \param size 字體大小/空白比例/間隔比例/旋轉角度
* \param underline 下畫線
* \param diaphaneity 透明度
*
* \sa getFont, restoreFont
*/
void
setFont(
int
*type,
CvScalar *size = NULL, bool *underline = NULL,
float
*diaphaneity = NULL);
/**
* 恢復原始的字體設置。
*
* \sa getFont, setFont
*/
void
restoreFont();
//================================================================
//================================================================
/**
* 輸出漢字(顏色默認爲黑色)。遇到不能輸出的字符將停止。
*
* \param img 輸出的影象
* \param text 文本內容
* \param pos 文本位置
*
* \return 返回成功輸出的字符長度,失敗返回-1。
*/
int
putText(IplImage *img,
const
char
*text, CvPoint pos);
/**
* 輸出漢字(顏色默認爲黑色)。遇到不能輸出的字符將停止。
*
* \param img 輸出的影象
* \param text 文本內容
* \param pos 文本位置
*
* \return 返回成功輸出的字符長度,失敗返回-1。
*/
int
putText(IplImage *img,
const
wchar_t *text, CvPoint pos);
/**
* 輸出漢字。遇到不能輸出的字符將停止。
*
* \param img 輸出的影象
* \param text 文本內容
* \param pos 文本位置
* \param color 文本顏色
*
* \return 返回成功輸出的字符長度,失敗返回-1。
*/
int
putText(IplImage *img,
const
char
*text, CvPoint pos, CvScalar color);
/**
* 輸出漢字。遇到不能輸出的字符將停止。
*
* \param img 輸出的影象
* \param text 文本內容
* \param pos 文本位置
* \param color 文本顏色
*
* \return 返回成功輸出的字符長度,失敗返回-1。
*/
int
putText(IplImage *img,
const
wchar_t *text, CvPoint pos, CvScalar color);
//================================================================
//================================================================
private
:
// 輸出當前字符, 更新m_pos位置
void
putWChar(IplImage *img, wchar_t wc, CvPoint &pos, CvScalar color);
//================================================================
//================================================================
private
:
FT_Library m_library;
// 字庫
FT_Face m_face;
// 字體
//================================================================
//================================================================
// 默認的字體輸出參數
int
m_fontType;
CvScalar m_fontSize;
bool m_fontUnderline;
float
m_fontDiaphaneity;
//================================================================
//================================================================
};
#endif
// OPENCV_CVX_TEXT_2007_08_31_H</opencv2></ft2build.h>
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
|
#include <wchar.h>
#include
#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)
if
(type >=
0
) m_fontType = *type;
}
if
(size)
{
{
m_fontSize.val[
0
] = fabs(size->val[
0
]);
m_fontSize.val[
1
] = fabs(size->val[
] = fabs(size->val[
|