展會信息港展會大全

字符識別(模板匹配BP神經(jīng)網(wǎng)絡(luò)訓(xùn)練)
來源:互聯(lián)網(wǎng)   發(fā)布日期:2011-10-01 18:02:31   瀏覽:19339次  

導(dǎo)讀:Abstract 2一 引言:... 3二 字符圖像獲。... 3三 字符預(yù)處理... 43.2 字符區(qū)域………………………………………………………………………….43.2 字符區(qū)域分割...

3.2 字符區(qū)域………………………………………………………………………….4

5.1 訓(xùn)練樣本制作………………………………………………………………………………….6

5.2設(shè)計BP神經(jīng)網(wǎng)絡(luò)………………………………………………………………………………6

摘 要

在MATLAB環(huán)境下利用USB攝像頭采集字符圖像,讀取一幀保存為圖像,然后對讀取保存的字符圖像,灰度化,二值化,在此基礎(chǔ)上做傾斜矯正,對矯正的圖像進(jìn)行濾波平滑處理,然后對字符區(qū)域進(jìn)行提取分割出單個字符,識別方法一是采用模板匹配的方法逐個對字符與預(yù)先制作好的字符模板比較,如果結(jié)果小于某一閾值則結(jié)果就是模板上的字符;二是采用BP神經(jīng)網(wǎng)絡(luò)訓(xùn)練,通過訓(xùn)練好的net對待識別字符進(jìn)行識別。最然后將識別結(jié)果通過MATLAB下的串口工具輸出51單片機上用液晶顯示出來。

                                                                                                                                                                 

關(guān)鍵字: 傾斜矯正,字符分割,模板匹配,BP神經(jīng)網(wǎng)絡(luò),液晶顯示

 

 

Abstract

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 display

一 引言:

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

關(guān)于字符識別的方法有很多種,最簡單的就是模板匹配,還有根據(jù)采集到的字符用BP神經(jīng)網(wǎng)絡(luò)或者SVM來訓(xùn)練得到結(jié)果的方式。本文主要針對模板匹配的方式,在MATLAB環(huán)境下編程實現(xiàn)。

 

二 字符圖像獲。

在MATLAB下利用image acquisition toolbox獲取視頻幀,并保存圖像在工程文件夾內(nèi)。攝像頭采用普通的USB攝像頭,由于這種攝像頭拍攝的照片延時比較大,所以先用image acquisition toolbox下的對視頻進(jìn)行預(yù)覽,調(diào)整出最佳的效果來,采集的圖像效果越好則識別率越高。 根據(jù)測試,實驗選擇640*480的視頻獲取窗口,顏色空間選取為RGB空間,獲取一幀后保存為jpg的存儲格式。


三 字符預(yù)處理

3.1字符矯正

由于攝像頭拍攝的圖像存在一定存在的傾斜度,在分割字符區(qū)域時,應(yīng)先對字符進(jìn)行矯正。過程如下:

將通過攝像頭獲取的保存幀圖像灰度化,然后對其進(jìn)行邊緣提取,再在1到180度角內(nèi)對圖像進(jìn)行旋轉(zhuǎn),記錄下邊緣提取后的圖像在x軸方向上的投影,當(dāng)x軸方向上的投影最小的時候即表示圖像中字符平行于y軸,已經(jīng)完成矯正,此時記錄下旋轉(zhuǎn)的傾斜角。然后利用imrotate函數(shù)實現(xiàn)對字符圖像的矯正。

 

3.2 字符區(qū)域分割:

在第三步完成對字符圖像的傾斜矯正后,將圖像分別做x軸和y軸方向上的投影既可以知道字符區(qū)域在x軸上的像素分布范圍和y軸上的像素分布范圍,然后對根據(jù)這個范圍對圖像做分割,在MATLAB中表示為:

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

其中g(shù)oal為分割后的圖像,I為分割前的圖像,ix1和ix2分別為x軸上投影的像素范圍的起始坐標(biāo)值和終止坐標(biāo)值,iy1和iy2分別為y軸上投影的像素范圍的起始坐標(biāo)值和終止坐標(biāo)值。

 

3.3 單個字體分割:

在分割得到的字符區(qū)域圖像上,只需要做y軸上的投影就可以知道每個字符在y軸上的分布區(qū)間,然后利用這個分布區(qū)間就可以分割出單個字符。


3.4 單個字體裁剪

在第五步分割出來的字符基礎(chǔ)上進(jìn)一步對字符的像素區(qū)域進(jìn)行裁剪,原理也是分別做x軸,y軸方向上的投影,求的字符的區(qū)間再做剪裁。

 

四 模板字符識別

4.1字符模板制作:

模板的要求是與要識別的字符的字體格式一致,實驗中采用word上的標(biāo)準(zhǔn)字符,通過截圖軟件截圖后按照3-6步的處理過程制作出需要的字符模板,從0到9共10個數(shù)字,A到Z共26個字母。

 

4.2 字符模板歸一化

在滿足識別率的條件下,盡量采用小模板識別可以提神運算速度,具體的模板大小,可以根據(jù)后面的與待識別字符的比較中調(diào)節(jié)。

 

4.3識別過程:

將待識別字符與字符模板做同樣的歸一化處理,然后遍歷與字符模板比較,處理方法為先和字符模板做差,然后計算做差后的圖像的總像素值,如果小于每一個閾值,則表示該待識別字符和該模板是同一個字符,這樣就完成了一次識別。

循環(huán)對要識別的字符做同樣的處理就可以識別出所有的字符,將結(jié)果保存在字符串中。

 

五 BP神經(jīng)網(wǎng)絡(luò)字符識別

BP(Back Propagation)網(wǎng)絡(luò)是1986年由Rumelhart和McCelland為首的科學(xué)家小組提出,是一種按誤差逆?zhèn)鞑ニ惴ㄓ?xùn)練的多層前饋網(wǎng)絡(luò),是目前應(yīng)用最廣泛的神經(jīng)網(wǎng)絡(luò)模型之一。BP網(wǎng)絡(luò)能學(xué)習(xí)和存貯大量的輸入-輸出模式映射關(guān)系,而無需事前揭示描述這種映射關(guān)系的數(shù)學(xué)方程。它的學(xué)習(xí)規(guī)則是使用最速下降法,通過反向傳播來不斷調(diào)整網(wǎng)絡(luò)的權(quán)值和閾值,使網(wǎng)絡(luò)的誤差平方和最小。BP神經(jīng)網(wǎng)絡(luò)模型拓?fù)浣Y(jié)構(gòu)包括輸入層(input)、隱層(hide layer)和輸出層(outputlayer)。

BP (Back Propagation)神經(jīng)網(wǎng)絡(luò),即誤差反傳誤差反向傳播算法的學(xué)習(xí)過程,由信息的正向傳播和誤差的反向傳播兩個過程組成。輸入層各神經(jīng)元負(fù)責(zé)接收來自外界的輸入信息,并傳遞給中間層各神經(jīng)元;中間層是內(nèi)部信息處理層,負(fù)責(zé)信息變換,根據(jù)信息變化能力的需求,中間層可以設(shè)計為單隱層或者多隱層結(jié)構(gòu);最后一個隱層傳遞到輸出層各神經(jīng)元的信息,經(jīng)進(jìn)一步處理后,完成一次學(xué)習(xí)的正向傳播處理過程,由輸出層向外界輸出信息處理結(jié)果。當(dāng)實際輸出與期望輸出不符時,進(jìn)入誤差的反向傳播階段。誤差通過輸出層,按誤差梯度下降的方式修正各層權(quán)值,向隱層、輸入層逐層反傳。周而復(fù)始的信息正向傳播和誤差反向傳播過程,是各層權(quán)值不斷調(diào)整的過程,也是神經(jīng)網(wǎng)絡(luò)學(xué)習(xí)訓(xùn)練的過程,此過程一直進(jìn)行到網(wǎng)絡(luò)輸出的誤差減少到可以接受的程度,或者預(yù)先設(shè)定的學(xué)習(xí)次數(shù)為止。

  BP神經(jīng)網(wǎng)絡(luò)模型BP網(wǎng)絡(luò)模型包括其輸入輸出模型、作用函數(shù)模型、誤差計算模型和自學(xué)習(xí)模型。

 。1)節(jié)點輸出模型

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

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

  f-非線形作用函數(shù);q -神經(jīng)單元閾值。

  圖1 典型BP網(wǎng)絡(luò)結(jié)構(gòu)模型

 。2)作用函數(shù)模型

  作用函數(shù)是反映下層輸入對上層節(jié)點刺激脈沖強度的函數(shù)又稱刺激函數(shù),一般取為(0,1)內(nèi)連續(xù)取值Sigmoid函數(shù): f(x)=1/(1+e) (3)

 。3)誤差計算模型

  誤差計算模型是反映神經(jīng)網(wǎng)絡(luò)期望輸出與計算輸出之間誤差大小的函數(shù):

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

  tpi- i節(jié)點的期望輸出值;Opi-i節(jié)點計算輸出值。

 。4)自學(xué)習(xí)模型

  神經(jīng)網(wǎng)絡(luò)的學(xué)習(xí)過程,即連接下層節(jié)點和上層節(jié)點之間的權(quán)重拒陣Wij的設(shè)定和誤差修正過程。BP網(wǎng)絡(luò)有師學(xué)習(xí)方式-需要設(shè)定期望值和無師學(xué)習(xí)方式-只需輸入模式之分。自學(xué)習(xí)模型為

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

h -學(xué)習(xí)因子;Фi-輸出節(jié)點i的計算誤差;Oj-輸出節(jié)點j的計算輸出;a-動量因子。

 

5.1 訓(xùn)練樣本制作:

在不同分辨率和不同傾斜角度下分別采集幾組圖片作為訓(xùn)練樣本,本實驗為了節(jié)省計算時間,根據(jù)需要只做12345ABCDE這10個字符的識別,因此只各采集了10組數(shù)據(jù)。不同分辨率下5組,不同傾斜角度下5組。然后按照2-4上的操作過程的對字符進(jìn)行處理,獲得32*32大小的訓(xùn)練樣本共100個。

 

5.2設(shè)計BP神經(jīng)網(wǎng)絡(luò)

利用MATLAB下的神經(jīng)網(wǎng)絡(luò)工具設(shè)計一個,以字符圖像的x軸y軸像素值為輸入特征作為輸入層的輸入;以logsig函數(shù)作為隱含層,隱含層設(shè)計節(jié)點25個,輸出層就是預(yù)期的結(jié)果,共十種可能,所以有輸出層有十種輸出。

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

net.trainParam.epochs=250;%訓(xùn)練步數(shù)

net.trainParam.goal=0.001;%目標(biāo)誤差

net.trainParam.show=10;%系統(tǒng)每10步顯示一次訓(xùn)練誤差的變化曲線

net.trainParam.lr=0.05; %學(xué)習(xí)速度

net=train(net,p,t)%訓(xùn)練

并保存訓(xùn)練結(jié)果save name net

 

5.3 BP訓(xùn)練

首先對待識別字符預(yù)處理,然后讀取讀取訓(xùn)練好的網(wǎng)絡(luò)load name net,通過sim函數(shù)對字符進(jìn)行識別,結(jié)果輸出,保存在一個字符串內(nèi)。

 

六 識別結(jié)果發(fā)送下位機

利用MTLAB下的串口工具發(fā)送識別出的結(jié)果給下位機,下位機為51核的單片機,然后在單片機內(nèi)經(jīng)過程序處理驅(qū)動LM1602液晶顯示結(jié)果。

 

5.1 MATLAB下的串口工具:

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

a、支持基于串行接口(RS-232、RS-422、RS-485)的通信;

b、通信數(shù)據(jù)支持二進(jìn)制和文本(ASCII)兩種方式;

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

d、支持基于事件驅(qū)動的通信(亦稱中斷方式)。

 

5.2 下位機處理

5.2.1主控電路

主控芯片采用基于51核的STC12A50S8,51單片機是對目前所有兼容Intel 8031指令系統(tǒng)的單片機的統(tǒng)稱。

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

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

  ·32條I/O口線·111條指令,大部分為單字節(jié)指令

  ·21個專用寄存器

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

  ·一個全雙工串行通信口

  ·外部數(shù)據(jù)存儲器尋址空間為64kB

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

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

  ·單一+5V電源供電

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

  RAM:用以存放可以讀寫的數(shù)據(jù),如運算的中間結(jié)果、最終結(jié)果以及欲顯示的數(shù)據(jù);

  ROM:用以存放程序、一些原始數(shù)據(jù)和表格;

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

  T/C:兩個定時/記數(shù)器,既可以工作在定時模式,也可以工作在記數(shù)模式;

  五個中斷源的中斷控制系統(tǒng);

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

  片內(nèi)振蕩器和時鐘產(chǎn)生電路,石英晶體和微調(diào)電容需要外接。最高振蕩頻率為12M。

5.2.2 液晶顯示電路

實驗中顯示模板采用1602字符型液晶,它是工業(yè)字符型液晶,能夠同時顯示16x02即32個字符。602液晶模塊內(nèi)部的字符發(fā)生存儲器(CGROM)已經(jīng)存儲了160個不同的點陣字符圖形,這些字符有:阿拉伯?dāng)?shù)字、英文字母的大小寫、常用的符號、和日文假名等,每一個字符都有一個固定的代碼,比如大寫的英文字母“A”的代碼是01000001B(41H),顯示時模塊把地址41H中的點陣字符圖形顯示出來,我們就能看到字母“A”。

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

5.2. 3 串口通信圖:

由于單片機的串口輸出為TTL電平,與PC機通信是需要采用轉(zhuǎn)換為RS232電平,實驗中使用美信公司的MAX232芯片。它是美信公司專門為電腦的RS-232標(biāo)準(zhǔn)串口設(shè)計的單電源電平轉(zhuǎn)換芯片,使用+5v單電源供電。

 

七 總結(jié):

本實驗完成了usb攝像頭的視頻幀圖像采集,并對采集圖像進(jìn)行了數(shù)字圖像處理,采用模板匹配和BP神經(jīng)網(wǎng)絡(luò)訓(xùn)練的方式對字符進(jìn)行識別,并利用MATLAB下的串口工具和下位機單片機通信,發(fā)送識別結(jié)果顯示在字符液晶上。

試驗中存在的問題:一是,對圖像字符進(jìn)行分割的時候,如果圖像采集的分辨率過低的話會出現(xiàn)字符斷裂的情況,這時候要做的就是對字符進(jìn)行連通域檢測。二是在做本實驗的程序都是針對特定字符進(jìn)行處理的,沒有做自適應(yīng)的字符個數(shù)檢測。三是BP訓(xùn)練樣本數(shù)太少,所以訓(xùn)練后的網(wǎng)絡(luò)對字符的識別結(jié)果并不好。這些都需要后續(xù)的改進(jìn)。

 

八參考文獻(xiàn):

[ 1]  王鵬.基于神經(jīng)網(wǎng)絡(luò)的手寫體字符識別 北京工業(yè)大學(xué) , 2002

[ 2]  閆雪梅 ,王曉華 ,夏興高. 基于 PCA和 BP神經(jīng)網(wǎng)絡(luò)算法的車牌字符識別 北京理工大學(xué)信息科學(xué)技術(shù)學(xué)院 2007

[ 3]  金城 二維圖像特征研究 浙江大學(xué)博士論文 2006

[ 4]  MATLAB2010R image processing tools

 

附錄:

MATLAB程序:

一、模板匹配:

%%%%%%%%%%%%%%%%%模板字符識別1.0%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%朱本福
%利用usb攝像頭在MATLAB中通過image acquisition toolbox
%獲取一幀圖片并保存為ocr.jpg在讀取圖片進(jìn)行處理,采用模板匹配的
%方式進(jìn)行識別,模板為根據(jù)操作制作的,最后將結(jié)果通過串口發(fā)送出去顯示在單片機上
%MATLAB2010下開發(fā)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
clc;
clear all;
close all;
vid = videoinput('winvideo', 1, 'YUY2_640x480');%視頻獲取字符圖像
src = getselectedsource(vid);
vid.FramesPerTrigger = 1;
preview(vid);%預(yù)覽
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)


%字符區(qū)域分割:
goal4=goal3(ix1:iy1,jx1:jy1);
    imwrite(goal4,'goal4.jpg');
figure(21);imshow(goal4);
[m,n]=size(goal4)
%[L,num] = bwlabel(goal4,8);%區(qū)域標(biāo)記,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軸上分布的區(qū)間
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 %根據(jù)n_yy和n_yx的個數(shù)及分布區(qū)間,選擇分割區(qū)間
%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ì)分,避免字體出現(xiàn)大小不一致的情況,也就是再在x軸上進(jìn)行分割
[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 %根據(jù)n_yy和n_yx的個數(shù)及分布區(qū)間,選擇分割區(qū)間
    %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)
%對單個字符細(xì)分
[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  %這個可以根據(jù)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

子函數(shù):

%對分割出的單個字符進(jìn)行分割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);

子函數(shù):

%對分割出的單個字符進(jìn)行分割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)

二、BP神經(jīng)網(wǎng)絡(luò)訓(xùn)練后識別:

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


% 創(chuàng)建和訓(xùn)練BP網(wǎng)絡(luò) 
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)


%字符區(qū)域分割:
goal4=goal3(ix1:iy1,jx1:jy1);
  %  imwrite(goal4,'goal4.jpg');
figure(21);imshow(goal4);
[m,n]=size(goal4)
%[L,num] = bwlabel(goal4,8);%區(qū)域標(biāo)記,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軸上分布的區(qū)間
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 %根據(jù)n_yy和n_yx的個數(shù)及分布區(qū)間,選擇分割區(qū)間
%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ì)分,避免字體出現(xiàn)大小不一致的情況,也就是再在x軸上進(jìn)行分割
[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 %根據(jù)n_yy和n_yx的個數(shù)及分布區(qū)間,選擇分割區(qū)間
    %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)
%對單個字符細(xì)分
[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)]

贊助本站

相關(guān)內(nèi)容
AiLab云推薦
展開

熱門欄目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能實驗室 版權(quán)所有    關(guān)于我們 | 聯(lián)系我們 | 廣告服務(wù) | 公司動態(tài) | 免責(zé)聲明 | 隱私條款 | 工作機會 | 展會港