章 安,馬明棟
(1.南京郵電大學(xué) 通信與信息工程學(xué)院,江蘇 南京 210003; 2.南京郵電大學(xué) 地理與生物信息學(xué)院,江蘇 南京 210003)
1929年德國科學(xué)家Tausheck提出了OCR的概念[1],通過對圖像像素點(diǎn)的分割,與字符庫對照,獲取最近似的計(jì)算機(jī)文字。最初的OCR技術(shù)目的在于信息化處理大量的印刷品,例如報(bào)刊雜志、文件資料和其他文字材料,進(jìn)而開始了西文OCR技術(shù)的研究,以便代替人工鍵盤輸入[2]。隨著時(shí)間的推移,科技公司的不懈努力以及計(jì)算機(jī)技術(shù)的飛速發(fā)展,西文OCR技術(shù)現(xiàn)已廣泛應(yīng)用于各個(gè)領(lǐng)域,實(shí)現(xiàn)了“電子化”信息處理。
國內(nèi)對于印刷體漢字識(shí)別的研究從20世紀(jì)70年代末起步[3],至今己有近四十年的發(fā)展歷史。從最開始對數(shù)字、英文、符號(hào)識(shí)別的研究,到對漢字識(shí)別進(jìn)行了探索,80年代后期,大量研究人員鉆研其中,漢字識(shí)別技術(shù)也趨于實(shí)用化[4]。如今市場上的OCR識(shí)別平臺(tái)層出不窮,最常見的百度、華為和騰訊等公司都提供了文字識(shí)別云平臺(tái),在所需的環(huán)境之下,調(diào)用其提供的在線接口,便可以實(shí)現(xiàn)文字的識(shí)別。
Tesseract是一個(gè)開源OCR庫,源碼存在于github上。基于其開源的特性,可以添加接口,豐富其功能。支持Tesseract的Leptonica組件有著優(yōu)越的圖像分析性能,保證了文字識(shí)別的精度。除此之外,Tesseract還具有多平臺(tái)的可移植性,擁有龐大的Unicode字符識(shí)別庫。
識(shí)別是智能的基礎(chǔ)[5],目前互聯(lián)網(wǎng)技術(shù)迅速發(fā)展,在AI(artificial intelligence,人工智能)技術(shù)的需求之下,OCR技術(shù)成為了不可忽略的部分,通過文字的識(shí)別,提高了各行各業(yè)的生產(chǎn)效率。
文字識(shí)別通常有兩種形式,手寫體與印刷體[6]。對于印刷體而言,研究結(jié)果相對成熟,而手寫體更為復(fù)雜,該文的討論范圍僅在于印刷體的文字識(shí)別。
文字識(shí)別通常包括以下流程:
(1)預(yù)處理:預(yù)處理操作在圖像識(shí)別之前。已采集的圖像質(zhì)量受多方面因素影響,圖像的亮暗、印刷體質(zhì)量、污點(diǎn)或陰影都是干擾識(shí)別的因素。預(yù)處理主要是對圖像進(jìn)行處理,將圖像灰度化以及二值化,進(jìn)而對圖像的傾斜、邊框等問題進(jìn)行處理,使得文字規(guī)范,圖像平滑,從而有利于接下來的處理操作[7]。
(2)版面分析:版面分析主要處理文本圖像的不同部分,分析圖像中不同類型文本,例如標(biāo)題或是正文,插圖或是表格,從而獲取文章邏輯結(jié)構(gòu),包括各區(qū)域的邏輯屬性、文章的層次關(guān)系和閱讀順序。最后根據(jù)版面分析和文字的結(jié)果,進(jìn)行版面重構(gòu)。
(3)圖像切分:識(shí)別是單個(gè)文字的識(shí)別,因而必須對圖像進(jìn)行行列切分。印刷體文字圖像行列間距、字間距大致相等,簡化了處理方法。
(4)特征提取與模型訓(xùn)練:通過深度學(xué)習(xí)框架,對文字識(shí)別進(jìn)行特征提取和模型訓(xùn)練,提高了識(shí)別的有效性和可靠性。
(5)識(shí)別后處理:識(shí)別后處理通常包括版面的重構(gòu)和識(shí)別的校正,對原圖像版面的恢復(fù)以及不同語言模型的校正[8]。
通過以上流程,計(jì)算機(jī)通過輸入的圖像,分析并識(shí)別文字,同時(shí)保存于硬件中。識(shí)別流程不包括圖像的采集、最終圖像的輸出,這類工作由其他硬件實(shí)現(xiàn)。
預(yù)處理是文字識(shí)別的重要一環(huán),預(yù)處理對圖像質(zhì)量的提升起到了關(guān)鍵作用。預(yù)處理通常包括灰度化、二值化、傾斜校正和噪聲消除[9],該文實(shí)現(xiàn)了以下幾個(gè)預(yù)處理方法,為Tesseract文字識(shí)別做好準(zhǔn)備。
Tesseract處理圖像的DPI(dots per inch,每英寸點(diǎn)像素?cái)?shù))默認(rèn)為300 DPI,因而對于DPI不足的圖片,需要進(jìn)行縮放處理。常用的縮放算法有最近鄰算法(最近鄰插值)、雙線性插值算法以及更為復(fù)雜的三次插值算法[10],三種算法的精度不一?;谖淖肿R(shí)別的精度要求,該文實(shí)現(xiàn)了雙線性插值圖像縮放算法。
在離散數(shù)學(xué)中,插值是指在離散數(shù)據(jù)的基礎(chǔ)上補(bǔ)差連續(xù)函數(shù)[11],使得該連續(xù)曲線通過全部給定的離散數(shù)據(jù)點(diǎn),關(guān)鍵在于恢復(fù)曲線的連續(xù)與平滑。與之類似,圖像基本構(gòu)成是有限像素集,在圖像縮放的過程中,需要對圖像進(jìn)行像素的插入(放大)或是疊加(縮小)。
圖像縮放的過程中,原圖像與輸出圖像具有一定的映射關(guān)系:
Y(x'+u,y'+v)=X(x,y)=X(h1(x,y),h2(x,y))
(1)
其中,X(x,y)表示輸入圖像,Y(x'+u,y'+v)表示輸出圖像,h1和h2表示映射函數(shù)。轉(zhuǎn)換之后可能出現(xiàn)小數(shù)的情況,令x'和y'作為坐標(biāo)的整數(shù)部分,u和v作為小數(shù)部分。
圖1 雙線性插值示意
如圖1所示,取轉(zhuǎn)換點(diǎn)四個(gè)領(lǐng)域整數(shù)位置點(diǎn)(x',y'),(x',y'+1),(x'+1,y'),(x'+1,y'+1)。設(shè)RGB滿足函數(shù)f(x,y),則轉(zhuǎn)換之后的點(diǎn)坐標(biāo)中的RGB值為:
f(x,y)=f(x'+u,y'+v)
(2)
f(x'+u,y'+v)=f(x,y)*(1-u)*(1-v)+
f(x',y'+1)*(1-u)*v+
f(x'+1,y)*u*(1-v)+
f(x'+1,y'+1)*u*v
(3)
式(3)類比于一維坐標(biāo)系下的長度比值關(guān)系,在二維坐標(biāo)系下,是富含規(guī)律的面積比值關(guān)系。即所求點(diǎn)的RGB等于:
f(x,y)=∑Ri*S對角
(4)
其中,Ri表示領(lǐng)域點(diǎn)的RGB中的某一項(xiàng),S對角表示對角的矩形面積值。
示例代碼:
for (int k=0;k<3;k++)
{
change[x+k]=image[o_x+k]*(1-a_x)*(1-a_y)+
//對應(yīng)f(x,y)*(1-u)*(1-v)
image[o_b+k]*a_x*(1-a_y)+
/對應(yīng)/f(x',y'+1)*(1-u)*v
image[o_c+k]* a_y*(1 - a_x) +
//對應(yīng)f(x'+1,y)*u*(1-v)
image[o_d+k]* a_y*a_x;
//對應(yīng)f(x'+1,y'+1)*u*v
}
二值化的過程形如二進(jìn)制中的01變化,圖像的二值化就是將圖像的像素點(diǎn)的灰度值設(shè)置成0或255。首要工作是將圖像灰度化,灰度化是將原圖像各像素R、G、B三個(gè)值按照不同的權(quán)值,將加權(quán)和均賦值給目標(biāo)圖像的RGB值。二值化的算法的重點(diǎn)是獲取像素點(diǎn)灰度的閾值,高于閾值的像素點(diǎn)灰度設(shè)置為255,反之設(shè)置為0。二值化的算法眾多,常用的如利用聚類思想、根據(jù)灰度特征劃分前景后景的Otsu算法,以及基于像素點(diǎn)為中心確定利用范圍像素確定像素閾值的Bernsen算法[12]。
由于人眼對RGB三色的敏感度不同[13],因而灰度化時(shí)權(quán)值必然不同,該文利用心理學(xué)公式(5)中的權(quán)值實(shí)現(xiàn)灰度化,該公式適用于sRGB存儲(chǔ)空間的圖像。
Gray=R*0.299+G*0.587+B*0.114
(5)
實(shí)現(xiàn)方法只需遍歷所有像素點(diǎn),對其RGB求加權(quán)和,將新值更新到源像素點(diǎn)中。
對于二值化過程,該文使用Otsu算法,Otsu算法又稱為“大津法”、最大類間方差法[14]。該算法的主要思想是根據(jù)圖像的灰度特征將圖像分為前景與背景兩部分,而前景就是所求的目標(biāo)圖像[15],使用方差這一統(tǒng)計(jì)量,反映前后景灰度差距,其中存在概率分布,實(shí)行概率加權(quán),最終遍歷所有可能的灰度值,方差最大處為灰度閾值。
具體流程如下:
設(shè)圖像灰度范圍為[0,L-1],閾值M∈[0,L-1]。
(1)分別計(jì)算像素灰度值在[0,M]與(M,L-1]出現(xiàn)的概率P1和P2,其中:
P1+P2=1
(6)
(2)分別計(jì)算像素在[0,M]和(M,L-1]的平均值μ1和μ2及總體灰度平均值μ。
(3)灰度類間方差函數(shù)為:
σ2=P1(μ1-μ)2+P2(μ2-μ)2
(7)
由概率以及均值關(guān)系可推出最終表達(dá)式:
σ2=P1P2(μ1μ2)2
(8)
(4)遍歷所有灰度閾值M,方差最大時(shí)的M即為最佳閾值。
示例為部分代碼:
int OtsuAlgThreshold(const Mat){
int M;//閾值
for(int i=0;i < 255;i++){
double p1=0,u1=0,p2=0,u2=0;
double sum1=0,sum2=0;//像素點(diǎn)總數(shù)
double gray_sum1=0,gray_sum2=0;//灰度值總數(shù)
for(int j=0;j<=i;j++){
sum2+=gram[j];
gray_num2+= j*gram[j];
sum1+= gram[i+j];
gray_num1+=(i +j)*gram[i+j];
}
u2=gray_sum2/sum2;
p2=sum2/total;
u1=gray_sum1/sum1;
p1=sum1/total;
//類間方差計(jì)算
double Sq=p1*p2*(u1-u2)*(u1-u2);
if(SqMax < sq){
SqMax=sq;//更新最大方差值
M=i;
}
}
return M;//返回閾值M
}
以上獲取最佳方差的灰度值之后,便可通過遍歷像素點(diǎn)進(jìn)行灰度值調(diào)整。
輸入的圖像由于采集設(shè)備的原因可能存在意想不到的邊框,或是圖像角度發(fā)生了偏移,因而會(huì)影響接下來的版面分析與行列切分工作,最終影響識(shí)別效果。此部分涉及到兩個(gè)部分,一是發(fā)生偏移的角度,二是邊框的選取。該文參考OpenCV庫中的函數(shù),實(shí)現(xiàn)了一種方法,方法的重點(diǎn)在于遍歷查找最小外接矩形,旋轉(zhuǎn)之后進(jìn)行切割,從而獲取最終圖像。方法流程如下:
(1)獲取圖像最小外接矩形。
(2)獲取圖像偏移角度,同時(shí)進(jìn)行旋轉(zhuǎn)操作。
(3)對圖像進(jìn)行輪廓檢測,循環(huán)篩選。
(4)切邊,獲取最終圖像。
該思路之前需要對圖像進(jìn)行灰度化和二值化處理,以便于提高檢測的精度。
此前的圖像預(yù)處理是為了文字識(shí)別作鋪墊。預(yù)處理過程使得圖像質(zhì)量得到一定的改善,其DPI和對比度得到顯著提升,文字的方向和邊框也得到校正,從而改善了識(shí)別的準(zhǔn)確性。文中的漢字識(shí)別,依賴于Tesseract框架,識(shí)別出Unicode字符。
此測試環(huán)境需要的配置如表1所示。
表1 配置環(huán)境與說明
預(yù)先需要使用CMake編譯工具將Libtiff、Leptonica編譯,在Tesseract中添加動(dòng)態(tài)鏈接庫(后綴為.dll)文件之后方可使用。
識(shí)別代碼如下:
char *outPut;
tesseract::TessBaseAPI *ocr=new tesseract::TessBaseAPI();
//初始化ocr識(shí)別模式
if(ocr->Init(NULL, "eng")) {
cerr<<"Initialize Failed”< exit(1);//退出 } //傳入?yún)?shù) Pix *image=pixRead(Imag_name); ocr->SetImage(image); //輸出結(jié)果 outPut=ocr->GetUTF8Text(); cout<