基于MATLAB,使用SVM和ANN实现车牌识别
WHY
本人一直对计算机图像识别和机器学习以及人工神经网络有很浓厚的兴趣,看到了基于openCV(原文)的实现流程,就萌生了在假期时间使用MATLAB进行车牌识别的想法。
在CSDN中查阅了很多相关文章,写下这篇文章算是一个回馈,也是一个总结,顺便在路途中找点事情做。另外本人编程外行,水平有限,不足之处欢迎探讨,代码不规范之处请无视。
HOW
UI用的是MATLAB App,具体实现流程如下:
下面会贴上实现过程及源码:
一、输入图像
global I
[filename, pathname]=uigetfile({
'*.jpg';'*.bmp'}, 'File Selector');
I=imread([pathname '\' filename]);
imshow(I, 'Parent', app.UIAxes);%title('原图');
二-三、图像处理
这部分的重点是用sobel算子进行边缘检测以及用大津法对图像进行二值化处理,设置的参数可以进一步调优。难点是用minboundrect函数画出最小外接矩形,用biasrectoplane提取矩形并进行归一化处理(这里用MATLAB自带的函数不理想,是我自己设计的算法),最后对矩形图像进行初步筛选,得到类车牌矩形,为SVM分类做准备。
主函数
global I
global I_cell
G = fspecial('gaussian', [5 5], 2);
I_blur = imfilter(I,G,'same'); %高斯模糊
imshow(I_blur, 'Parent', app.UIAxes_2);
I_gray = rgb2gray(I_blur); %转化为灰度图
imshow(I_gray, 'Parent', app.UIAxes_3);
[high,width] = size(I_gray); % 获得图像的高度和宽度
F2 = double(I_gray);
U = double(I_gray);
uSobel = I_gray;
for i = 2:high - 1 %sobel边缘检测
for j = 2:width - 1
Gx = (U(i+1,j-1) + 2*U(i+1,j) + F2(i+1,j+1)) - (U(i-1,j-1) + 2*U(i-1,j) + F2(i-1,j+1));
Gy = (U(i-1,j+1) + 2*U(i,j+1) + F2(i+1,j+1)) - (U(i-1,j-1) + 2*U(i,j-1) + F2(i+1,j-1));
uSobel(i,j) = sqrt(Gx^2 + Gy^2);
end
end
I_sobel= im2uint8(uSobel);
imshow(I_sobel, 'Parent', app.UIAxes_4);%画出边缘检测后的图像
level = graythresh(I_sobel); %OTSU 大津法取阈值
I_OTSU=imbinarize(I_sobel,level);
imshow(I_OTSU, 'Parent', app.UIAxes_5);%画出二值化后的图像
se = strel('rectangle', [3 17]); %创建一个平坦的矩形结构,MN指定大小
I_close = imclose(I_OTSU,se); %闭操作
imshow(I_close, 'Parent', app.UIAxes_6);%画出闭操作后的图像
I_contour = bwperim(I_close); %轮廓提取
imshow(I_contour, 'Parent', app.UIAxes_7);%画出轮廓图像
I_fill= imfill(I_contour,'holes');
B = bwboundaries(I_fill, 'noholes'); % B为cell
figure(1)
imshow(I);
hold on;
I_cell = {
};
for k = 1 : length(B)
thisBoundary = B{
k};
[rectx,recty,area,perimeter]=minboundrect(thisBoundary(:, 2), thisBoundary(:, 1),'a');
rectx= floor(rectx);
recty= floor(recty);
[theta,I_crop] = biasrectoplane(rectx,recty,I);
if (~isnan(I_crop)) & (length(I_crop)>100)
I_crop=imresize(I_crop,[36 136]);
I_cell=[I_cell, I_crop];
end
plot(thisBoundary(:, 2), thisBoundary(:, 1), 'r', 'LineWidth', 0.5);
hold on;
line(rectx(:),recty(:),'color','g');
end
figure(2)
for m= 1:length(I_cell)
subplot(1,length(I_cell),m)
imshow(I_cell{
1,m});
hold on
end
minboundrect
function [rectx,recty,area,perimeter] = minboundrect(x,y,metric)
if (nargin<3) || isempty(metric)
metric = 'a';
elseif ~ischar(metric)
error 'metric must be a character flag if it is supplied.'
else
% check for 'a' or 'p'
metric = lower(metric(:)');
ind = strmatch(metric,{
'area','perimeter'});
if isempty(ind)
error 'metric does not match either ''area'' or ''perimeter'''
end
% just keep the first letter.
metric = metric(1);
end
% preprocess data
x=x(:);
y=y(:);
% not many error checks to worry about
n = length(x);
if n~=length(y)
error 'x and y must be the same sizes'
end
if n>3
try
edges = convhull(x,y);
x = x(edges);
y = y(edges);
end
% probably fewer points now, unless the points are fully convex
nedges = length(x) - 1;
elseif n>1
% n must be 2 or 3
nedges = n;
x(end+1) = x(1);
y(end+1) = y(1);