基于MATLAB的车牌识别(GUI)
目錄
車牌識別系統的介紹與展示? ?
?
圖像預處理?
1.灰度處理
2.邊緣檢測?
車牌定位
1.圖像腐蝕
2.圖像平滑
3.移除對象
4.圖像切割
車牌識別
1.灰度處理
2.直方圖均衡化
3.二值化
4.中值濾波
5.字符識別
車牌識別系統的介紹與展示? ?
車牌識別技術的推廣普及對加強道路管理、城市交通事故、違章停車、處理車輛被盜案件、保障社會穩定等方面有非常重大的影響。恰逢今年學習了數字圖像處理這門課程,開發了一個車牌識別的小APP,可以進行車牌的正確識別。
一個完整的車牌號識別系統要完成從圖像采集到字符識別輸出,過程相當復雜,基本可以分成硬件部分和軟件部分,硬件部分包括系統觸發、圖像采集,軟件部分包括圖像預處理、車牌定位、車牌識別三個部分。下面是一個車牌識別后的運行結果圖:
圖像預處理?
1.灰度處理
由于彩色圖不易確定車牌邊界,將彩色圖轉換為灰度圖以進一步處理圖片。這里使用了rgb2gray函數,該函數接收一個rgb圖像變量作為參數,返回該圖像轉換為灰度圖后的圖像數據,并將該數據賦值給變量I1。
若想得到該灰度圖的灰度分布情況,可使用imhist函數畫出該灰度圖的灰度值分布直方圖。
%% 灰度處理 img1 = rgb2gray(img); % RGB圖像轉灰度圖像 figure; subplot(1, 2, 1); imshow(img1); title('灰度圖像'); subplot(1, 2, 2); imhist(img1); title('灰度處理后的灰度直方圖');2.邊緣檢測?
在將彩色圖轉換為灰度圖后,便可用edge函數識別該圖像的邊界,edge函數通過使用一階導數和二階導數檢測亮度的不連續來確定圖像的邊界,它可以使用Sobel,Prewitt,Roberts,Canny,LoG,零交叉等多種算子,這里使用Roberts算子進行邊緣檢測。
%% 邊緣檢測 img4 = edge(img1, 'roberts', 0.15, 'both'); figure('name','邊緣檢測'); imshow(img4); title('roberts算子邊緣檢測');車牌定位
1.圖像腐蝕
由于邊緣檢測后的圖像中無關結構太多,這里需對圖像進行腐蝕處理,實現腐蝕處理的函數為imerode,它接收一個圖像數據和一個結構子,圖像中背景與結構子完全重合的像素點輸出值為1,不完全重合的和完全不重合的像素點輸出值為0,最后返回使用該結構子腐蝕過后的圖像數據,以此實現削減無關結構的目的。
%% 圖像腐蝕 se=[1;1;1]; img5 = imerode(img4, se); figure('name','圖像腐蝕'); imshow(img5); title('圖像腐蝕后的圖像');2.圖像平滑
腐蝕后的圖像結構大多呈分散狀分布,不連貫。為了方便之后確認車牌位置,這里需對該圖像進行平滑處理,在此我們使用閉操作使車牌平滑,并減小噪音,閉操作可以理解為先膨脹后腐蝕,實現函數為imclose。
%% 平滑圖像 se = strel('rectangle', [30, 30]); img6 = imclose(img5, se); figure('name','平滑處理'); imshow(img6); title('平滑圖像的輪廓');3.移除對象
%% 從圖像中刪除所有少于2200像素8鄰接 img7 = bwareaopen(img6, 2200); figure('name', '移除小對象'); imshow(img7); title('從圖像中移除小對象');4.圖像切割
在經過上面的處理之后,最初要識別的彩色圖像已經變成了以車牌為主要結構的二值圖像,我們可以對這種主體結構清晰的二值圖像進行掃描,進而確定出車牌的位置。
這里確定車牌位置的思路為:
首先使用size函數得到該圖像矩陣的行數y和列數x,用zero函數建立一個y行1列的零矩陣blue_Y,然后使用嵌套循環結構遍歷該二值圖像的每一個像素點,把每行值為1的像素點(也就是藍色像素點)的數量分別記錄在先前創建的矩陣blue_y中。遍歷完之后,找出blue_y矩陣中值最大的元素,它所對應的行即為該二值圖像中藍色像素點最多的行,該行可認為是靠近車牌中心的一行。
然后我們以這一行為起點,分別向上向下逐行掃描,當被掃描到的藍中白色像素點多于某個值時(該值只是一個用于判斷的估計值),繼續向上(或向下)掃描,直到掃描到某行中的藍色像素點數量小于估計值時,停止掃描,并記錄這一行的行數,該行數即為車牌的上邊界(或下邊界)。
同理,我們可以用相同的方法確定出車牌的左邊界和右邊界。
然后將原圖按照上述方法確定的坐標進行裁剪,即可得到僅有車牌的圖像。
%% 圖像切割 [y, x, z] = size(img7); img8 = double(img7); % 轉成雙精度浮點型% 車牌的藍色區域 % Y方向 blue_Y = zeros(y, 1); for i = 1:yfor j = 1:xif(img8(i, j) == 1) % 判斷車牌位置區域blue_Y(i, 1) = blue_Y(i, 1) + 1; % 像素點統計endend end% 找到Y坐標的最小值 img_Y1 = 1; while (blue_Y(img_Y1) < 5) && (img_Y1 < y)img_Y1 = img_Y1 + 1; end% 找到Y坐標的最大值 img_Y2 = y; while (blue_Y(img_Y2) < 5) && (img_Y2 > img_Y1)img_Y2 = img_Y2 - 1; end% x方向 blue_X = zeros(1, x); for j = 1:xfor i = 1:yif(img8(i, j) == 1) % 判斷車牌位置區域blue_X(1, j) = blue_X(1, j) + 1;endend end% 找到x坐標的最小值 img_X1 = 1; while (blue_X(1, img_X1) < 5) && (img_X1 < x)img_X1 = img_X1 + 1; end% 找到x坐標的最小值 img_X2 = x; while (blue_X(1, img_X2) < 5) && (img_X2 > img_X1)img_X2 = img_X2 - 1; end% 對圖像進行裁剪 img9 = img(img_Y1:img_Y2, img_X1:img_X2, :); figure('name', '定位剪切圖像'); imshow(img9); title('定位剪切后的彩色車牌圖像')% 保存提取出來的車牌圖像 % imwrite(img9, '車牌圖像.jpg');車牌識別
1.灰度處理
% 轉換成灰度圖像 plate_img1 = rgb2gray(img9); % RGB圖像轉灰度圖像 figure; subplot(1, 2, 1); imshow(plate_img1); title('灰度圖像'); subplot(1, 2, 2); imhist(plate_img1); title('灰度處理后的灰度直方圖');2.直方圖均衡化
為了使識別更加準確,我們將上一步得到的直方圖使用histeq函數進行均衡化,增強圖像的對比度。
% 直方圖均衡化 plate_img2 = histeq(plate_img1); figure('name', '直方圖均衡化'); subplot(1,2,1); imshow(plate_img2); title('直方圖均衡化的圖像'); subplot(1,2,2); imhist(plate_img2); title('直方圖');3.二值化
為了便于將其中的字符分離,我們將它轉換為二值圖像
% 二值化處理 plate_img3 = im2bw(plate_img2, 0.76); figure('name', '二值化處理'); imshow(plate_img3); title('車牌二值圖像');4.中值濾波
在車牌轉換為二值圖像后,為了使圖像中干擾元素減少,我們對其進行中值濾波,以減小圖中噪音。
% 中值濾波 plate_img4 = medfilt2(plate_img3); figure('name', '中值濾波'); imshow(plate_img4); title('中值濾波后的圖像');5.字符識別
目前用于車牌字符識別(OCR)的算法主要有基于模板匹配的OCR算法以及基于人工神經網絡的OCR算法。基于模板匹配的OCR的基本過程是:首先對待識別字符進行二值化并將其尺寸大小縮放為字符數據庫中模板的大小,然后與所有的模板進行匹配,最后選最佳匹配作為結果。用人工神經網絡進行字符識別主要有兩種方法:一種方法是先對待識別字符進行特征提取,然后用所獲得的特征來訓練神經網絡分類器。識別效果與字符特征的提取有關,而字符特征提取往往比較耗時。因此,字符特征的提取就成為研究的關鍵。另一種方法則充分利用神經網絡的特點,直接把待處理圖像輸入網絡,由網絡自動實現特征提取直至識別。
模板匹配的主要特點是實現簡單,當字符較規整時對字符圖像的缺損、污跡干擾適應力強且識別率相當高。綜合模板匹配的這些優點我們將其用為車牌字符識別的主要方法。
模板匹配是圖象識別方法中最具代表性的基本方法之一,它是將從待識別的圖象或圖象區域f(i,j)中提取的若干特征量與模板T(i,j)相應的特征量逐個進行比較,計算它們之間規格化的互相關量,其中互相關量最大的一個就表示期間相似程度最高,可將圖象歸于相應的類。也可以計算圖象與模板特征量之間的距離,用最小距離法判定所屬類。然而,通常情況下用于匹配的圖象各自的成像條件存在差異,產生較大的噪聲干擾,或圖象經預處理和規格化處理后,使得圖象的灰度或像素點的位置發生改變。在實際設計模板的時候,是根據各區域形狀固有的特點,突出各類似區域之間的差別,并將容易由處理過程引起的噪聲和位移等因素都考慮進去,按照一些基于圖象不變特性所設計的特征量來構建模板,就可以避免上述問題。
此處采用相減的方法來求得字符與模板中哪一個字符最相似,然后找到相似度最大的輸出。汽車牌照的字符一般有七個,大部分車牌第一位是漢字,通常代表車輛所屬省份,或是軍種、警別等有特定含義的字符簡稱;緊接其后的為字母與數字。車牌字符識別與一般文字識別在于它的字符數有限,漢字共約50多個,大寫英文字母26個,數字10個。所以建立字符模板庫也極為方便。為了實驗方便,結合本次設計所選汽車牌照的特點,只建立了7個漢字26個字母與10個數字的模板。其他模板設計的方法與此相同。
首先取字符模板,接著依次取待識別字符與模板進行匹配,將其與模板字符相減,得到的0越多那么就越匹配。把每一幅相減后的圖的0值個數保存,然后找數值最大的,即為識別出來的結果。
%% 字符識別 plate_img5 = my_imsplit(plate_img4); [m, n] = size(plate_img5);s = sum(plate_img5); %sum(x)就是豎向相加,求每列的和,結果是行向量; j = 1; k1 = 1; k2 = 1; while j ~= nwhile s(j) == 0j = j + 1;endk1 = j;while s(j) ~= 0 && j <= n-1j = j + 1;endk2 = j + 1;if k2 - k1 > round(n / 6.5)[val, num] = min(sum(plate_img5(:, [k1+5:k2-5])));plate_img5(:, k1+num+5) = 0;end endy1 = 10; y2 = 0.25; flag = 0; word1 = []; while flag == 0[m, n] = size(plate_img5);left = 1;width = 0;while sum(plate_img5(:, width+1)) ~= 0width = width + 1;endif width < y1plate_img5(:, [1:width]) = 0;plate_img5 = my_imsplit(plate_img5);elsetemp = my_imsplit(imcrop(plate_img5, [1,1,width,m]));[m, n] = size(temp);all = sum(sum(temp));two_thirds=sum(sum(temp([round(m/3):2*round(m/3)],:)));if two_thirds/all > y2flag = 1;word1 = temp;endplate_img5(:, [1:width]) = 0;plate_img5 = my_imsplit(plate_img5);end endfigure; subplot(2,4,1), imshow(plate_img5);% 分割出第二個字符[word2,plate_img5]=getword(plate_img5);subplot(2,4,2), imshow(plate_img5);% 分割出第三個字符[word3,plate_img5]=getword(plate_img5);subplot(2,4,3), imshow(plate_img5);% 分割出第四個字符[word4,plate_img5]=getword(plate_img5);subplot(2,4,4), imshow(plate_img5);% 分割出第五個字符[word5,plate_img5]=getword(plate_img5);subplot(2,3,4), imshow(plate_img5);% 分割出第六個字符[word6,plate_img5]=getword(plate_img5);subplot(2,3,5), imshow(plate_img5);% 分割出第七個字符[word7,plate_img5]=getword(plate_img5);subplot(2,3,6), imshow(plate_img5);figure;subplot(5,7,1),imshow(word1),title('1');subplot(5,7,2),imshow(word2),title('2');subplot(5,7,3),imshow(word3),title('3');subplot(5,7,4),imshow(word4),title('4');subplot(5,7,5),imshow(word5),title('5');subplot(5,7,6),imshow(word6),title('6');subplot(5,7,7),imshow(word7),title('7');word1=imresize(word1,[40 20]);%imresize對圖像做縮放處理,常用調用格式為:B=imresize(A,ntimes,method);其中method可選nearest,bilinear(雙線性),bicubic,box,lanczors2,lanczors3等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]);subplot(5,7,15),imshow(word1),title('11');subplot(5,7,16),imshow(word2),title('22');subplot(5,7,17),imshow(word3),title('33');subplot(5,7,18),imshow(word4),title('44');subplot(5,7,19),imshow(word5),title('55');subplot(5,7,20),imshow(word6),title('66');subplot(5,7,21),imshow(word7),title('77');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':'Z' '京遼魯陜蘇豫浙貴']);%建立自動識別字符代碼表;'京津滬渝港澳吉遼魯豫冀鄂湘晉青皖蘇贛浙閩粵瓊臺陜甘云川貴黑藏蒙桂新寧'% 編號:0-9分別為 1-10;A-Z分別為 11-36;% 京 津 滬 渝 港 澳 吉 遼 魯 豫 冀 鄂 湘 晉 青 皖 蘇% 贛 浙 閩 粵 瓊 臺 陜 甘 云 川 貴 黑 藏 蒙 桂 新 寧% 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 % 60 61 62 63 64 65 66 67 68 69 70subBw2 = zeros(40, 20);num = 1; % 車牌位數for i = 1:7ii = int2str(i); % 將整型數據轉換為字符串型數據word = imread([ii,'.jpg']); % 讀取之前分割出的字符的圖片segBw2 = imresize(word, [40,20], 'nearest'); % 調整圖片的大小segBw2 = im2bw(segBw2, 0.5); % 圖像二值化if i == 1 % 字符第一位為漢字,定位漢字所在字段kMin = 37;kMax = 44;elseif i == 2 % 第二位為英文字母,定位字母所在字段kMin = 11;kMax = 36;elseif i >= 3 % 第三位開始就是數字了,定位數字所在字段kMin = 1;kMax = 36;endl = 1;for k = kMin : kMaxfname = strcat('字符模板\',liccode(k),'.jpg'); % 根據字符庫找到圖片模板samBw2 = imread(fname); % 讀取模板庫中的圖片samBw2 = im2bw(samBw2, 0.5); % 圖像二值化% 將待識別圖片與模板圖片做差for i1 = 1:40for j1 = 1:20subBw2(i1, j1) = segBw2(i1, j1) - samBw2(i1 ,j1);endend% 統計兩幅圖片不同點的個數,并保存下來Dmax = 0;for i2 = 1:40for j2 = 1:20if subBw2(i2, j2) ~= 0Dmax = Dmax + 1;endendenderror(l) = Dmax;l = l + 1;end% 找到圖片差別最少的圖像errorMin = min(error);findc = find(error == errorMin); % error % findc% 根據字庫,對應到識別的字符Code(num*2 - 1) = liccode(findc(1) + kMin - 1);Code(num*2) = ' ';num = num + 1;end% 顯示識別結果disp(Code);msgbox(Code,'識別出的車牌號');完整的代碼及GUI我上傳到這里了,有需要的可以進行下載,也可以私信聯系我
基于MATLAB的車牌識別系統(GUI)-C#文檔類資源-CSDN文庫https://download.csdn.net/download/S2191300319/85075374?spm=1001.2014.3001.5501
寫在最后:
此算法參考網上諸多算法,其中有不太正確之處,我將其進行整合調試,目前運行非常順暢,效果也還可以,后續我會繼續改進,若有不當之處,希望大家多多指正!
總結
以上是生活随笔為你收集整理的基于MATLAB的车牌识别(GUI)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python画图matlab,matla
- 下一篇: Maven最新版的下载与安装教程(详细教