基于Matlab的车牌识别完整教程:从图像预处理到字符识别实战解析

文章目录

引言:为什么用Matlab做车牌识别?

车牌识别的核心流程:5步搞定

第一步:图像预处理------让图片"听话"

[1.1 读取图片 & 转灰度图](#1.1 读取图片 & 转灰度图)

[1.2 去噪滤波](#1.2 去噪滤波)

[1.3 增强对比度](#1.3 增强对比度)

[1.4 二值化处理](#1.4 二值化处理)

第二步:车牌定位------找到车牌在哪里

[2.1 边缘检测](#2.1 边缘检测)

[2.2 形态学操作:让边缘连起来](#2.2 形态学操作:让边缘连起来)

[2.3 筛选车牌区域](#2.3 筛选车牌区域)

第三步:字符分割------把每个字符分开

[3.1 预处理车牌区域](#3.1 预处理车牌区域)

[3.2 计算垂直投影](#3.2 计算垂直投影)

[3.3 找分割点](#3.3 找分割点)

第四步:字符识别------认出每个字符

[4.1 制作模板库](#4.1 制作模板库)

[4.2 模板匹配](#4.2 模板匹配)

第五步:结果输出------展示成果

[常见问题 & 解决方法](#常见问题 & 解决方法)

问题1:车牌倾斜怎么办?

问题2:光线太暗/太亮怎么办?

问题3:字符识别错误怎么办?

总结:动手试试吧!

引言:为什么用Matlab做车牌识别?

说起车牌识别,你可能第一时间想到的是交通摄像头抓拍、停车场自动计费这些场景------但你知道吗?用Matlab也能轻松实现这个功能!作为一个曾经在Matlab里踩过无数坑的技术爱好者,我必须说:Matlab的图像处理工具箱简直是为这类任务量身定做的!它自带的函数库能帮你搞定从图像读取到字符匹配的所有步骤,而且代码量比其他语言少得多,对新手友好到爆炸!今天我就把自己摸索出来的完整流程分享给大家,从入门到实战,保证你看完就能动手做一个简单的车牌识别系统!

车牌识别的核心流程:5步搞定

不管用什么工具,车牌识别的基本逻辑都是一样的。咱们把它拆成5个关键步骤,一步步来:

图像预处理:把原始图片变得更"干净",方便后续操作

车牌定位:从整张图里找出车牌所在的区域

字符分割:把车牌上的每个字符(比如"京A12345"里的每个字)分开

字符识别:识别每个分割出来的字符是什么

结果输出:把识别到的字符组合成完整的车牌号码

听起来是不是很清晰?接下来咱们用Matlab逐个攻破这些步骤!

第一步:图像预处理------让图片"听话"

原始图片往往有很多干扰:比如光线太暗、有噪点、颜色太鲜艳......预处理就是要解决这些问题,让车牌区域更突出。

1.1 读取图片 & 转灰度图

Matlab里读图片用imread()函数,比如img = imread('car.jpg');。但彩色图处理起来太麻烦,咱们先转成灰度图------因为车牌的字符和背景在灰度上差异更大。转灰度用rgb2gray():gray_img = rgb2gray(img);。

1.2 去噪滤波

图片里的小噪点会影响后续的边缘检测,所以得先过滤掉。最常用的是高斯滤波,Matlab里用imgaussfilt():filtered_img = imgaussfilt(gray_img, 1.5);。这里的1.5是滤波半径,数值越大越模糊,自己调一调试试!

1.3 增强对比度

如果图片光线不均,字符和背景的差异会变小。这时候用imadjust()函数增强对比度:adjusted_img = imadjust(filtered_img, [0.2 0.8], []);。括号里的0.2 0.8是输入灰度范围,把这部分拉伸到0-255,对比度一下子就上来了!

1.4 二值化处理

二值化就是把图片变成黑白两色------字符是黑色,背景是白色(或者反过来)。Matlab里用im2bw():binary_img = im2bw(adjusted_img, 0.5);。这里的0.5是阈值,超过的变白色,低于的变黑色。如果效果不好,试试调整这个数值!

超级重要!!! 预处理的效果直接决定后面步骤的成败,一定要多试几次参数,直到图片里的车牌边缘清晰可见!

第二步:车牌定位------找到车牌在哪里

车牌定位是整个流程中最关键也最难的一步。咱们用"边缘检测+形态学操作+区域筛选"的组合拳来搞定它!

2.1 边缘检测

车牌的字符和背景之间有明显的边缘,用Canny边缘检测算法找边缘是最常用的方法。Matlab里用edge()函数:edge_img = edge(binary_img, 'Canny', [0.1 0.3]);。这里的两个阈值控制边缘的灵敏度,自己调调看!

2.2 形态学操作:让边缘连起来

边缘检测后,车牌区域的边缘可能是零散的。咱们用形态学的"闭操作"(膨胀+腐蚀)把这些零散的边缘连在一起,形成一个完整的车牌区域。Matlab里用imclose():

matlab

复制代码

se = strel('rectangle', [15 5]); % 创建一个矩形结构元素

closed_img = imclose(edge_img, se);

这里的15 5是矩形的大小,你可以根据图片尺寸调整------比如图片大就用更大的数值。

2.3 筛选车牌区域

现在图片里有很多连通区域,咱们需要找出符合车牌特征的那个。车牌的特征是什么?一般是:

长宽比大概是3:1(比如标准车牌长440mm,宽140mm)

面积不能太小也不能太大

Matlab里用bwconncomp()找连通区域,再用regionprops()获取每个区域的属性:

matlab

复制代码

stats = regionprops(closed_img, 'BoundingBox', 'Area');

plate_region = [];

for i = 1:length(stats)

bb = stats(i).BoundingBox;

area = stats(i).Area;

width = bb(3);

height = bb(4);

% 筛选长宽比在2.5到3.5之间,面积大于1000的区域

if width/height > 2.5 && width/height <3.5 && area>1000

plate_region = imcrop(gray_img, bb); % 裁剪出车牌区域

break;

end

end

如果找到符合条件的区域,就用imcrop()裁剪出来------这就是咱们要的车牌图片啦!

第三步:字符分割------把每个字符分开

车牌区域找到了,接下来要把每个字符分开。这里最常用的是"垂直投影法"------因为字符之间有空隙,垂直方向上的像素和会出现谷点,谷点就是分割线!

3.1 预处理车牌区域

先把裁剪出来的车牌区域再做一次二值化,确保字符是黑色的:plate_binary = im2bw(plate_region, 0.6);。然后可以用imcomplement()反转一下,让字符变成白色(方便后续处理):plate_binary = imcomplement(plate_binary);。

3.2 计算垂直投影

垂直投影就是计算每一列的白色像素数量。Matlab里用sum()函数:proj = sum(plate_binary, 1);。这里的1表示按列求和。

3.3 找分割点

投影结果里,谷点(数值小的地方)就是字符之间的空隙。咱们可以设置一个阈值,比如投影值小于最大值的10%的地方就是分割点。然后根据这些分割点裁剪出每个字符:

matlab

复制代码

proj = proj/max(proj); % 归一化投影值

split_points = find(proj < 0.1); % 找谷点

% 把分割点分组,得到每个字符的列范围

char_regions = [];

start_col = 1;

for j = 2:length(split_points)

if split_points(j) - split_points(j-1) >5 % 间隔大于5的是字符之间的空隙

end_col = split_points(j-1);

char_regions = [char_regions; start_col end_col];

start_col = split_points(j);

end

end

% 裁剪每个字符

chars = [];

for k =1:size(char_regions,1)

c = imcrop(plate_binary, [char_regions(k,1) 1 char_regions(k,2)-char_regions(k,1)+1 size(plate_binary,1)]);

chars{end+1} = c;

end

这样就能得到每个字符的图片啦!如果字符粘连,可以用imerode()做一次腐蚀操作,把它们分开。

第四步:字符识别------认出每个字符

字符识别最基础的方法是"模板匹配"------把分割出来的字符和咱们提前做好的模板对比,找最像的那个!

4.1 制作模板库

首先得有一个模板库,包含所有可能的车牌字符:汉字(比如"京、沪、粤"等)、字母(A-Z)、数字(0-9)。你可以找一张标准车牌的图片,裁剪出每个字符,保存成单独的图片,比如"jing.png""A.png""1.png"等。然后把这些模板读入Matlab,统一大小(比如20x20像素):

matlab

复制代码

template_dir = 'templates/';

template_files = dir(fullfile(template_dir, '*.png'));

templates = [];

labels = [];

for m=1:length(template_files)

t = imread(fullfile(template_dir, template_files(m).name));

t = imresize(t, [20 20]); % 统一大小

t = im2bw(t,0.5); % 二值化

templates{end+1} = t;

labels{end+1} = template_files(m).name(1:end-4); % 取文件名作为标签

end

4.2 模板匹配

对于每个分割出来的字符,咱们用normxcorr2()计算它和每个模板的相关系数------相关系数越大,说明越像。然后取最大的那个对应的标签就是识别结果:

matlab

复制代码

result = '';

for n=1:length(chars)

char_img = imresize(chars{n}, [20 20]); % 调整字符大小和模板一致

char_img = im2bw(char_img,0.5);

max_corr = 0;

best_label = '';

for p=1:length(templates)

corr = normxcorr2(templates{p}, char_img);

current_max = max(corr(:));

if current_max > max_corr

max_corr = current_max;

best_label = labels{p};

end

end

result = [result best_label];

end

最后result变量里就是咱们识别到的车牌号码啦!

第五步:结果输出------展示成果

识别完成后,咱们可以用disp()函数输出结果,或者在图片上画个框显示车牌区域和识别结果:

matlab

复制代码

% 在原始图片上画框

img_with_plate = img;

bb = stats(i).BoundingBox;

img_with_plate = rectangle('Position', bb, 'EdgeColor', 'red', 'LineWidth',2);

hold on;

% 显示识别结果

text(bb(1), bb(2)-10, result, 'Color','red', 'FontSize',12);

hold off;

imshow(img_with_plate);

disp(['识别到的车牌号码:', result]);

这样就能直观地看到结果啦!

常见问题 & 解决方法

在实战中,你可能会遇到一些问题,这里分享几个我踩过的坑和解决办法:

问题1:车牌倾斜怎么办?

如果车牌是倾斜的,定位和分割都会出错。解决办法是用霍夫变换找倾斜角度,然后旋转图片。Matlab里用hough()函数:

matlab

复制代码

% 找倾斜角度

[H, theta, rho] = hough(edge_img);

peaks = houghpeaks(H, 5);

lines = houghlines(edge_img, theta, rho, peaks);

angle = lines(1).Theta;

if angle >45, angle = angle-90; end

% 旋转图片

rotated_img = imrotate(img, angle, 'bilinear', 'crop');

问题2:光线太暗/太亮怎么办?

用直方图均衡化histeq()增强对比度:equalized_img = histeq(gray_img);。这个函数能让图片的灰度分布更均匀,暗的地方变亮,亮的地方变暗。

问题3:字符识别错误怎么办?

可能是模板库不够全,或者字符预处理不好。试试:

增加更多模板(比如不同字体的字符)

调整字符分割的阈值

对字符做"细化"处理(用bwmorph()函数的'thin'选项)

总结:动手试试吧!

好了,整个流程都讲完了!其实基于Matlab的车牌识别并不难------关键是理解每个步骤的目的,然后灵活运用Matlab的图像处理函数。你可以找一张自己拍的汽车图片,按照这个流程一步步写代码,看看能不能识别出车牌号码!

最后想说:技术学习最忌讳纸上谈兵,一定要动手实践!哪怕一开始识别错误,调整几个参数,多试几次,你一定会看到进步的。希望这篇教程能帮到你,祝你学习愉快!

(注:本文所有代码仅为示例,实际使用时请根据图片情况调整参数和细节哦!)

解每个步骤的目的,然后灵活运用Matlab的图像处理函数。你可以找一张自己拍的汽车图片,按照这个流程一步步写代码,看看能不能识别出车牌号码!

最后想说:技术学习最忌讳纸上谈兵,一定要动手实践!哪怕一开始识别错误,调整几个参数,多试几次,你一定会看到进步的。希望这篇教程能帮到你,祝你学习愉快!

(注:本文所有代码仅为示例,实际使用时请根据图片情况调整参数和细节哦!)

Copyright © 2022 破界远征沙盒工坊 All Rights Reserved.