接着昨天的工作,把最后一部分識別講完。
關於字符識別這塊,一種最省事的辦法是匹配識別,將所得的字符和自己的標准字符庫相減,計算所得結果,值最小的即為識別的結果。不過這種方法是在所得字符較為標准的情況,由於眾多因素影響,切割出來的字符往往不是標准的,因此識別效果也不好。本次采用的BP神經網絡方法,至於像其他的分類器方法,沒有嘗試,這里就不說了。
利用神經網絡的方法的思路也比較清晰,將已有的字符庫輸入到神經網絡的輸入口進行訓練,然后用訓練好的神經網絡對待識別的字符繼續識別,輸出識別結果。matlab里面已經集成好神經網絡,直接調用即可。
這里說明一下,考慮到減小輸入量,這里把輸入的字符划分為八行四列,計算每塊的總數,然后把這些數作為樣本輸入到神經網絡。
字符識別部分代碼:
for i=1:136 ii=int2str(i); fname=strcat('D:\1_2學習\圖像處理\車牌識別\matlab_car_plate-recognization\char_result\character_test\cha&num\',ii,'.bmp'); image=imread(fname); change_image=catch2chi2character(image); P(:,i)=change_image; end T = [eye(34) eye(34) eye(34) eye(34)]; alphabet = P; targets = T; [R,Q] = size(alphabet); [S2,Q] = size(targets); S1=20;%20 purelin tansig net = newff(minmax(alphabet),[S1,S2],{ 'purelin' 'purelin' },'trainscg','learngdm');%trainscg traingdx net.inputWeights{1,1}.initFcn ='randnr'; net.layerWeights{2,1}.initFcn ='randnr'; net.performFcn = 'sse'; net.trainParam.goal = 0.1; net.trainParam.show = 20; net.trainParam.epochs = 10000; net.trainParam.mc = 0.95; net.trainparam.lr=0.015;%0.01 %設置學習速率 P = alphabet; T = targets; [net,tr] = train(net,P,T);%訓練好的神經網絡
函數catch2chi2character:
function lett=catch2chi2character(I1) %% 訓練樣本前期處理 % bw_7050=imresize(I1,[32 16],'nearest');%將圖片統一划為50*25大小 [m n]=size(I1); bw_7050=I1; % figure,imshow(I1); histrow=sum(bw_7050'); %計算水平投影 histcol=sum(bw_7050); %計算豎直投影 for i=1:m if(histrow(i)>0) row_x=i; break; end end for i=1:n if(histcol(i)>0) col_x=i; break; end end for i=n:-1:1 if(histcol(i)>0) col_y=i; break; end end for i=m:-1:1 if(histrow(i)>0) row_y=i; break; end end picture(:,:)=bw_7050(row_x:row_y,col_x:col_y); bw_7050=imresize(picture,[32 16],'nearest');%將圖片統一划為50*25大小 % figure,imshow(bw_7050) for cnt=1:8%粗網格特征作為輸入矢量 for cnt2=1:4 Atemp=sum(bw_7050((cnt*4-3:cnt*4),(cnt2*4-3:cnt2*4))); %獲取字符的統計特征 lett((cnt-1)*4+cnt2)=sum(Atemp); end end ma=max(max(lett)); mi=min(min(lett)); lett=(lett-mi)/(ma); histrow=sum(bw_7050'); %計算水平投影 histcol=sum(bw_7050); %計算豎直投影 lett=lett'; end
字符識別:
for i=2:7 ii=int2str(i); fname=strcat('D:\1_2學習\圖像處理\車牌識別\matlab_car_plate-recognization\char_result\',ii,'.bmp'); image=imread(fname); [size_x size_y]=size(image); max_num=max(max(image)); min_num=min(min(image))-1; for ix=1:size_x for ij=1:size_y if image(ix,ij)>min_num+(max_num-min_num)/10 image(ix,ij)=255; else image(ix,ij)=0; end end end % I2 = bwmorph(image,'remove'); %提取邊緣 % image_main = bwmorph(I2,'skel',Inf); %骨架化 % figure,imshow(image) change_image=catch2chi2character(image); Ptest(:,i-1)=change_image; end [a,b]=max(sim(net,Ptest)); disp(b); liccode=char(['A':'H' 'J':'N' 'P':'Z' '0':'9']); %建立自動識別字符代碼表 for i=1:6 str(i)=liccode(b(i)); end
漢字識別和字符差不多,這里就不貼上去了。。
總結一下:采用這種方式,基本上字符都可以識別出來。考慮到樣本采集、數字處理過程中對字符的影響,像字符O和D,一定情況下無法識別。這也是程序所存在的問題,即沒有對相似的字符進行區分。。漢字也存在這種情況,左右結構的也沒有考慮。因此想做到完整還有好多工作要做。。
這個是簡單的GUI結果圖:

總結一下:
1.獲取的車牌規格要統一,否則很難把握好車牌定位這塊。
2.切割字符關鍵在於讓程序確定在車牌的位置,這樣切割起來就比較方便了。不足的地方在於從定位到切割這塊要耗費一點時間,感覺是自己程序太過復雜?不知道有沒比較簡單的思路沒。
3.字符識別想要做的好,工作還是比較多的。這次神經網絡訓練過程中參數設置很重要,土辦法是去試,不知道有沒有科學點的辦法。。
4.算是對這段時間來的一個總結,里面涉及到的內容還是很多的,多看看模式識別方面的知識。
結束。。2015-5-11
