天天看點

【漢字識别】基于matlab GUI漢字精準識别【含Matlab源碼 2197期】

一、漢字識别簡介

漢字作為中華民族文化的資訊載體,與人們的日常學習和工作密不可分。在網絡資訊交流中,需要輸入大量的中文資訊 ,重複、單調的傳統鍵盤手工輸入方式效率低下,已逐漸不能滿足迅速發展的資訊化時代。而傳統的模闆比對法對于漢字的識别率不高,作者提出一種基于SVM的多特征手寫漢字識别技術,可大幅提高漢字的識别率以及錄入效率。

1 系統流程

首先對漢字圖像進行灰階化、二值化、形态學處理、傾斜校正、字元分割和歸一化、細化等圖像預處理操作,再對字元進行特征提取,最後采用SVM算法構造分類器。系統識别流程如圖1所示。

2 SVM原理

SVM(Support Vector Machines)是建立在統計學習理論的VC維理論和結構風險最小原理基礎上的,面對小樣本問題,其能表現出良好的學習能力,并能做到與資料的維數無關 。

【漢字識别】基于matlab GUI漢字精準識别【含Matlab源碼 2197期】

圖1 漢字識别流程圖

SVM方法是從線性可分情況下的最優分類超平面提出的,所謂最優分類超平面就是要求分類平面不但能将兩類無錯地分開,且要使分類平面兩側樣本之間的間隔最大[4] 。過兩類樣本中離最優分類超平面最近的點,且平行于最優分類超平面的分類超平面上的訓練樣本稱為支援向量[3] 。設樣本集(xi,yi),xi∈Rd,yi∈{1,-1},i=1,…,n。線上性可分情況下,則可找到權向量w,使兩類間隔最大,即‖w‖2最小,同時滿足

【漢字識别】基于matlab GUI漢字精準識别【含Matlab源碼 2197期】

其中,i=1,…,n,n表示分類樣本的數目。

為求解上述優化問題,引入拉格朗日函數

【漢字識别】基于matlab GUI漢字精準識别【含Matlab源碼 2197期】

式中,α為拉格朗日乘子,αi≥0。

通過拉格朗日函數L分别對w,b求偏導,并令偏導數值為0,結果代入超平面方程得到最優分類函數

【漢字識别】基于matlab GUI漢字精準識别【含Matlab源碼 2197期】

漢字識别的分類對象是非線性不可分的。對于不可分問題,可通過引入非負松弛變量ξi加以解決,則限制條件變為

【漢字識别】基于matlab GUI漢字精準識别【含Matlab源碼 2197期】

式中,C是懲罰因子,用來調節分類的準确率與泛化能力[5] 。拉格朗日乘子α的取值範圍變為0≤αi≤C。對于低維空間的非線性可分問題,可通過引入核函數解決。原始資料的核函數變換為(xi·xj)→K(xi·xj),則非線性情況下,使用核函數之後對應的分類函數為

【漢字識别】基于matlab GUI漢字精準識别【含Matlab源碼 2197期】

3 關鍵技術

3.1 質心特征的提取

質心特征是字元筆劃分布的展現。将二值圖像轉化成點陣形式,黑色像素點用“1”表示,白色像素點用“0”表示。設c(i,j)表示漢字點陣,質心計算如下:水準質心

【漢字識别】基于matlab GUI漢字精準識别【含Matlab源碼 2197期】

垂直質心

【漢字識别】基于matlab GUI漢字精準識别【含Matlab源碼 2197期】

式中,i表示該點陣的行;j表示該點陣的行。

3.2 筆劃特征的提取

漢字由橫、豎、撇、捺4種基本筆劃構成,筆劃的構成展現了漢字的基本形态[7] 。下面對4種基本筆劃進行提取。

(1)橫、豎筆劃的提取。橫筆劃中所有的像素點具有同一縱坐标,而豎筆劃中所有的像素點具有同一橫坐标[8] 。其特征明顯,提取算法也基本相同。本文提出一種将細化後圖像與原圖像相結合的筆劃提取方法,方法如下:1)對細化後圖像進行自上而下、從左往右的水準掃描,若同一縱坐标上連續的黑點個數大于或等于2,則記下這些黑點的坐标;2)對原圖像進行水準掃描,若這些黑點依然連續,則說明這些黑點構成一個橫筆劃,橫筆劃數量加1;3)重複第1、2步;4)當細化後圖像水準掃描全部完成時,記下橫筆劃數。同理,對細化後圖像進行自左向右而下、從上往下的豎直掃描,可得到豎筆劃數;

(2)撇、捺筆劃的提取。1)将細化後圖像中的橫、豎筆劃删除,降低圖像的複雜性;2)自上而下、從左往右的水準掃描細化後圖像,如果第i行掃描到黑點,記下該黑點的縱坐标yi;3)跳出對第i行的掃描,依次掃描第i+1,i+2,i+3,…,20行,記下首次掃描到黑點的縱坐标y2,y3,y4,…,y21-i;4)比較y2,y3,y4,…,y21-i,若滿足yj+1≤yj≤yj+1+1∪yj+2≤yj≤yj+2+2,j∈{1,2,3,…,20-i},則這些點構成一撇筆劃,撇筆劃數量+1,若滿足yj≤yj+1≤yj+1∪yj≤yj+2≤yj+2,j∈{1,2,3,…,20-i},則這些點構成一捺筆劃,捺筆劃數量+1;5)删除已提取的撇、捺筆劃,重複第2)~4)步;6)掃描結束後,記下撇、捺筆劃數。

3.3 特征點的提取

漢字筆劃特征點主要有端點、折點、歧點、交點[9] 。端點是筆劃的起點或終點(不與其他筆劃相接);折點是指筆劃方向出現顯著變化的點;歧點是三叉點,要求其中兩個筆端的分支方向相同;交點是四叉點,且有兩對等的對頂角。自左向右、自上而下的對二值圖像進行掃描,統計各筆劃特征點的個數。

3.4 構造分類器

分類器是整個字元識别系統的核心,作者采用SVM來構造分類器。SVM方法解決的是二分類問題,為使其能夠應用于10個漢字的分類,需構造多值分類器。将采用一對一方法構造分類器。對于10個不同的漢字,一對一方法需要構造(C210即45)個分類器,分類結束後選取得票數最多的類别作為最終的識别結果。

二、部分源代碼

function varargout = main(varargin)
% 開始初始化代碼 - DO NOT EDIT
 gui_Singleton = 1;
 gui_State = struct(‘gui_Name’, mfilename, …
 ‘gui_Singleton’, gui_Singleton, …
 ‘gui_OpeningFcn’, @main_OpeningFcn, …
 ‘gui_OutputFcn’, @main_OutputFcn, …
 ‘gui_LayoutFcn’, [] , …
 ‘gui_Callback’, []);
 if nargin && ischar(varargin{1})
 gui_State.gui_Callback = str2func(varargin{1});
 endif nargout
 [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
 else
 gui_mainfcn(gui_State, varargin{:});
 end
 % 結束初始化代碼
 pause(1);
 % 執行之前主要是可見的。
 function main_OpeningFcn(hObject, eventdata, handles, varargin)
 set(handles.process,‘enable’,‘on’)% 此函數沒有輸出參數,見 OutputFcn.
 % main的選擇預設的指令行輸出
 handles.output = hObject;
 % 更新handles 結構
 guidata(hObject, handles);
 % UIWAIT 等待使用者響應 (see UIRESUME)
 % uiwait(handles.figure1);% — 這個函數的輸出傳回到指令行。
 function varargout = main_OutputFcn(hObject, eventdata, handles)
 tic
 % 獲得預設指令行輸出的把手結構
 varargout{1} = handles.output;% — 執行按鈕在pushbutton1。
 function pushbutton1_Callback(hObject, eventdata, handles)[filename pathname]=uigetfile({‘.jpg’;'.bmp’}, ‘File Selector’);
 I = imread([pathname ‘’ filename]);
 handles.I = I;
 % 更新處理結構
 guidata(hObject, handles);
 axes(handles.axes1);
 imshow(I);title(‘原始圖檔’)set(handles.process,‘enable’,‘on’)
 % — 執行過程中按下按鈕。function process_Callback(hObject, eventdata, handles)
 set(handles.edit3,‘string’,‘正在識别!請稍候…’);
 I = handles.I;
 I1=rgb2gray(I);;%rgb2gray轉換成灰階圖
 guidata(hObject, handles);
 axes(handles.axes2);
 imshow(I1);title(‘灰階圖’);
 axes(handles.axes3);
 imhist(I1);title(‘灰階圖直方圖’);
 %繼續
 pause(2);
 I2=edge(I1,‘roberts’,0.15,‘both’);
 guidata(hObject, handles);
 axes(handles.axes2);
 imshow(I2);title(‘robert算子邊緣檢測’);
 pause(2);
 se=[1;1;1];
 I3=imerode(I2,se);
 guidata(hObject, handles);
 axes(handles.axes3);
 imshow(I3);title(‘腐蝕後圖像’);
 %繼續
 pause(2);
 se=strel(‘rectangle’,[10,25]);%生成一個矩陣
 I4=imclose(I3,se);%閉運算
 guidata(hObject, handles);
 axes(handles.axes2);
 imshow(I4);title(‘平滑圖像的輪廓’);
 %繼續
 pause(2);
 I5=bwareaopen(I4,2000);%小于2000的對象都被删除
 guidata(hObject, handles);
 axes(handles.axes2);
 imshow(I5);title(‘從對象中移除小對象’);
 %繼續
 pause(2);
 [PY2,PY1,PX2,PX1]=chepai_fenge(I5);%調用分割車牌
 global threshold;
 [PY2,PY1,PX2,PX1,threshold]=chepai_xiuzheng(PY2,PY1,PX2,PX1);%調用車牌校正
 IY=I(PY1:PY2,:😅;
 Plate=I5(PY1:PY2,PX1:PX2);%使用caitu_tiqu
 global dw;
 dw=Plate;
 PX1=PX1-1;%對車牌區域的校正
 PX2=PX2+1;
 dw=I(PY1:PY2,PX1:PX2,:);
 axes(handles.axes2);
 imshow(dw),title(‘區域的校正’);
 pause(2);
 t=tic;
 guidata(hObject, handles);
 axes(handles.axes2);
 imshow(IY),title(‘水準方向合理區域’);
 axes(handles.axes3);
 imshow(dw),title(‘定位剪切後的彩色圖像’);
 pause(2);
 imwrite(dw,‘New number plate.jpg’);
 %[filename,filepath]=uigetfile(‘New number plate.jpg’,‘輸入一個定位裁剪後的車牌圖像’);
 %jpg=strcat(filepath,filename);
 a=imread(‘New number plate.jpg’);
 b=rgb2gray(a);%對定位後的車牌灰階化
 figure(3),subplot(3,2,1),imshow(b),title(‘灰階圖像’);
 g_max=double(max(max(b)));
 g_min=double(min(min(b)));
 T=round(g_max-(g_max-g_min)/2); %T 為二值化的門檻值
 [m,n]=size(b);
 d=(double(b)>=T); % d:二值圖像
 figure(3),subplot(3,2,2),imshow(d),title(‘二值圖像’);
 figure(3),subplot(3,2,3),imshow(d),title(‘均值濾波前’);
 pause(1);
 h=fspecial(‘average’,3); %均值濾波器
 d=im2bw(round(filter2(h,d)));
 figure(3),subplot(3,2,4),imshow(d),title(‘均值濾波後’);
 se=eye(2); % eye(n) returns the n-by-n identity matrix 機關矩陣
 %字元面積與車牌面積之比在(0.235,0.365)之間
 [m,n]=size(d); %如果大于0.365則對圖像進行腐蝕,如果小于0.235則對圖像進行膨脹
 if bwarea(d)/m/n>=0.365%計算面積
 d=imerode(d,se);%imerode 實作圖像腐蝕 d為待處理圖像,se是結構元素對象
 elseif bwarea(d)/m/n<=0.235
 d=imdilate(d,se);%imdilate 圖像膨脹
 end      

三、運作結果

【漢字識别】基于matlab GUI漢字精準識别【含Matlab源碼 2197期】

四、matlab版本及參考文獻

1 matlab版本

2019b

繼續閱讀