目录
一 处理流程
二 结果展示
三 核心要点解读
四 matlab代码实现
整套方案还包括以下博客:
(1)基于matlab的蓝色车牌识别(绪论)
(2)基于matlab的蓝色车牌识别(车牌定位)
(3)基于matlab的蓝色车牌识别(车牌倾斜矫正)
(4)基于matlab的蓝色车牌识别(车牌字符分割)
(5)基于matlab的蓝色车牌识别(车牌字符识别)
转载请注明出处,谢谢!
首先对汽车图片进行预处理, 然后使用sobel算子进行边缘检测,接着运用数学形态学运算找出若干个候选区域,最后基于混合特征(颜色特征、几何特征和面积特征)精确定位出车牌区域。
1.汽车图片
2. 高斯模糊图片
3.垂直边缘图片
4.形态学处理后图片
5.车牌图片
1.图像预处理
灰度化:去除冗余信息,减少存储开销,提高运行速度;
亮度调整:车牌图像的灰度有时会集中于某一较小区间,如图像偏暗或偏亮,有时有必要车辆图像的对比度;
高斯滤波:去除噪声,同时模糊一些非车牌边缘(比如后面的树叶),为sobel边缘检测做铺垫。
2.边缘检测
在牌照的矩形区域内存在丰富的边缘,呈现出规则的纹理特征车牌边缘有一定的密集性,车牌的垂直边缘比水平边缘密集,而车身的其他部位如保险杠则水平边缘较明显,垂直边缘较少;本研究选取sobel算子进行垂直边缘检测,感兴趣的同学可以试一试其它的边缘算子方法。
3.形态学处理
意义:将得到的边缘图像进行闭运算与开运算使牌照区域连通,得到牌照的候选区域;
闭运算:闭运算是先膨胀后腐蚀的过程,用来填充物体内细小空洞、平滑边界,连通车牌区域,以便于取轮廓;
开运算:开运算是先腐蚀后膨胀的过程,用来消除细小的噪声、平滑较大物体的边界;
结构元素形状选取:车牌区域的形状是长方形的(也可以使用水平和垂直直线),所以选取方形的结构元素进行形态学操作;
结构元素大小选取:用字符的标准宽度、高度、车牌的标准宽度、标准高度、图片测量的车牌宽度和高度之间的关系,来大概确定结构元素的宽和长,再经过多次调试进一步确定结构元素宽和长。
4.混合特征
当形态学处理之后,有多个连通区域作为车牌的候选区域,这时使用车片的先验知识(混合特征比如车牌颜色特征、面积特征、长宽比特征)来筛选出唯一的车牌区域;
颜色判断:首先将rgb图像转化为hsv颜色模型,然后统计每个候选车牌的蓝色像素点数量(先验知识:在整个车牌中,蓝色背景像素占整个车牌的70%),当蓝色像素点数量大于设定阈值时,该候选区域判断为车牌区域(颜色特征判断不能确定唯一的车牌区域,比如马路上行驶的车辆(有车牌)、蓝色电瓶车、护栏上的蓝色贴纸);
面积判断:一般情况下,车辆的头部在第一个减速带和第二个减速带之间才会触发摄像机拍摄车辆图片,通过多次做实验,会知道车牌在图片中的最小像素面积和最大像素面积,通过设定一定的面积阈值,再次筛选候选车牌区域;
长宽比判断:车牌的标准尺寸为440mmx140mm, 标准长高比约为3.1,通过把候选车牌区域标记成一个方形,计算方形的长和宽,通过设定一定的长宽比阈值,再次筛选候选车牌区域。
说明:车牌特征还有很多,大家可以多总结总结试一试(比如水平像素跳变比较频繁,车牌在减速带的上方且有一定的距离,等等限制的特征)。
clear;clc;
close all;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%% 1.载入车牌图片并预处理
[fn,pn,fi]=uigetfile('车牌\*.jpg','选择图片');
%fn:图片名字,pn:图片路径,fi:文件类型
img=imread([pn fn]);
figure(1);imshow(img);title('原始图像');
grayimg = rgb2gray(img);
figure(2);imshow(grayimg);title("灰度图像");
H = fspecial('gaussian',5,3); % 高斯模糊
blurred = imfilter(grayimg,H,'replicate');
figure(3); imshow(blurred);title("高斯模糊");
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%% 2.垂直边缘检测和形态学处理
bw = edge(blurred,'sobel','vertical');
figure(4); imshow(bw);title("边缘图像"); % 垂直边缘检测
se1 = strel('rectangle',[30,18]);
bw_close=imclose(bw,se1);
figure(5);imshow(bw_close);title("闭操作");
se2 = strel('rectangle',[21,19]);
bw_open = imopen(bw_close, se2);
figure(6);imshow(bw_open);title("开操作");
bw_close = bwareaopen(bw_open,2500); % 移除小对象
figure(7);imshow(bw_close);title("去除噪声");
se3 = strel('rectangle',[25,17]);
bw_dilate = imdilate(bw_close,se3);
figure(8);imshow(bw_dilate);title("膨胀操作");
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%% 3.取车牌候选区域并基于混合特征精确定位出车牌区域
stats = regionprops(bw_dilate,'BoundingBox','Centroid');
L = length(stats);
fprintf("车牌候选区域的数量:%d \n", L);
index_area = area_judge(stats);
index_color = color_judge(stats,img);
index_ratio = ratio_judge(stats);
index1 = intersect(index_area,index_color);
index = intersect(index1, index_ratio);
bb = stats(index).BoundingBox;
I=img(floor(bb(2))+1:floor(bb(2)+bb(4)),floor(bb(1))+1:floor(bb(1)+bb(3)),:);
figure(9);imshow(I); title("车牌")
imwrite(I, ['plate/',fn])
function index = area_judge(stats)
j = 1;
for i=1:length(stats)
bb = stats(i).BoundingBox;
area = bb(4) * bb(3);
if area<20000
index(j) = i;
j = j+1;
end
end
function index = color_judge(stats,img)
j = 1;
for i=1:length(stats)
bb = stats(i).BoundingBox; % 取预判断的区域
I=img(floor(bb(2))+1:floor(bb(2)+bb(4)),floor(bb(1))+1:floor(bb(1)+bb(3)),:);
% figure(8); imshow(I);
hsv = rgb2hsv(I);
[height,width,~] = size(hsv);
count = 0; % 统计蓝色像素值的数量
for h=1:height
for w=1:width
h_judge = (hsv(h,w,1)>0.55) && (hsv(h,w,1)<0.73);
% s_judge = (hsv(h,w,2)>0.05) && (hsv(h,w,2)<0.7);
% v_judge = (hsv(h,w,3)>0.2) && (hsv(h,w,3)<0.7);
if h_judge
count = count + 1;
end
end
end
pixel_sum = width*height;
if count>0.4*pixel_sum
index(j) = i;
j = j+1;
end
end
function index = ratio_judge(stats)
j = 1;
for i=1:length(stats)
bb = stats(i).BoundingBox;
r = bb(3)/bb(4);
ratio_std = 440/140;
if (r>ratio_std-1.1) && (r