胡 文,馬玲玉
(哈爾濱商業(yè)大學(xué) 計(jì)算機(jī)與信息工程學(xué)院,哈爾濱 150028)
基于OpenCV手機(jī)拍照快遞單文字識(shí)別的研究
胡 文,馬玲玉
(哈爾濱商業(yè)大學(xué) 計(jì)算機(jī)與信息工程學(xué)院,哈爾濱 150028)
基于OpenCV在Android手機(jī)上設(shè)計(jì)了快遞單文字識(shí)別機(jī)制,識(shí)別內(nèi)容主要分為電話和姓名識(shí)別.手機(jī)拍攝快遞單后,在屏幕上畫出兩個(gè)矩形框,根據(jù)矩形框的周長(zhǎng)面積特征,判定電話和姓名區(qū)域并提取這兩部分圖片;對(duì)這兩個(gè)圖片進(jìn)行灰度化、二值化、形態(tài)學(xué)處理,再進(jìn)行字符分割、歸一化處理.為了提高數(shù)字分割速度提出一種基于輪廓檢測(cè)的分割方法.根據(jù)數(shù)字和漢字的不同特征選取不同的識(shí)別方法進(jìn)行字符識(shí)別.
文字識(shí)別;openCV;Android;快遞單識(shí)別
隨著電子商務(wù)的飛速發(fā)展,物流行業(yè)呈現(xiàn)出前所未有的盛況.物流站點(diǎn)收發(fā)包裹需聯(lián)系大量收件人,若用手機(jī)拍照快遞單后,將其信息提取到手機(jī)上,會(huì)節(jié)省很多時(shí)間和人力.當(dāng)前字符識(shí)別系統(tǒng)很多,大多是掃描整個(gè)圖片進(jìn)行識(shí)別.本文只提取圖片的重要部分進(jìn)行識(shí)別,提高識(shí)別精度,降低識(shí)別時(shí)間.
OpenCV 是一款內(nèi)嵌圖像處理、模式識(shí)別、機(jī)器
學(xué)習(xí)等各種算法的跨平臺(tái)開(kāi)源計(jì)算機(jī)視覺(jué)庫(kù),基于此開(kāi)發(fā)的程序可提高系統(tǒng)的速度、精度和可靠性[1].
Android是一款基于Linux 平臺(tái)的開(kāi)源手機(jī)操作系統(tǒng),界面友好,操作簡(jiǎn)易.其應(yīng)用程序通過(guò)Android SDK(Software Development Kit)利用Java 編程語(yǔ)言進(jìn)行開(kāi)發(fā),也可利用第三方C/C++ 庫(kù)協(xié)助開(kāi)發(fā)[2].
本實(shí)驗(yàn)為windows32位系統(tǒng),首先下載集成環(huán)境adt-bundle-windows-x86,運(yùn)行Eclipse程序.然后添加AndroidSDK,安裝android-ndk-r10.最后導(dǎo)入OpenCV-2.4.6-android-sdk,先加載Opencv-sdk包中的庫(kù),再加載示例程序.
快遞單上包含很多信息,本文只研究姓名和電話號(hào)碼識(shí)別,設(shè)計(jì)流程如圖1所示.手機(jī)拍照后手動(dòng)用矩形框畫出電話號(hào)碼和姓名部分,根據(jù)兩個(gè)矩形框的的周長(zhǎng)面積特征判定所畫出的圖片類別,依次對(duì)其進(jìn)行灰度化、二值化、形態(tài)學(xué)處理和字符分割.數(shù)字分割用輪廓檢測(cè)方法,漢字分割用低谷投影檢測(cè)法.最后進(jìn)行歸一化.預(yù)處理后根據(jù)數(shù)字和漢字的不同進(jìn)行特征提取,依據(jù)這些特征進(jìn)行字符識(shí)別.
圖1 設(shè)計(jì)流程
2.1 圖片定位提取
本程序有兩個(gè)Activity,主Activity用于照片的獲取.CameraBridgeViewBase抽象類擴(kuò)展了Android的SurfaceView,其實(shí)例實(shí)現(xiàn)了為相機(jī)提供了回調(diào)操作的兩個(gè)接口.本文實(shí)現(xiàn)的是可在RGBA色彩或灰度格式中獲得一幅Mat圖像的CvCameraViewListener2接口[2].CvCamer ViewListener2接口提供三個(gè)回調(diào)方法.本程序通過(guò)onCameraFrame方法對(duì)相機(jī)幀進(jìn)行實(shí)時(shí)處理,包括濾鏡及圖片的保存.濾鏡過(guò)程用到 UnivariateInterpolator等類,需導(dǎo)入commons-math-3.4.1.jar包.濾鏡關(guān)鍵代碼如下:UnivariateInterpolator interpolator;
if (valIn.length > 2) {
interpolator = new SplineInterpolator();
} else {
interpolator = new LinearInterpolator();}
return interpolator.interpolate(valIn, valOut);
}}
該濾鏡相當(dāng)于FujiVelvia膠片的效果,使相機(jī)達(dá)到很高的分辨率、銳化和很細(xì)的顆粒.圖片保存較繁瑣,用獨(dú)立的方法實(shí)現(xiàn).在該方法中啟動(dòng)副Activity.在副Activity中顯示拍攝好的照片,對(duì)該照片手動(dòng)用兩個(gè)矩形框圈畫出姓名和電話號(hào)碼,觸摸矩形框滑動(dòng)可移動(dòng)矩形框,而觸摸其對(duì)頂點(diǎn)可縮放大小.記錄矩形框頂點(diǎn)坐標(biāo),據(jù)此計(jì)算兩個(gè)矩形框的周長(zhǎng)面積來(lái)區(qū)別出矩形框的類別.保存裁剪好后的兩個(gè)圖片.
為支持包含Opencv庫(kù)的程序運(yùn)行,手機(jī)需安裝OpenCV Manager.OpenCV Manager 通過(guò)BaseLoaderCallback抽象類與客戶端交互,該類提供回調(diào)方法對(duì)客戶服務(wù).本程序在該方法中實(shí)現(xiàn)相機(jī)的連接,初始化數(shù)據(jù),加載OpenCV庫(kù).
2.2 圖片預(yù)處理
2.2.1二值化處理
首先使用CvCameraViewFrame類的gray()方法進(jìn)行灰度化處理.其次進(jìn)行二值化處理,采用閾值法.
普通方法:
cvThreshold( CvArr* src,CvArr* dst,
double threshold, double max_value(M),
CV_THRESH_BINARY)
src為源圖片,dst為目標(biāo)圖片,threshold(T)為設(shè)定的閾值,dst中像素值依據(jù)dsti=(srci>T) ?M: 0得出[3].如圖2所示.
圖2 閾值化過(guò)程
自適應(yīng)閾值法:
cvAdaptiveThreshold( CvArr* src,CvArr*dst,double max_val,int adaptive_method=CV_ADAPTIVE_THRESH_MEAN_C,
threshold_type = CV_THRESH _ BINARY,
int block _ size(b) = 3,double param1 = 5)
每個(gè)像素點(diǎn)閾值都不同.閾值通過(guò)計(jì)算像素點(diǎn)周圍的b×b區(qū)域的加權(quán)平均,并減掉一個(gè)常數(shù)(paraml)獲得.該方法適用于有較強(qiáng)梯度的圖像.
本文采用普通方法進(jìn)行二值化.二值化后圖片變?yōu)楹诎追置?,為消除孤立的點(diǎn)進(jìn)行形態(tài)學(xué)處理.首先用cvErode進(jìn)行腐蝕,腐蝕結(jié)構(gòu)元素為1×1;再用cvDilate進(jìn)行膨脹,膨脹結(jié)構(gòu)元素為2×2[4].
2.2.2字符分割
1)數(shù)字字符分割
本文根據(jù)Opencv輪廓的相關(guān)知識(shí)提出一個(gè)數(shù)字字符分割的算法,算法流程如圖3所示.用cvCvtColor( dst,src, CV_BGR2GRAY )得到兩個(gè)圖片副本.
圖3 算法流程
CvFindContours ( img,storage,&contours,sizeof(CvContour), CV_RETR_LIST)函數(shù)檢測(cè)圖片1的輪廓.storage為輪廓的存儲(chǔ)開(kāi)辟內(nèi)存空間.contours序列指針指向輪廓存儲(chǔ)的首地址,用于獲取各個(gè)輪廓.CV_RETR_LIST表示提取整個(gè)圖片的輪廓.同理檢測(cè)圖片2時(shí)CV_RETR_LIST改為CV_RETR_CCOMP,只檢測(cè)圖片最外圍的邊框和內(nèi)部的孔,圖4所示.對(duì)于數(shù)字0,4,6,8,9可檢測(cè)出內(nèi)部的孔.
cvDrawContours( img, contours, cvScalarAll(255),cvScalarAll(255), 1)根據(jù)檢測(cè)出的輪廓繪制圖片.圖片1繪制出整個(gè)圖片,圖片2繪制出內(nèi)部的孔和最外圍的邊界.
cvSub(src1,src2,dst)兩個(gè)圖片相減dst=src1-src2.新得到的圖片進(jìn)行輪廓檢測(cè),可排除0,4,6,8內(nèi)部孔的干擾,如圖5所示.
cvBoundingRect(contours, 0)獲取所有輪廓的矩形框信息,該函數(shù)返回CvRect類型的數(shù)據(jù),用循環(huán)將所有輪廓的矩形框信息存儲(chǔ)到CvRect數(shù)組中.檢測(cè)該數(shù)組中所有矩形框的長(zhǎng)寬,快遞單上的信息為印刷體數(shù)字,每個(gè)數(shù)字的長(zhǎng)寬只有細(xì)微差異,排除具有巨大差異的矩形框,得到包含每個(gè)數(shù)字的矩形框.序列中輪廓的排序是隨機(jī)的,獲取的矩形框也是隨機(jī)的,根據(jù)矩形框的左上頂點(diǎn)的坐標(biāo)進(jìn)行矩形框排序.
cvSetImageROI(img,rect[i])根據(jù)矩形框數(shù)組設(shè)定圖像的感興趣區(qū)域.cvCopy(img,roiimg[i])將所有提取出的感興趣圖片放到圖片數(shù)組中,該數(shù)組中包含了已經(jīng)按順序分割好的字符.
圖4 內(nèi)輪廓
圖5 外輪廓
本文的數(shù)字字符分割方法與以往多方面檢測(cè)分割方法比速度較快,與低谷投影檢測(cè)法比較精度較高.
2)漢字字符分割
漢字字符分割,由于漢字本身的復(fù)雜性,并不適合上述方法.采用低谷投影法進(jìn)行漢字字符分割即列掃描.檢測(cè)到一列的像素都為黑色時(shí),該列為分割點(diǎn).具體過(guò)程為獲取圖片的行列長(zhǎng)度,雙循環(huán)遍歷整個(gè)圖片的像素,當(dāng)行不變時(shí)統(tǒng)計(jì)每列像素為黑的像素?cái)?shù),當(dāng)其中一列都為黑時(shí),記錄下來(lái),即為分割點(diǎn).用Opencv中的庫(kù)函數(shù)histogramImage繪制圖片的直方圖,可直觀的看出分界線,如圖6所示圖中的低谷即為分割點(diǎn).
圖6 直方圖
2.2.3歸一化
字符分割后,需進(jìn)行歸一化處理,得到大小相同的圖片.用Opencv中cvResize (src,dst, CV_INTER_LINEAR)實(shí)現(xiàn).src為源圖像,dst為目標(biāo)尺寸大小,CV_INTER_LINEAR表示線性插值法,dst的像素值由原圖像附近的4(2×2范圍)個(gè)臨近像素的線性加權(quán)計(jì)算,權(quán)重由這4個(gè)像素到精確目標(biāo)點(diǎn)的距離確定.除此之外還有區(qū)域差值,用dst中新的像素點(diǎn)覆蓋原來(lái)的像素點(diǎn),求取覆蓋區(qū)域的平均值.最近鄰插值,dst中各點(diǎn)的像素值設(shè)為原圖像中與其距離最近的點(diǎn)的像素值[5].本文采用線性插值法.圖片歸一化后方便后續(xù)的特征提取與字符識(shí)別.
2.3 特征提取
2.3.1數(shù)字特征提取
1)統(tǒng)計(jì)特征
本文選取的是數(shù)字的Hu不變矩.矩是對(duì)輪廓上所有點(diǎn)積分運(yùn)算(即求和運(yùn)算)得到的一個(gè)特征.輪廓的矩可定義如下:
(1)
p為x維度上的矩,q為y維度上的矩.在實(shí)際應(yīng)用中多使用歸一化的矩.本程序用歸一化的中心矩.中心矩定義如下:
xavg=m1B/mBB,yavg=mB1/mBB
(2)
xavg和yavg表示圖片重心.歸一化矩是每個(gè)矩都除以m00的一個(gè)冪.歸一化中心矩定義如下:
(3)
Hu矩是從歸一化中心矩計(jì)算而來(lái),具有平移,旋轉(zhuǎn),縮放不變性.Hu矩共有七個(gè).用該矩作為特征向量?jī)?yōu)點(diǎn)是速度快,缺點(diǎn)是識(shí)別率低,但對(duì)于簡(jiǎn)單的快遞單上的印刷體電話號(hào)碼的識(shí)別效果較好[6].用OpenCV中的庫(kù)函數(shù)cvMatchShapes(object1,object2,method,0)進(jìn)行Hu矩匹配.method表示矩計(jì)算方法,當(dāng)method為CV_CONTOURS_MATCH_11,公式如下:
(4)
2)結(jié)構(gòu)特征
本文選取的數(shù)字結(jié)構(gòu)特征為交叉點(diǎn),凸缺陷,輪廓樹(shù)編碼.
交叉點(diǎn)特征.首先提取水平交叉點(diǎn).把數(shù)字平分為上中下三部分,如圖7所示.水平方向兩條直線穿過(guò)圖片[7].掃描這兩條直線所覆蓋的圖片像素,當(dāng)像素由1變0時(shí)記錄一個(gè)交點(diǎn),由此可得到一對(duì)數(shù)值.同理垂直方向也會(huì)得到一組數(shù)值.掃描像素的方法應(yīng)用雙循環(huán)遍歷圖片的像素.外層循環(huán)獲取第j行的首地址,以指針數(shù)組的形式存儲(chǔ)整行地址.內(nèi)層循環(huán)直接根據(jù)指針地址獲得像素值.
圖7 交點(diǎn)
凸缺陷特征.首先計(jì)算一個(gè)輪廓的凸包,然后計(jì)算其凸缺陷.如圖8所示,數(shù)字周圍黑色的細(xì)線畫出了凸包,a,b,c標(biāo)出的格子區(qū)域是數(shù)字的輪廓相對(duì)于凸包的凸缺陷 ,如所看到的這些凸缺陷表現(xiàn)出了數(shù)字的不同特征.Opencv提供了三個(gè)關(guān)于凸包和凸缺陷的重要函數(shù).CvCheckContoirConvexity()檢測(cè)輪廓是否為凸.cvConvexHull2()計(jì)算已知輪廓的凸包,該函數(shù)已點(diǎn)的形式返回凸包.CvCOnvexityDefects()根據(jù)輪廓,凸包計(jì)算出凸缺陷序列.
圖8 凸缺陷
輪廓樹(shù)是描述一個(gè)特定形狀內(nèi)各部分的等級(jí)關(guān)系.從一個(gè)輪廓?jiǎng)?chuàng)建輪廓樹(shù)是從底端到頂端的.輪廓上的每個(gè)點(diǎn)都不是完全和它的相鄰點(diǎn)共線的,搜索三角形突出的周邊形狀,每個(gè)三角形被一條線段代替,線段通過(guò)連接非相鄰的兩點(diǎn)連接得到,每替換一次輪廓的頂點(diǎn)數(shù)減1并且輪廓樹(shù)多一個(gè)節(jié)點(diǎn).如果這樣的三角形的兩側(cè)為原始邊,那么通過(guò)這兩條邊得到的線段為輪廓樹(shù)的葉子節(jié)點(diǎn).這個(gè)過(guò)程最終把一個(gè)物體的外形減為一個(gè)四邊形,該四邊形被剖開(kāi)得到的三角形為根節(jié)點(diǎn)的兩個(gè)子節(jié)點(diǎn)[8].具體過(guò)程見(jiàn)圖9.Opencv提供了獲取輪廓樹(shù)和對(duì)比兩個(gè)輪廓樹(shù)的函數(shù).
2.3.2漢字特征提取
漢字本身比數(shù)字的結(jié)構(gòu)復(fù)雜的多.本文采用多特征融合的方法[9].包括Harris角點(diǎn)檢測(cè),SURF特征檢測(cè),ORB特征檢測(cè).
Harris角點(diǎn)檢測(cè)是一種基于灰度圖像的角點(diǎn)檢測(cè)算法.用局部小窗口在圖像上移動(dòng),當(dāng)向各方向移動(dòng)窗口內(nèi)的圖像灰度值均明顯變化時(shí),窗口內(nèi)包含角點(diǎn).即角點(diǎn)是圖像局部曲率突變的點(diǎn)[8].設(shè)當(dāng)窗口平移量為(u,v)時(shí)窗口內(nèi)圖像的灰度變化量為E(u,v),可得如下所示:
(1)邊三角形A,B,C跟三角形D (2)線段來(lái)源圖9 輪廓樹(shù)
M為每點(diǎn)周圍小窗口的二階導(dǎo)數(shù)圖像的自相關(guān)矩陣.對(duì)角點(diǎn)的檢測(cè)改為對(duì)M的特征值的分析,如果M的兩個(gè)特征值為大數(shù)值正數(shù),該點(diǎn)為角點(diǎn).Opencv基于此提供了cornerHarris函數(shù)來(lái)對(duì)圖像進(jìn)行角點(diǎn)檢測(cè),輸出為已對(duì)源圖像的角點(diǎn)標(biāo)記好的目標(biāo)圖像.
SURF特征檢測(cè)算法是Sift算法的加速版.Sift算法在圖像的空間尺度中尋找極值點(diǎn),并提取出其位置、尺度、旋轉(zhuǎn)不變量.Sift算法的關(guān)鍵是建立一幅圖像的金字塔,在每一層進(jìn)行高斯濾波并求取圖像差(DOG)進(jìn)行特征點(diǎn)的提取,而Surf則用Hessian Matrix進(jìn)行特征點(diǎn)提取.Hessian矩陣是Surf算法的核心.Opencv中有三個(gè)函數(shù)實(shí)現(xiàn)這個(gè)算法.
ORB算法是在FAST關(guān)鍵點(diǎn)檢測(cè)和BRIEF特征上實(shí)現(xiàn).FAST算法是檢測(cè)候選特征點(diǎn)周圍一圈的像素值,如果候選點(diǎn)周圍領(lǐng)域內(nèi)有足夠多的像素點(diǎn)與該候選點(diǎn)的灰度值差別夠大,則認(rèn)為是一個(gè)特征點(diǎn).BRIEF描述子是在特征點(diǎn)附近隨機(jī)選取若干點(diǎn)對(duì),將這些點(diǎn)對(duì)的灰度值的大小組合成一個(gè)二進(jìn)制串,這個(gè)特征串即為BRIEF描述子[10].ORB算法解決了BRIEF描述子的旋轉(zhuǎn)不變性且速度較快.Opencv中ORB算法已被實(shí)現(xiàn),可直接使用.
2.4 字符識(shí)別
數(shù)字識(shí)別.本文對(duì)數(shù)字提取的三個(gè)特征,Opencv中有自帶的函數(shù)進(jìn)行匹配.首先建立模板庫(kù),統(tǒng)一模板庫(kù)內(nèi)數(shù)字圖像的大小.其次對(duì)模板庫(kù)內(nèi)的所有圖像進(jìn)行以上三個(gè)特征的檢測(cè),分別確定出數(shù)字0~9的三個(gè)特征檢測(cè)的范圍.再檢測(cè)示例數(shù)字的三個(gè)特征,與模板中的值進(jìn)行綜合比較最接近哪個(gè)即為哪個(gè)數(shù)字.
漢字識(shí)別.本文的漢字特征是基于多個(gè)特征提取的,識(shí)別方法用Opencv構(gòu)建BP神經(jīng)網(wǎng)絡(luò)根據(jù)之前提取的三個(gè)特征進(jìn)行樣本訓(xùn)練.目前Opencv可以在Visual C++下構(gòu)建BP神經(jīng)網(wǎng)絡(luò)但在Android系統(tǒng)下僅可以通過(guò)jni調(diào)用封裝好的Opencv的C++代碼,所以在Android系統(tǒng)下用Opencv構(gòu)建BP神經(jīng)網(wǎng)絡(luò)還有待研究.
本文研究快遞單上的姓名和電話識(shí)別,區(qū)別之前掃描整張圖片,只提取圖片的兩個(gè)重要部分進(jìn)行識(shí)別,提高了識(shí)別時(shí)間和識(shí)別精度.針對(duì)數(shù)字分割本文提出一種基于輪廓檢測(cè)的數(shù)字分割方法,提高了分割速度.字符識(shí)別本文采用多特征融合的方法,提高了識(shí)別效率.基于Opencv開(kāi)發(fā)軟件系統(tǒng)可節(jié)省很多時(shí)間.相信該研究隨著快遞產(chǎn)業(yè)的蓬勃發(fā)展將具有廣泛的應(yīng)用前景.
[1] 晁 越, 李中健, 黃士飛. OpenCV圖像處理編程研究[J].電子設(shè)計(jì)工程, 2013, 21(10): 175-177.
[2] HOWSE J. Android OpenCV 應(yīng)用程序設(shè)計(jì)[M]. 北京: 清華大學(xué)出版社, 2015. 21-64.
[3] LAGANIERE R. OpenCV2 Computer.Opencv2視覺(jué)編程手冊(cè) [M]. 北京: 科學(xué)出版社, 2013. 30-53.
[4] 張智豐, 張亞榮, 裴志利. OpenCV耦合人機(jī)交互的手機(jī)表面目標(biāo)檢測(cè)定位研究[J]. 組合機(jī)床與自動(dòng)化加工技術(shù), 2015(3): 67-70.
[5] 朱燕敏. 基于OpenCV的視頻字幕識(shí)別系統(tǒng)研究與實(shí)現(xiàn)[D].長(zhǎng)春: 吉林大學(xué), 2014. 11-22.
[6] GONZALEZ R C, WOODS R E. 數(shù)字圖像處理[M]. 北京: 電子工業(yè)出版社, 2007.
[7] 樊可霞, 周一軍, 涂 煊. 基于OpenCV的社??ㄌ?hào)碼識(shí)別算法的研究[J]. 信息技術(shù), 2014(3): 175-178.
[8] BRADSKI G, KAEHLER A.學(xué)習(xí) OpenCV[M]. 北京: 清華大學(xué)出版社, 2009. 246-279.
[9] 張 震, 楊 曉. 基于OpenCV實(shí)現(xiàn)多特征融合的移動(dòng)車牌定位算法[J]. 計(jì)算機(jī)應(yīng)用與軟件, 2014, 31(4): 289-292.
[10] 毛云星, 冷雪飛. Opencv3編程入門[M]. 北京: 電子工業(yè)出版社, 2015.
Study on recognition character in express list by mobile phone camera based on OpenCV
HU Wen, MA Ling-yu
(School of Computer and Information Engineering, Harbin University of Commerce, Harbin 150028, China)
In this paper, a system of recognition character in express list on the Android mobile was designed based on OpenCV. Identification content is mainly divided into telephone numbers recognition and names recognition. Mobile phone was used to take a photo of express list and draw two rectangular boxes on the screen. According to the perimeter area of rectangular box, the phone numbers and the names area were determined, and the two parts of picture were extracted. The two pictures were grayed, binarized, morphology processed and then character segmented, normalization processed. In order to increase the speed of digital divide, a segmentation method was presented based on contour detection. Finally, according to the different characters of the numbers and the Chinese characters, different recognition methods were selected for the character recognition.
character recognition; openCV; Android; express listh recognition
2015-04-07.
胡 文(1957-),男,博士,教授,研究方向:嵌入式設(shè)計(jì).
O177
A
1672-0946(2015)05-0564-05
哈爾濱商業(yè)大學(xué)學(xué)報(bào)(自然科學(xué)版)2015年5期