模式識別之ocr項目---(模板匹配&BP神經網絡訓練)

摘 要算法

在MATLAB環境下利用USB攝像頭採集字符圖像,讀取一幀保存爲圖像,而後對讀取保存的字符圖像,灰度化,二值化,在此基礎上作傾斜矯正,對矯正的圖像進行濾波平滑處理,而後對字符區域進行提取分割出單個字符,識別方法一是採用模板匹配的方法逐個對字符與預先製做好的字符模板比較,若是結果小於某一閾值則結果就是模板上的字符;二是採用BP神經網絡訓練,經過訓練好的net對待識別字符進行識別。最而後將識別結果經過MATLAB下的串口工具輸出51單片機上用液晶顯示出來。編程

                                                                                                                                                                 

關鍵字: 傾斜矯正,字符分割,模板匹配,BP神經網絡,液晶顯示網絡

 

 

Abstractless

In the MATLAB environmentusing USB camera capture the character images, saved as an image reading, thenread the saved character images, grayscale, binary, on this basis do tilt correction,the correction image smoothing filter, and then extract the character regionsegmentation of a single character, and then one by one using a templatematching method of character with good character template is a pre-production,if the result is less than a certain threshold, the result is a template of thecharacter. Second, the BP neural network trained by the trained net to identifythe character towards recognition The results will identify the most and thenthe serial port through the MATLAB tool output 51 under microcontroller withLCD display.異步

 

 

Keyword: Tilt correction, character segmentation,template matching, liquid crystal displayide

一 引言:函數

光學字符識別(OCR,Optical Character Recognition)是指對文本資料進行掃描,而後對圖像文件進行分析處理,獲取文字及版面信息的過程。已有30多年曆史,近幾年又出現了圖像字符識別(image character recognition,ICR)和智能字符識別(intelligent character recognition,ICR),實際上這三種自動識別技術的基本原理大體相同。工具

關於字符識別的方法有不少種,最簡單的就是模板匹配,還有根據採集到的字符用BP神經網絡或者SVM來訓練獲得結果的方式。本文主要針對模板匹配的方式,在MATLAB環境下編程實現。學習

 

二 字符圖像獲取:測試

在MATLAB下利用image acquisition toolbox獲取視頻幀,並保存圖像在工程文件夾內。攝像頭採用普通的USB攝像頭,因爲這種攝像頭拍攝的照片延時比較大,因此先用image acquisition toolbox下的對視頻進行預覽,調整出最佳的效果來,採集的圖像效果越好則識別率越高。 根據測試,實驗選擇640*480的視頻獲取窗口,顏色空間選取爲RGB空間,獲取一幀後保存爲jpg的存儲格式。

 

 

三 字符預處理

3.1字符矯正

因爲攝像頭拍攝的圖像存在必定存在的傾斜度,在分割字符區域時,應先對字符進行矯正。過程以下:

將經過攝像頭獲取的保存幀圖像灰度化,而後對其進行邊緣提取,再在1到180度角內對圖像進行旋轉,記錄下邊緣提取後的圖像在x軸方向上的投影,當x軸方向上的投影最小的時候即表示圖像中字符平行於y軸,已經完成矯正,此時記錄下旋轉的傾斜角。而後利用imrotate函數實現對字符圖像的矯正。

 

3.2 字符區域分割:

在第三步完成對字符圖像的傾斜矯正後,將圖像分別作x軸和y軸方向上的投影既能夠知道字符區域在x軸上的像素分佈範圍和y軸上的像素分佈範圍,而後對根據這個範圍對圖像作分割,在MATLAB中表示爲:

goal=I(ix1:iy1,jx1:jy1);

其中goal爲分割後的圖像,I爲分割前的圖像,ix1和ix2分別爲x軸上投影的像素範圍的起始座標值和終止座標值,iy1和iy2分別爲y軸上投影的像素範圍的起始座標值和終止座標值。

 

 

3.3 單個字體分割:

在分割獲得的字符區域圖像上,只須要作y軸上的投影就能夠知道每一個字符在y軸上的分佈區間,而後利用這個分佈區間就能夠分割出單個字符。

 

3.4 單個字體裁剪

在第五步分割出來的字符基礎上進一步對字符的像素區域進行裁剪,原理也是分別作x軸,y軸方向上的投影,求的字符的區間再作剪裁。

 

四 模板字符識別

4.1字符模板製做:

模板的要求是與要識別的字符的字體格式一致,實驗中採用word上的標準字符,經過截圖軟件截圖後按照3-6步的處理過程製做出須要的字符模板,從0到9共10個數字,A到Z共26個字母。

 

4.2 字符模板歸一化

在知足識別率的條件下,儘可能採用小模板識別能夠提神運算速度,具體的模板大小,能夠根據後面的與待識別字符的比較中調節。

 

4.3識別過程:

將待識別字符與字符模板作一樣的歸一化處理,而後遍歷與字符模板比較,處理方法爲先和字符模板作差,而後計算作差後的圖像的總像素值,若是小於每個閾值,則表示該待識別字符和該模板是同一個字符,這樣就完成了一次識別。

循環對要識別的字符作一樣的處理就能夠識別出全部的字符,將結果保存在字符串中。

 

五 BP神經網絡字符識別

BP(Back Propagation)網絡是1986年由Rumelhart和McCelland爲首的科學家小組提出,是一種按偏差逆傳播算法訓練的多層前饋網絡,是目前應用最普遍的神經網絡模型之一。BP網絡能學習和存貯大量的輸入-輸出模式映射關係,而無需事前揭示描述這種映射關係的數學方程。它的學習規則是使用最速降低法,經過反向傳播來不斷調整網絡的權值和閾值,使網絡的偏差平方和最小。BP神經網絡模型拓撲結構包括輸入層(input)、隱層(hide layer)和輸出層(outputlayer)。

BP (Back Propagation)神經網絡,即偏差反傳偏差反向傳播算法的學習過程,由信息的正向傳播和偏差的反向傳播兩個過程組成。輸入層各神經元負責接收來自外界的輸入信息,並傳遞給中間層各神經元;中間層是內部信息處理層,負責信息變換,根據信息變化能力的需求,中間層能夠設計爲單隱層或者多隱層結構;最後一個隱層傳遞到輸出層各神經元的信息,經進一步處理後,完成一次學習的正向傳播處理過程,由輸出層向外界輸出信息處理結果。當實際輸出與指望輸出不符時,進入偏差的反向傳播階段。偏差經過輸出層,按偏差梯度降低的方式修正各層權值,向隱層、輸入層逐層反傳。周而復始的信息正向傳播和偏差反向傳播過程,是各層權值不斷調整的過程,也是神經網絡學習訓練的過程,此過程一直進行到網絡輸出的偏差減小到能夠接受的程度,或者預先設定的學習次數爲止。

  BP神經網絡模型BP網絡模型包括其輸入輸出模型、做用函數模型、偏差計算模型和自學習模型。

  (1)節點輸出模型

  隱節點輸出模型:Oj=f(∑Wij×Xi-qj) (1)

  輸出節點輸出模型:Yk=f(∑Tjk×Oj-qk) (2)

  f-非線形做用函數;q -神經單元閾值。

  圖1 典型BP網絡結構模型

  (2)做用函數模型

  做用函數是反映下層輸入對上層節點刺激脈衝強度的函數又稱刺激函數,通常取爲(0,1)內連續取值Sigmoid函數: f(x)=1/(1+e) (3)

  (3)偏差計算模型

  偏差計算模型是反映神經網絡指望輸出與計算輸出之間偏差大小的函數:

  Ep=1/2×∑(tpi-Opi) (4)

  tpi- i節點的指望輸出值;Opi-i節點計算輸出值。

  (4)自學習模型

  神經網絡的學習過程,即鏈接下層節點和上層節點之間的權重拒陣Wij的設定和偏差修正過程。BP網絡有師學習方式-須要設按期望值和無師學習方式-只需輸入模式之分。自學習模型爲

  △Wij(n+1)= h ×Фi×Oj+a×△Wij(n) (5)

h -學習因子;Фi-輸出節點i的計算偏差;Oj-輸出節點j的計算輸出;a-動量因子。

 

5.1 訓練樣本製做:

在不一樣分辨率和不一樣傾斜角度下分別採集幾組圖片做爲訓練樣本,本實驗爲了節省計算時間,根據須要只作12345ABCDE這10個字符的識別,所以只各採集了10組數據。不一樣分辨率下5組,不一樣傾斜角度下5組。而後按照2-4上的操做過程的對字符進行處理,得到32*32大小的訓練樣本共100個。

 

5.2設計BP神經網絡

利用MATLAB下的神經網絡工具設計一個,以字符圖像的x軸y軸像素值爲輸入特徵做爲輸入層的輸入;以logsig函數做爲隱含層,隱含層設計節點25個,輸出層就是預期的結果,共十種可能,因此有輸出層有十種輸出。

net=newff(pr,[25 1],{'logsig' 'purelin'},'traingdx', 'learngdm');

net.trainParam.epochs=250;%訓練步數

net.trainParam.goal=0.001;%目標偏差

net.trainParam.show=10;%系統每10步顯示一次訓練偏差的變化曲線

net.trainParam.lr=0.05; %學習速度

net=train(net,p,t)%訓練

並保存訓練結果save name net

 

5.3 BP訓練

首先對待識別字符預處理,而後讀取讀取訓練好的網絡load name net,經過sim函數對字符進行識別,結果輸出,保存在一個字符串內。

 

六 識別結果發送下位機

利用MTLAB下的串口工具發送識別出的結果給下位機,下位機爲51核的單片機,而後在單片機內通過程序處理驅動LM1602液晶顯示結果。

 

5.1 MATLAB下的串口工具:

在Matlab6.0以上版本中新增的設備控制工具條(instrument control toolbox)具有支持計算機與其它具備串口的外部設備之間的通訊的功能。其特色以下:

a、支持基於串行接口(RS-23二、RS-42二、RS-485)的通訊;

b、通訊數據支持二進制和文本(ASCII)兩種方式;

c、支持異步通訊和同步通訊;

d、支持基於事件驅動的通訊(亦稱中斷方式)。

 

5.2 下位機處理

5.2.1主控電路

主控芯片採用基於51核的STC12A50S8,51單片機是對目前全部兼容Intel 8031指令系統的單片機的統稱。

·8位CPU·4kbytes 程序存儲器(ROM)(52爲8K)

  ·256bytes的數據存儲器(RAM)(52有384bytes的RAM)

  ·32條I/O口線·111條指令,大部分爲單字節指令

  ·21個專用寄存器

  ·2個可編程定時/計數器·5箇中斷源,2個優先級(52有6個)

  ·一個全雙工串行通訊口

  ·外部數據存儲器尋址空間爲64kB

  ·外部程序存儲器尋址空間爲64kB

  ·邏輯操做位尋址功能·雙列直插40PinDIP封裝

  ·單一+5V電源供電

  CPU:由運算和控制邏輯組成,同時還包括中斷系統和部分外部特殊功能寄存器;

  RAM:用以存放能夠讀寫的數據,如運算的中間結果、最終結果以及欲顯示的數據;

  ROM:用以存放程序、一些原始數據和表格;

  I/O口:四個8位並行I/O口,既可用做輸入,也可用做輸出;

  T/C:兩個定時/記數器,既能夠工做在定時模式,也能夠工做在記數模式;

  五個中斷源的中斷控制系統;

  一個全雙工UART(通用異步接收發送器)的串行I/O口,用於實現單片機之間或單片機與微機之間的串行通訊;

  片內振盪器和時鐘產生電路,石英晶體和微調電容須要外接。最高振盪頻率爲12M。

5.2.2 液晶顯示電路

實驗中顯示模板採用1602字符型液晶,它是工業字符型液晶,可以同時顯示16x02即32個字符。602液晶模塊內部的字符發生存儲器(CGROM)已經存儲了160個不一樣的點陣字符圖形,這些字符有:阿拉伯數字、英文字母的大小寫、經常使用的符號、和日文假名等,每個字符都有一個固定的代碼,好比大寫的英文字母「A」的代碼是01000001B(41H),顯示時模塊把地址41H中的點陣字符圖形顯示出來,咱們就能看到字母「A」。

由於1602識別的是ASCII碼,試驗能夠用ASCII碼直接賦值,在單片機編程中還能夠用字符型常量或變量賦值,如'A’。

5.2. 3 串口通訊圖:

因爲單片機的串口輸出爲TTL電平,與PC機通訊是須要採用轉換爲RS232電平,實驗中使用美信公司的MAX232芯片。它是美信公司專門爲電腦的RS-232標準串口設計的單電源電平轉換芯片,使用+5v單電源供電。

 

七 總結:

本實驗完成了usb攝像頭的視頻幀圖像採集,並對採集圖像進行了數字圖像處理,採用模板匹配和BP神經網絡訓練的方式對字符進行識別,並利用MATLAB下的串口工具和下位機單片機通訊,發送識別結果顯示在字符液晶上。

試驗中存在的問題:一是,對圖像字符進行分割的時候,若是圖像採集的分辨率太低的話會出現字符斷裂的狀況,這時候要作的就是對字符進行連通域檢測。二是在作本實驗的程序都是針對特定字符進行處理的,沒有作自適應的字符個數檢測。三是BP訓練樣本數太少,因此訓練後的網絡對字符的識別結果並很差。這些都須要後續的改進。

 

八參考文獻:

[ 1]  王鵬.基於神經網絡的手寫體字符識別 北京工業大學 , 2002

[ 2]  閆雪梅 ,王曉華 ,夏興高. 基於 PCA和 BP神經網絡算法的車牌字符識別 北京理工大學信息科學技術學院 2007

[ 3]  金城 二維圖像特徵研究 浙江大學博士論文 2006

[ 4]  MATLAB2010R image processing tools

 

附錄:

MATLAB程序:

1、模板匹配:

%%%%%%%%%%%%%%%%%模板字符識別1.0%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%朱本福
%利用usb攝像頭在MATLAB中經過image acquisition toolbox
%獲取一幀圖片並保存爲ocr.jpg在讀取圖片進行處理,採用模板匹配的
%方式進行識別,模板爲根據操做製做的,最後將結果經過串口發送出去顯示在單片機上
%MATLAB2010下開發
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
clc;
clear all;
close all;
vid = videoinput('winvideo', 1, 'YUY2_640x480');%視頻獲取字符圖像
src = getselectedsource(vid);
vid.FramesPerTrigger = 1;
preview(vid);%預覽
start(vid) ;
vid.ReturnedColorspace = 'rgb';
vid.FramesPerTrigger =1;
imaqmem(10000000);
frame = getsnapshot(vid) ;%獲取一幀
figure(1);
imshow(frame)
imwrite(frame,'ocr.jpg','jpg');%保存該幀圖片

stop(vid);
delete(vid);


I=imread('ocr.jpg');%讀取測試圖片
[m,n,z]=size(I)
figure(1);
imshow(I);title('測試圖片')
I1=rgb2gray(I);
    imwrite(I1,'I1.jpg');%保存二值化圖像
figure(2);
imshow(I1);%顯示二值化圖像
%figure(3);
%imhist(I1);


Ic = imcomplement(I1);%取反
    imwrite(Ic,'Ic.jpg');
figure(33);imshow(Ic);
BW = im2bw(Ic, graythresh(Ic));%二值化
    imwrite(BW,'BW.jpg');
figure(5), imshow(BW); 


bw=edge(I1,'prewitt');%邊緣提取
    imwrite(bw,'bw.jpg');
figure(32);imshow(bw);
theta=1:180;
[R,xp]=radon(bw,theta);
[I0,J]=find(R>=max(max(R)));%J記錄了傾斜角
qingxiejiao=90-J
goal1=imrotate(BW,qingxiejiao,'bilinear','crop');
    imwrite(goal1,'goal1.jpg');
figure,imshow(I1);title('correct image');



%中值濾波
goal3=medfilt2(goal1,[3,3]);
figure(19), imshow(goal3);


goal3=medfilt2(goal3,[3,3]);
    imwrite(goal3,'goal3.jpg');
figure(19), imshow(goal3);


%求解X方向的投影像素範圍
[ix1,iy1]=xfenge(goal1)


%求解y方向的投影像素範圍
[jx1,jy1]=yfenge(goal1)


%字符區域分割:
goal4=goal3(ix1:iy1,jx1:jy1);
    imwrite(goal4,'goal4.jpg');
figure(21);imshow(goal4);
[m,n]=size(goal4)
%[L,num] = bwlabel(goal4,8);%區域標記,1,2,3,4


ysum(n-1)=0;
for y=1:n-1
ysum(y)=sum(goal4(:,y));
end
%y=1:n-1;
%figure(12)
%plot(y,ysum)%畫出y方向上的像素分佈


%找出ysum分佈的幾個與y軸交點就是單個字符在y軸上分佈的區間
i=1;j=1;
for y=1:n-2
    if (ysum(y)==0)&(ysum(y+1)~=0)
        yy(i)=y
        i=i+1;
    end
    
    if (ysum(y)~=0)&(ysum(y+1)==0)
        yx(j)=y
        j=j+1;
    end
end
[m_yy,n_yy]=size(yy);%求出字符的分佈並分割
if n_yy==3 %根據n_yy和n_yx的個數及分佈區間,選擇分割區間
%segment
num1=goal4(1:m , 1:yx(1));%分割出字符1
figure(23);imshow(num1);


num2=goal4(1:m ,yy(1):yx(2));%分割出字符2
figure(24);imshow(num2);


num3=goal4(1:m ,  yy(2):yx(3));%分割出字符3
figure(25);imshow(num3);


num4=goal4(1:m ,  yy(3):n);%分割出字符4
figure(26);imshow(num4);


%[m1,n1]=size(num1)%求出各個字符的大小
%[m2,n2]=size(num2)
%[m3,n3]=size(num3)
%[m4,n4]=size(num4)
%對單個字符細分,避免字體出現大小不一致的狀況,也就是再在x軸上進行分割
[ix1,iy1]=xfenge(num1)
[ix2,iy2]=xfenge(num2)
[ix3,iy3]=xfenge(num3)
[ix4,iy4]=xfenge(num4)
num1=goal4(ix1:iy1 , 1:yx(1));
figure(23);imshow(num1);



num2=goal4(ix2:iy2 ,yy(1):yx(2));
figure(24);imshow(num2);


num3=goal4(ix3:iy3 ,  yy(2):yx(3));
figure(25);imshow(num3);


num4=goal4(ix4:iy4 ,  yy(3):n);
figure(26);imshow(num4);


imwrite(num1, 'nnum1.bmp'); 
imwrite(num2, 'nnum2.bmp'); 
imwrite(num3, 'nnum3.bmp'); 
imwrite(num4, 'nnum4.bmp'); 
end


if n_yy==4 %根據n_yy和n_yx的個數及分佈區間,選擇分割區間
    %segment
num1=goal4(1:m , yy(1):yx(1));
figure(23);imshow(num1);


num2=goal4(1:m ,yy(2):yx(2));
figure(24);imshow(num2);


num3=goal4(1:m ,  yy(3):yx(3));
figure(25);imshow(num3);


num4=goal4(1:m ,  yy(4):n);
figure(26);imshow(num4);
%[m1,n1]=size(num1)
%[m2,n2]=size(num2)
%[m3,n3]=size(num3)
%[m4,n4]=size(num4)
%對單個字符細分
[ix1,iy1]=xfenge(num1)
[ix2,iy2]=xfenge(num2)
[ix3,iy3]=xfenge(num3)
[ix4,iy4]=xfenge(num4)
num1=goal4(ix1:iy1 , yy(1):yx(1));
figure(23);imshow(num1);


num2=goal4(ix2:iy2 ,yy(2):yx(2));
figure(24);imshow(num2);


num3=goal4(ix3:iy3 ,  yy(3):yx(3));
figure(25);imshow(num3);


num4=goal4(ix4:iy4 ,  yy(4):n);
figure(26);imshow(num4);
imwrite(num1, 'nnum1.bmp'); 
imwrite(num2, 'nnum2.bmp'); 
imwrite(num3, 'nnum3.bmp'); 
imwrite(num4, 'nnum4.bmp'); 
end




for i=1:36 %將模板歸一化
    imageName=strcat(num2str(i),'.bmp');
    I = imread(imageName);
   % figure;imshow(imageName);
   M{i}=imresize(I,[16,12],'nearest');
   %figure;imshow(M{i});
end



Rchar(4)='0';
for i=1:4 
    imagenum=strcat('nnum',num2str(i),'.bmp');
    J=imread(imagenum);
     [m,n]=size(J)
    num{i}=imresize(J,[16,12],'nearest');  %待識別字符歸一化
    [m,n]=size(num{i})
    figure;imshow(num{i});
 for j=1:36   
    MM{j}=xor(num{i} , M{j});  %差分比較
   % figure;imshow(MM{j});
    dist(j)=sum(sum(MM{j}))
    
        if dist(j)<=28  %這個能夠根據dist的具體狀況選取,這裏去18分割效果不錯
        char(i)=j
        end
    end
      
    
switch char(i)%遍歷比較
         case 1 
             Rchar(i)='1' ;
         case 2 
             Rchar(i)='2';
         case 3 
             Rchar(i)='3';
         case 4
             Rchar(i)='4' ;
         case 5 
             Rchar(i)='5';
         case 6 
             Rchar(i)='6';
         case 7 
             Rchar(i)='7';
         case 8 
             Rchar(i)='8';
         case 9 
             Rchar(i)='9';
         case 10 
             Rchar(i)='0';
         case 11 
             Rchar(i)='A' ;
         case 12 
             Rchar(i)='B';
         case 13 
             Rchar(i)='C';
         case 14 
             Rchar(i)='D' ;
         case 15 
             Rchar(i)='E';
         case 16 
             Rchar(i)='F';
         case 17
             Rchar(i)='G' ;
         case 18 
             Rchar(i)='H';
         case 19 
             Rchar(i)='I';
         case 20 
             Rchar(i)='J' ;
         case 21 
             Rchar(i)='K';
         case 22 
             Rchar(i)='L';
         case 23 
             Rchar(i)='M' ;
         case 24 
             Rchar(i)='N';
        case 25 
            Rchar(i)='O';
         case 26 
             Rchar(i)='P' ;
         case 27 
             Rchar(i)='Q';
         case 28 
             Rchar(i)='R';
         case 29 
             Rchar(i)='S' ;
         case 30 
             Rchar(i)='T';
         case 31 
             Rchar(i)='U';
         case 32 
             Rchar(i)='V' ;
         case 33 
             Rchar(i)='W';
         case 34
             Rchar(i)='X';
         case 35 
             Rchar(i)='Y' ;
         case 36 
             Rchar(i)='Z';
         otherwise 
             Rchar(i)='false'   ;
     end
 end
 schar=[Rchar(1),Rchar(2),Rchar(3),Rchar(4)]
 
%schar=['4','5','A','B'] 


sport1=serial('COM4');%串口輸出字符
sport1.BaudRate=9600;
fopen(sport1);
fwrite(sport1,schar);
INSTRFIND
fclose(sport1);
delete(sport1);
clear sport1;
INSTRFIND

子函數:

%對分割出的單個字符進行分割x方向的再分割
function [ix,iy]=xfenge(goal1)
[m,n]=size(goal1);
ix(m)=0;
xx=0;j=1;
for  x=1:m
    for y=1:n
        if goal1(x,y)==1;
            xx=1;
        end
    end
    if xx==1
        ix(j)=x;
        j=j+1;
    end
end
ix=ix(1);


iy(m)=0;
xx=0;j=1;
for  x=m:-1:1
    for y=n:-1:1
        if goal1(x,y)==1;
            xx=1;
        end
    end
    if xx==1
        iy(j)=x;
        j=j+1;
    end
end
iy=iy(1);

子函數:

%對分割出的單個字符進行分割y方向的再分割
function [jx,jy]=yfenge(goal1)
[m,n]=size(goal1);
jx(m)=0;
xx=0;j=1;
for  y=1:n
    for x=1:m
        if goal1(x,y)==1;
            xx=1;
        end
    end
    if xx==1
        jx(j)=y;
        j=j+1;
    end
end
jx=jx(1)


jy(m)=0;
xx=0;j=1;
for  y=n:-1:1
    for x=m:-1:1
        if goal1(x,y)==1;
            xx=1;
        end
    end
    if xx==1
        jy(j)=y;
        j=j+1;
    end
end
jy=jy(1)

 

2、BP神經網絡訓練後識別:

clc;
clear all;
close all;




for kk = 0:99
    p1=ones(16,16);
    m=strcat('muban3\',int2str(kk),'.bmp');
    x=imread(m,'bmp');


    [i,j]=find(x==1);
    imin=min(i);
    imax=max(i);
    jmin=min(j);
    jmax=max(j);
    bw1=x(imin:imax,jmin:jmax);%words segmentation
    
    bw1=imresize(bw1,[16,16],'nearest');
    [i,j]=size(bw1);
    i1=round((16-i)/2);
    j1=round((16-j)/2);
    p1(i1+1:i1+i,j1+1:j1+j)=bw1;
    
    for m=0:15
        p(m*16+1:(m+1)*16,kk+1)=p1(1:16,m+1);
    end
    
    switch kk
        case{0,10,20,30,40,50,60,70,80,90}
            t(kk+1)=1;
        case{1,11,21,31,41,51,61,71,81,91}
            t(kk+1)=2;
        case{2,12,22,32,42,52,62,72,82,92}
            t(kk+1)=3;
        case{3,13,23,33,43,53,63,73,83,93}
            t(kk+1)=4;
        case{4,14,24,34,44,54,64,74,84,94}
            t(kk+1)=5;
        case{5,15,25,35,45,55,65,75,85,95}
            t(kk+1)=6;
        case{6,16,26,36,46,56,66,76,86,96}
            t(kk+1)=7;
        case{7,17,27,37,47,57,67,77,87,97}
            t(kk+1)=8;
        case{8,18,28,38,48,58,68,78,88,98}
            t(kk+1)=9;
        case{9,19,29,39,49,59,69,79,89,99}
            t(kk+1)=10;
    end
end


% 建立和訓練BP網絡 
pr(1:256,1)=0;
pr(1:256,2)=1;
net=newff(pr,[25 1],{'logsig' 'purelin'}, 'traingdx', 'learngdm');
net.trainParam.epochs=250;
net.trainParam.goal=0.001;
net.trainParam.show=10;
net.trainParam.lr=0.05;
net=train(net,p,t)


save E52net net;



% 識別 
I=imread('ocr.jpg');%讀取測試圖片
[m,n,z]=size(I)
figure(1);
imshow(I);title('測試圖片')
I1=rgb2gray(I);
 %   imwrite(I1,'I1.jpg');%保存二值化圖像
figure(2);
imshow(I1);%顯示二值化圖像
%figure(3);
%imhist(I1);


Ic = imcomplement(I1);%取反
  %  imwrite(Ic,'Ic.jpg');
figure(33);imshow(Ic);
BW = im2bw(Ic, graythresh(Ic));%二值化
  %  imwrite(BW,'BW.jpg');
figure(5), imshow(BW); 


bw=edge(I1,'prewitt');%邊緣提取
 %   imwrite(bw,'bw.jpg');
figure(32);imshow(bw);
theta=1:180;
[R,xp]=radon(bw,theta);
[I0,J]=find(R>=max(max(R)));%J記錄了傾斜角
qingxiejiao=90-J
goal1=imrotate(BW,qingxiejiao,'bilinear','crop');
  %  imwrite(goal1,'goal1.jpg');
figure,imshow(I1);title('correct image');


%中值濾波
goal3=medfilt2(goal1,[3,3]);
figure(19), imshow(goal3);


goal3=medfilt2(goal3,[3,3]);
  %  imwrite(goal3,'goal3.jpg');
figure(19), imshow(goal3);


%求解X方向的投影像素範圍
[ix1,iy1]=xfenge(goal1)


%求解y方向的投影像素範圍
[jx1,jy1]=yfenge(goal1)


%字符區域分割:
goal4=goal3(ix1:iy1,jx1:jy1);
  %  imwrite(goal4,'goal4.jpg');
figure(21);imshow(goal4);
[m,n]=size(goal4)
%[L,num] = bwlabel(goal4,8);%區域標記,1,2,3,4


ysum(n-1)=0;
for y=1:n-1
ysum(y)=sum(goal4(:,y));
end
%y=1:n-1;
%figure(12)
%plot(y,ysum)%畫出y方向上的像素分佈


%找出ysum分佈的幾個與y軸交點就是單個字符在y軸上分佈的區間
i=1;j=1;
for y=1:n-2
    if (ysum(y)==0)&(ysum(y+1)~=0)
        yy(i)=y
        i=i+1;
    end
    
    if (ysum(y)~=0)&(ysum(y+1)==0)
        yx(j)=y
        j=j+1;
    end
end
[m_yy,n_yy]=size(yy);%求出字符的分佈並分割
if n_yy==3 %根據n_yy和n_yx的個數及分佈區間,選擇分割區間
%segment
num1=goal4(1:m , 1:yx(1));%分割出字符1
figure(41);imshow(num1);


num2=goal4(1:m ,yy(1):yx(2));%分割出字符2
figure(42);imshow(num2);


num3=goal4(1:m ,  yy(2):yx(3));%分割出字符3
figure(43);imshow(num3);


num4=goal4(1:m ,  yy(3):n);%分割出字符4
figure(44);imshow(num4);
%[m1,n1]=size(num1)%求出各個字符的大小
%[m2,n2]=size(num2)
%[m3,n3]=size(num3)
%[m4,n4]=size(num4)
%對單個字符細分,避免字體出現大小不一致的狀況,也就是再在x軸上進行分割
[ix1,iy1]=xfenge(num1)
[ix2,iy2]=xfenge(num2)
[ix3,iy3]=xfenge(num3)
[ix4,iy4]=xfenge(num4)


num1=goal4(ix1:iy1 , 1:yx(1));
figure(51);imshow(num1);


num2=goal4(ix2:iy2 ,yy(1):yx(2));
figure(52);imshow(num2);


num3=goal4(ix3:iy3 ,  yy(2):yx(3));
figure(53);imshow(num3);


num4=goal4(ix4:iy4 ,  yy(3):n);
figure(54);imshow(num4);


imwrite(num1, '1.bmp'); 
imwrite(num2, '2.bmp'); 
imwrite(num3, '3.bmp'); 
imwrite(num4, '4.bmp'); 
end


if n_yy==4 %根據n_yy和n_yx的個數及分佈區間,選擇分割區間
    %segment
num1=goal4(1:m , yy(1):yx(1));
figure(61);imshow(num1);


num2=goal4(1:m ,yy(2):yx(2));
figure(62);imshow(num2);


num3=goal4(1:m ,  yy(3):yx(3));
figure(63);imshow(num3);


num4=goal4(1:m ,  yy(4):n);
figure(64);imshow(num4);


%[m1,n1]=size(num1)
%[m2,n2]=size(num2)
%[m3,n3]=size(num3)
%[m4,n4]=size(num4)
%對單個字符細分
[ix1,iy1]=xfenge(num1)
[ix2,iy2]=xfenge(num2)
[ix3,iy3]=xfenge(num3)
[ix4,iy4]=xfenge(num4)


num1=goal4(ix1:iy1 , yy(1):yx(1));imwrite(num1, '1.bmp'); 
figure(71);imshow(num1);


num2=goal4(ix2:iy2 ,yy(2):yx(2));imwrite(num2, '2.bmp'); 
figure(72);imshow(num2);


num3=goal4(ix3:iy3 ,  yy(3):yx(3));imwrite(num3, '3.bmp'); 
figure(73);imshow(num3);


num4=goal4(ix4:iy4 ,  yy(4):n);imwrite(num4, '4.bmp'); 
figure(74);imshow(num4);
end


for i=1:4
    imagenum=strcat(num2str(i),'.bmp');
    J=imread(imagenum);
     [m,n]=size(J)
    num{i}=imresize(J,[32,32],'nearest');  %待識別字符歸一化
    [m,n]=size(num{i})
    figure;imshow(num{i});
    imwrite(num{i}, [num2str(i),'.bmp']);
    
end
   
 clear all;
  for i=1:4  
    p(1:256,1)=1;
    p1=ones(16,16);
    load E52net net;
   % test=input('FileName:', 's');
    %x=imread(test,'bmp');
    m=strcat(num2str(i),'.bmp');
    x=imread(m,'bmp');


    [i,j]=find(x==1);
    imin=min(i);
    imax=max(i);
    jmin=min(j);
    jmax=max(j);
    bw1=x(imin:imax,jmin:jmax);%words segmentation
    
    bw1=imresize(bw1,[16,16],'nearest');
    [i,j]=size(bw1);
    i1=round((16-i)/2);
    j1=round((16-j)/2);
    p1(i1+1:i1+i,j1+1:j1+j)=bw1;
    
    for m=0:15
        p(m*16+1:(m+1)*16,1)=p1(1:16,m+1);
    end
    [a,Pf,Af]=sim(net,p);
    figure;imshow(p1);
    a=round(a)
    
        switch a
        case 1
            Rchar(i)='1'
        case 2
            Rchar(i)='2'
        case 3
            Rchar(i)='3'
        case 4
            Rchar(i)='4'
        case 5
            Rchar(i)='5'
        case 6
           Rchar(i)='A'
        case 7
           Rchar(i)='B'
        case 8
            Rchar(i)='C'
        case 9
           Rchar(i)='D'
        case 10
           Rchar(i)='E'
         otherwise 
            Rchar(i)='false'   ;
    end
end


 schar=[Rchar(1),Rchar(2),Rchar(3),Rchar(4)]

 

 

轉載地址:http://blog.csdn.net/u013050589/article/details/24302595

 

http://blog.csdn.net/sanwandoujiang/article/details/34107993

 

http://blog.csdn.net/sanwandoujiang/article/details/34103981

 

http://download.csdn.net/download/dengdong1028/7843431 臨近法

相關文章
相關標籤/搜索