一、簡介
1 在進行影像處理任務之前,首先要明確處理物件和處理流程
處理物件: 新能源車牌和藍色車牌
處理流程:

2 由于要對藍色和新能源車牌進行識別,而且新能源車牌是漸變色,所以直接通過設定閾值的方法去識別兩種車牌并沒有單獨識別藍色車牌的可靠性高,這里,我根據車牌字符的特征進行車牌位置定位:
2.1 根據字符特征初步找出車牌位置

2.2 根據車牌長寬比進行初步篩選
我們可以用最小外接矩形演算法框出上一步已選出的區域,然后根據車牌長寬比設定閾值,將滿足閾值的矩形篩選出來,當然但還是會存在一部分干擾區域,
2.3 對矩形內像素進行顏色統計
通過對初步篩選后剩余區域分別進行像素的顏色統計,我們即可準確找出車牌位置,與此同時車牌的型別(新能源或藍牌)也可以在這里判斷出來
3 傾斜校正
這一步是為后面垂直投影法分割字符和模板匹配做準備
簡單來講,使用霍夫線演算法檢測車牌上下邊框所在直線,計算這條直線傾斜角度,之后對車牌進行旋轉即可,當然復雜點的方法可以具體看我的源程式,具體效果如下圖:

4 二值化、形態學處理、字符識別
4.1 二值化和形態學處理這里就不在贅述,很多博客已經講的非常清晰
4.2 字符分割
在這里需要對字符進行準確的分割,在分割之前還是可能會有干擾,需要再次分割出車牌字符的準確位置,這里我的方法是:先向左投影,設定閾值,切割出上下邊界,同理在切割出左右邊界,但是這只適用于車牌邊框明顯的情況下,所以我不建議你使用這個方法,慎用!!!

到這里就可以使用垂直投影法進行字符分割,這里需要注意的是新能源車牌有八位,藍牌有七位
分割結果如下圖所示:

4.3 字符識別
這里使用模板匹配,因為新能源車牌字符和藍牌字符不一致,所以要制作兩套字符模板,另外需要注意的是,根據《中華人民共和國機動車號牌》序號編碼規則,26個英文字符中“I“、”O“不能使用,所以不存在"1"和"I"、"0"和"O"字符混淆的問題
二、源代碼
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% resize的目標尺寸650*X
% 調參
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
clear;
se1 = strel('rectangle',[15 15]); %創建一個平坦的矩形結構
se2 = strel('rectangle',[12 20]); %創建一個平坦的矩形結構
se3 = strel('rectangle',[12 15]);
imgraw=imread('C:\Users\lenovo\Desktop\licenseplate\0.png'); %讀取圖
% se1 = strel('rectangle',[15 25]); %創建一個平坦的矩形結構
% se2 = strel('rectangle',[10 25]); %創建一個平坦的矩形結構
% se3 = strel('rectangle',[14 19]);
% imgraw=imread('E:\matlab workspace\licenseplate\車牌2.jpg'); %讀取影像
[m,~]=size(imgraw);
times = 650/m;
img=imresize(imgraw,times,'nearest');
g= fspecial('gaussian',[5,5],1); %高斯濾波器
g_img = imfilter(img, g, 'replicate'); %影像濾波
gray_img=rgb2gray(g_img); %轉為灰色影像
open = imopen(gray_img,se1); %影像開操作
sub_img = imsubtract(gray_img,open); %影像相減
BW_img = imbinarize(sub_img); %使用Otsu方法確定全域閾值進行二值化
edge_img = edge(BW_img,'canny');
edge_img1 = imclose(edge_img,se2); %影像閉操作
edge_img2 = imopen(edge_img1,se3); %影像開操作
%%%%%%%%%%%%%%%%%%%%%%%%%%%使用車牌長寬比進行判斷%%%%%%%%%%%%%%%%%%%%%%%%%%%
[B,L] = bwboundaries(edge_img2,'noholes');
num_rect = 0; %符合要求的矩形數量
matrix_rect = {}; %符合要求的矩形的坐標元胞矩陣
for k = 1:length(B)
boundary = B{k};
c = boundary(:,2);
r = boundary(:,1);
[rectx,recty,area,perimeter] = minboundrect(c,r,'a'); %rectx,recty為逆時針排列
width = round(sqrt((recty(1)-recty(2))^2+(rectx(1)-rectx(2))^2));
leth = round(sqrt((recty(2)-recty(3))^2+(rectx(2)-rectx(3))^2));
if width > leth
temp = width;
width = leth;
leth = temp;
end
ratio = leth / width;
if ratio >2.5 && ratio <4.5
num_rect = num_rect + 1;
matrix_rect{num_rect} = [rectx,recty];
end
end
subplot(451); imshow(img); title('原始影像');
subplot(452); imshow(g_img); title('高通濾波后影像');
subplot(453); imshow(gray_img); title('灰度影像');
subplot(454); imshow(open); title('影像開操作');
subplot(455); imshow(sub_img); title('影像相減');
subplot(456); imshow(BW_img); title('影像二值化');
subplot(457); imshow(edge_img); title('影像邊緣');
subplot(458); imshow(edge_img2); title('影像開閉操作');
subplot(459); imshow(img); title('原圖框出車牌');
hold on
for k = 1:num_rect
rect = matrix_rect{k};
rx = rect(:,1);
ry = rect(:,2);
line(rx,ry,'Color','red');
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%判斷顏色、二次判斷車牌%%%%%%%%%%%%%%%%%%%%%%%%%%%
p=0; %計算滿足顏色條件的次數
color = 'no';
for o=1:num_rect
z=matrix_rect{o};
mid1x=(z(1,1)+z(2,1))/2;
mid1y=(z(1,2)+z(2,2))/2;
mid2x=(z(3,1)+z(4,1))/2;
mid2y=(z(3,2)+z(4,2))/2;
green=0;blue=0;
hsv= rgb2hsv(img); %RGB轉換為HSV
img_count = (abs(ceil(mid2x+0.601)-floor(mid1x+0.601)))*(abs(ceil(mid2y+0.001)-floor(mid1y+0.001)));
subplot(4,5,10); imshow(hsv);
for i=ceil(mid1y+1):floor(mid2y-1)
if mid2x==mid1x
for j=floor(mid2x+1):ceil(mid1x+1)
h = hsv(i,j,1);
s = hsv(i,j,2);
v = hsv(i,j,3);
if 0.40< h && h <= 0.46 && s>0.4 && s<=1 && v>0.3 && v<1
green = green+1;
elseif 0.56<h && h<=0.72 && s>0.4 && s<=1 && v>0.4 && v<1
blue =blue +1;
end
end
else
for j=ceil(mid2x+1):floor(mid1x-1)
h = hsv(i,j,1);
s = hsv(i,j,2);
v = hsv(i,j,3);
if 0.40< h && h <= 0.46 && s>0.4 && s<=1 && v>0.3 && v<1
green = green+1;
elseif 0.56<h && h<=0.72 && s>0.4 && s<=1 && v>0.4 && v<1
blue =blue +1;
end
end
end
end
if green*2 >= img_count && green>blue
color = 'green';
p=p+1;
b=z; %滿足條件的元胞
elseif blue*2 >= img_count && blue>green
color = 'blue';
p=p+1;
b=z; %滿足條件的元胞
end
end
if (color == 'blue')&&(p == 1)
flag = 0;
style = '識別到的是藍色';
elseif (color == 'green')&&(p == 1)
flag = 1;
style = '識別到的是新能源';
end
function image=cutting(img,flag)
%獲取圖片大小
[row,col] = size(img);
%設定邊界
img(:,col)=1;
img(:,1)=1;
%影像取反,方便后續處理,根據黑色判斷邊界
all = sum(~img); %行向量
%figure('NumberTitle','off','Name','投影'),bar(a),title('投影');
left = 1;
right = 1;
count1 =0; %記錄字符個數
for i = 1:col-1 %從左到右掃描
if all(i)==0&&all(i+1)~=0 %左側邊界
left = i;
end
if all(i)~=0&&all(i+1)==0 %右側邊界
right=i;
else
right =0; %左右兩側均為黑色邊框
end
if right~=0
count1 = count1+1;
left_bound(count1) = left; %存放左邊界
right_bound(count1) = right; %存放右邊界
end
end
for i = 1:count1 %???
if left_bound(i)<fix(col/8)
left_bound(i)=left_bound(1);
end
end
count2 =1; %k記錄滿足條件的字符個數
right_boundary = zeros(1,count1); %存放右邊界
left_boundary = zeros(1,count1); %存放左邊界
for i = 1:count1
if (right_bound(i) - left_bound(i))>(fix(col/15)) %判斷字符寬度是否滿足要求 問題:字符寬度怎么求
right_boundary(count2) = right_bound(i);
left_boundary(count2) = left_bound(i);
count2 = count2+1;
end
end
三、運行結果

四、備注
版本:2020
完整代碼或者代寫添加QQ 1564658423
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/282109.html
標籤:其他
上一篇:【軟體工程】第六章
