车牌识别(MATLAB)
生活随笔
收集整理的這篇文章主要介紹了
车牌识别(MATLAB)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
直接上程序:?
%車牌識別程序 %根據hsv色彩定位法定位車牌,將圖像轉為HSV模型,獲取每個像素點的HSV值,判斷是否為藍色像素點,統計每行每列藍色像素點的個數,從而獲取車牌位置 %根據該位置對原始彩色圖像進行剪裁,并進行二值化,濾波、去點處理,為字符分割做準備 %按順序切割出7個字符,并保存為7張圖片 %分別提取圖片和模板進行比較,將比較結果最接近的確定為對應模板,并最終顯示車牌識別結果I=imread('E:\車牌識別 - 2\程序、配套的字符模板、車牌照片 - 2\車牌照片\car2.jpg'); %讀入車牌照片 figure(1),imshow(I),title('原圖');%%%%根據hsv色彩定位法定位車牌%%%% Image=im2double(I); %把圖像數據類型轉換為double類型 Image=rgb2hsv(Image); %將RGB圖像轉化為hsv模型,H色相,S飽和度,V亮度 [y,x,~]=size(Image); Blue_y = zeros(y, 1); p=[0.56 0.71 0.4 1 0.3 1 0]; for i = 1 : y for j = 1 : x hij = Image(i, j, 1); %取出每個像素點的H、S、V值sij = Image(i, j, 2); vij = Image(i, j, 3); if (hij>=p(1) && hij<=p(2)) &&( sij >=p(3)&& sij<=p(4))&&(vij>=p(5)&&vij<=p(6)) %若像素點的HSV處于藍色的HSV范圍 Blue_y(i, 1) = Blue_y(i, 1) + 1;%統計每行的藍色像素點數目 end end end [~, MaxY] = max(Blue_y);%獲取藍色像素點最多的行號 Th = p(7); %Th=0 PY1 = MaxY; while ((Blue_y(PY1,1)>Th) && (PY1>0))%找到車牌上邊界 PY1 = PY1 - 1; end PY2 = MaxY; while ((Blue_y(PY2,1)>Th) && (PY2<y))%找到車牌下邊界PY2 = PY2 + 1; end PY1 = PY1 - 2; %上下邊界校正(擴大) PY2 = PY2 + 2; if PY1 < 1 %如果圖像內容只有車牌,上述校正可能會使得邊界值超出合理范圍,此處防止邊界值超出圖像范圍PY1 = 1; end if PY2 > y PY2 = y; end It=I(PY1:PY2,:,:);%Y方向獲取原圖的車牌區域 figure(2),subplot(3,1,1),imshow(It),title('hsv色彩分割法進行車牌行定位結果'); IY = Image(PY1:PY2, :, :); %對HSV模型圖像Image在Y方向進行截取 [y1,x1,z1]=size(IY); Blue_x=zeros(1,x1); for j = 1 : x1 for i = 1 : y1 hij = IY(i, j, 1); %獲取每個像素點的HSV sij = IY(i, j, 2); vij = IY(i, j, 3); if (hij>=p(1) && hij<=p(2)) &&( sij >=p(3)&& sij<=p(4))&&(vij>=p(5)&&vij<=p(6))%若為藍色像素點 Blue_x(1, j) = Blue_x(1, j) + 1; %記錄每一列藍色像素數目end end end PX1=1;PX2=x1;%找到左右邊界 while Blue_x(1, PX1)==0PX1=PX1+1; end while Blue_x(1, PX2)==0PX2=PX2-1; endI1=I(PY1:PY2,PX1:PX2,:);%車牌剪裁 figure(2),subplot(3,1,2),imshow(I1),title('hsv色彩分割法車牌定位結果'); I2=rgb2gray(I1); %%%%字符分割前的圖像處理%%%% %邊界校正 [y,x,z]=size(I2);%I2有y行x列 PX1=round(x*5/440);%根據實際車牌比例,將邊框部分去除 PX2=x-round(x*5/440); PY1=round(y*16/140); PY2=y-round(y*16/140); fprintf('校正后 左邊界=%d、右邊界=%d、上邊界=%d、下邊界=%d',PX1,PX2,PY1,PY2); %彩色圖像車牌部分截取 dw=I1(PY1:PY2,PX1:PX2,:);%對邊界進行截取 figure(2),subplot(3,1,3),imshow(dw),title('邊界校正結果'); imwrite(dw,'dw.jpg');%把截取后的彩色圖像新創建一張圖片,命名為dw a=imread('dw.jpg'); b=rgb2gray(a); imwrite(b,'1.車牌灰度圖像.jpg'); g_max=double(max(max(b)));%得出剪裁后灰度圖矩陣的最大值,并變成雙精度浮點型 g_min=double(min(min(b)));%得出剪裁后灰度圖矩陣的最小值,并變成雙精度浮點型 T=round(g_max-(g_max-g_min)/2); % T為二值化的閾值,round用于取整 d=(double(b)>=T); % d:二值圖像 imwrite(d,'2.車牌二值圖像.jpg'); figure(3),subplot(3,1,1),imshow(d),title('二值圖像');% 濾波 h=fspecial('average',3);%創建一個二維濾波器,average是類型,3是參數 d=im2bw(round(filter2(h,d)));%filter2進行濾波處理,im2bw使用閾值變換法把灰度圖像轉換成二值圖像 imwrite(d,'4.均值濾波后.jpg');%去點處理 d=cut(d); [m,n]=size(d); d(:,round(n*122/430):round(n*137/430))=0;%去除中間的點 d=bwareaopen(d,65);%用于刪除二值圖像中面積小于一個定值(此處為65)的對象,默認情況下使用8鄰域 figure(3),subplot(3,1,2),imshow(d),title('去點處理');%上下邊框處理,找到上下邊界處像素值小于20的行,并將整行設為零 s=zeros(1,m); i=1; while i<=ms(i)=sum(d(i,:));i=i+1; end j=0;c=zeros(1,m);%c矩陣用于記錄下邊框處像素值小于20的行,用于確定邊框與字符間空隙的位置 while j<mwhile s(j+1)>20&&j<m-1j=j+1;endif j<round(m*12/140) %如果是上邊框d((1:j),:)=0;else j>round(m*115/140)%如果是下邊框c(j)=j;%將下邊界處理中像素值小于20的行記錄下來d(j,:)=0;endj=j+1; end jj=round(m/2);%這里是為了找到下邊界處理中,被記錄下來的最小行(即邊框和字符間空隙的上沿),所以從中間開始往下找,直到找到的第一個非零數 while c(jj)==0jj=jj+1; end d((jj:m),:)=0;%將這一行以下皆設為0 d=cut(d); figure(3),subplot(3,1,3),imshow(d),title('上下邊框處理'); imwrite(d,'5.切割前.jpg');%%%%字符分割%%%% [~,n]=size(d); % 切割出 7 個字符 % 第一個字符, y1=n*15/440;y2=0.25;flag=0;word1=[]; while flag==0[m,~]=size(d);left=1;wide=0;while sum(d(:,wide+1))~=0 % 找到像素和為零的列wide=wide+1;endif wide<y1 % 若這一列的位置在圖像左側前10列之內則認為是左側干擾d(:,(1:wide))=0;%把左側干擾全部變為0,并將其切割掉d=cut(d);elsetemp=cut(imcrop(d,[1 1 wide m]));%將一個字符剪切下來[m,~]=size(temp);all=sum(sum(temp));%第一個字符的像素值總和two_thirds=sum(sum(temp((round(m/3):2*round(m/3)),:)));%單個字符中段1/3圖像的像素值總和if two_thirds/all>y2%驗證是否為字符flag=1;word1=temp; %獲取第一個字符word1endd(:,(1:wide))=0;d=cut(d);%當提取第一個字符結束或者不滿足上述條件時,將該區域變為0,并切除end end% 分割出第二個字符 [word2,d]=extract(d); % 分割出第三個字符 [word3,d]=extract(d); % 分割出第四個字符 [word4,d]=extract(d); % 分割出第五個字符 [word5,d]=extract(d); % 分割出第六個字符 [word6,d]=extract(d); % 分割出第七個字符 [word7,d]=extract(d); [m,n]=size(word1);%歸一化大小為 40*20 word1=imresize(word1,[40 20]); word2=imresize(word2,[40 20]); word3=imresize(word3,[40 20]); word4=imresize(word4,[40 20]); word5=imresize(word5,[40 20]); word6=imresize(word6,[40 20]); word7=imresize(word7,[40 20]); %將切割下來短的字符保存為圖片 imwrite(word1,'1.jpg'); imwrite(word2,'2.jpg'); imwrite(word3,'3.jpg'); imwrite(word4,'4.jpg'); imwrite(word5,'5.jpg'); imwrite(word6,'6.jpg'); imwrite(word7,'7.jpg');%%%%字符識別%%%% %建立自動識別字符代碼表 liccode=char(['0':'9' 'A':'H' 'J':'N' 'P':'Z' '藏川鄂甘贛桂貴黑滬吉冀津晉京遼魯蒙閩寧青瓊陜蘇皖湘新渝豫粵云浙']); %建立自動識別字符代碼表 SubBw2=zeros(40,20); l=1; for I=1:7ii=int2str(I);%將整形變成字符串t=imread([ii,'.jpg']);SegBw2=imresize(t,[40 20],'nearest');%進行二值化,方便比較g_max=double(max(max(SegBw2)));g_min=double(min(min(SegBw2)));T=round(g_max-(g_max-g_min)/2); % T為二值化的閾值SegBw2=(double(SegBw2)>=T); % SegBw2切割下來的字符的二值圖像if l==1 %第一位漢字識別kmin=35;kmax=65;elseif l==2 %第二位 A~Z 字母識別kmin=11;kmax=34;else l>=3; %第三位以后是字母或數字識別kmin=1;kmax=34;end%在每一位對應區間按順序提取字符模板for k2=kmin:kmaxfname=strcat('字符模板',liccode(k2),'.jpg');SamBw2 = imread(fname);if(k2~=2)SamBw2=rgb2gray(SamBw2);endg_max=double(max(max(SamBw2)));%二值化處理字符模板g_min=double(min(min(SamBw2)));T=round(g_max-(g_max-g_min)/2); % T為二值化的閾值SamBw2=(double(SamBw2)>=T); % SamBw2為字符模板的二值圖像%字符圖像與模板進行比較a1(k2)=corr2(SegBw2,SamBw2);endA1=a1(kmin:kmax);%將比較結果放入矩陣A1MaxA1=max(A1);%找到比較結果最大值findc=find(A1==MaxA1);%獲取最大值所在位置Code(l*2-1)=liccode(findc(1)+kmin-1);Code(l*2)=' ';l=l+1;%進行下一字符的提取和比較 end figure(4),subplot(2,7,1:7),imshow(dw),title('車牌定位結果'), xlabel({'','車牌切割結果'}); subplot(2,7,8),imshow(word1); subplot(2,7,9),imshow(word2); subplot(2,7,10),imshow(word3); subplot(2,7,11),imshow(word4); xlabel(['識別結果為: ', Code]); subplot(2,7,12),imshow(word5); subplot(2,7,13),imshow(word6); subplot(2,7,14),imshow(word7);運行結果如下
?
(車牌隨便找的,為了保護他人權益,用了較粗暴的涂鴉方式)
工程文檔下載請到:?https://download.csdn.net/download/lc886/12576374
?
總結
以上是生活随笔為你收集整理的车牌识别(MATLAB)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【文末赠书】我背着女朋友,用 Pytho
- 下一篇: 【ChatGPT】GPT-3.5+Cha