MATLAB车牌识别课程设计:前处理、定位分割与识别调参实战

发布时间:2026/9/17 8:31:32
MATLAB车牌识别课程设计:前处理、定位分割与识别调参实战 简介面向高校数字图像处理、模式识别课程设计的学生与自学者这份基于MATLAB的车牌识别课程设计文档围绕图像采集、预处理到字符识别的完整链路展开帮助读者掌握车牌定位与字符分割识别的工程实现方法。压缩包共1个docx文件约1.69MB文档结构完整含设计目的与要求、总体方案、各功能模块实现程序及主要函数说明可直接作为课设报告与代码参考。内容重点覆盖腐蚀与膨胀、边缘检测、霍夫变换定位、二值化与字符分割以及模板匹配识别并解释imerode、imdilate等函数的用法与参数。文档还给出环境要求、多幅图像测试与调试思路便于对照复现和排错。目前已有599人学习适合需要完成数字图像处理课程设计、快速搭建MATLAB车牌识别原型的读者参考学习。1. 车牌识别课程设计真正卡住进度的是前处理数字图像处理课程设计里挑车牌识别好处是评价标准很硬车牌框没框出来、字符切没切开、识别率是多少一眼就能看出来。坏处也很明显很多人把时间全砸在找一个「更强的分类器」上最后发现图里连车牌都没被正确框住。真正拖住进度的是前处理光照不均、车牌倾斜、字符粘连任何一步参数没给对后面换什么网络都救不回来。MATLAB 在这个题目里的位置比较特殊。图像处理工具箱把灰度化、边缘检测、形态学、连通域分析、Hough 变换都做成了单行函数不用写一堆胶水代码几百行就能把全流程跑通。代价是这些函数的默认参数对车牌场景并不友好edge的默认阈值、strel的默认形状、imbinarize的默认敏感度都要按车牌的像素尺寸重新定。下面按实际链路走一遍预处理、定位与矫正、字符分割、字符识别、识别率统计。每一段都给可运行的 MATLAB 代码和参数含义重点放在参数改成什么值、改错会看到什么现象。适合正在写课程设计、或者拿到一份 MATLAB 车牌识别源代码却读不懂每行在干什么的人。2. 车牌图像预处理从彩色图到候选边缘图的 MATLAB 链路预处理这一段的目标很明确把原始图变成一张「车牌区域的边缘连成一整块、其余区域尽量干净」的二值图。听起来简单但每一步的输出质量会直接决定后面连通域筛选有没有东西可筛。常见的做法是灰度化、对比度拉伸、边缘提取、形态学闭运算、孔洞填充、小面积清除六步串下来。2.1 灰度化与对比度拉伸的取值依据rgb2gray内部用的是 0.2989R 0.5870G 0.1140B 的加权这个权重来自人眼对绿光最敏感的视锥响应对蓝色车牌来说蓝色通道权重只有 0.114意味着蓝底在灰度图里偏暗白字偏亮对比方向正好合适。拉伸这一步容易被跳过。阴天或者逆光拍的车牌灰度值会挤在一个很窄的区间里比如全图落在 90 到 130 之间这时候边缘检测的梯度幅值普遍偏小固定阈值就会漏掉大量真实边缘。stretchlim的作用是先统计直方图把最暗的 1% 和最亮的 1% 像素找出来当作映射端点中间做线性拉伸两端做饱和截断。I imread(car_01.jpg); I imresize(I, [480 NaN]); % 固定高度 480宽度按比例缩放统一尺度 G im2double(rgb2gray(I)); % 转双精度后续阈值统一按 [0,1] 给 G imadjust(G, stretchlim(G, [0.01 0.99]), []); % 掐掉两端 1% 后线性拉伸 BW edge(G, sobel, 0.12); % 阈值给得偏小宁可多留候选边缘 se strel(rectangle, [5 21]); % 宽扁核形状贴合车牌的长宽比 BW imclose(BW, se); % 闭运算把断开的边缘连成块 BW imfill(BW, holes); % 填掉连通域内部的孔洞 BW bwareaopen(BW, 400); % 去掉面积不足 400 像素的碎块imresize到固定高度这一步值得单独说。strel的尺寸、bwareaopen的面积阈值都是绝对像素值如果输入图分辨率从 640×480 变到 1920×1080同一套参数的效果会完全不同。固定高度等于把尺度问题提前消掉后面所有参数只需要调一次。edge的阈值 0.12 是偏低的。低阈值会让边缘变粗、噪点变多但配合后面的闭运算和小面积清除漏检风险比误检风险更值得防。车牌一旦被漏掉后面任何一步都补不回来误检多几个候选框用几何特征过滤掉就行。2.2 形态学闭运算的选择为什么是宽扁核而不是圆盘imclose是先膨胀后腐蚀效果是把距离小于结构元素尺寸的断裂处连起来同时基本保持原区域大小。车牌是水平方向长、垂直方向短的矩形字符的竖直笔画在水平方向间距只有几个像素而车牌边框在水平方向是连续的。用strel(rectangle,[5 21])垂直方向 5 像素水平方向 21 像素正好把字符之间的小间隙填上又不会把上下相邻的两行文字连成一片。用strel(disk, 8)这种各向同性的核会出问题。圆的直径在水平和垂直方向一样大要做到水平方向连通 21 像素垂直方向也会连 21 像素车牌上下方的保险杠、车灯边缘都会被吸进来候选框会明显变胖甚至框住整辆车。这个差异在小图上不明显一旦分辨率上去就非常突出。2.3 预处理阶段的参数对照表参数所在函数含义车牌场景典型值调大后的现象拉伸区间stretchlim参与映射的像素比例[0.01 0.99]对比度增强变弱暗部细节保留更多边缘阈值edge(sobel)梯度幅值判定门限0.10 ~ 0.15边缘变少车牌边框可能断裂结构元素strel(rectangle)闭运算的核尺寸[5 21]候选框变胖容易吞掉车身区域最小面积bwareaopen连通域面积下限300 ~ 600小尺寸车牌会被当噪点删掉提示这三个参数里strel的尺寸最敏感。换数据集时先固定其它三个只调结构元素观察候选框数量从几十降到个位数的过程比一次性改全部参数更容易定位问题。3. 车牌定位与倾斜矫正连通域筛选加 HSV 辅助判定预处理得到的二值图里车牌区域只是若干连通域中的一个剩下的还有车标、车灯、栅格、文字广告。定位的本质是把这些候选按几何特征和颜色特征排序挑出最像车牌的那个。几何特征负责粗筛颜色特征负责确认角度检测负责把歪掉的车牌摆正。3.1 用 regionprops 做几何特征过滤regionprops一次能返回十几个属性车牌筛选用得上的是四个BoundingBox给出外接矩形Area是连通域真实像素数Extent是面积与外接矩形面积之比Image是裁剪出来的二值小块。中国蓝底车牌的长宽比在 3.1 到 3.4 之间考虑到定位误差和边框缺失判定区间放到 2.2 到 5.5 比较稳。Extent反映连通域的「密实度」矩形物体通常在 0.6 以上字符区域因为笔画之间有间隙Extent只有 0.3 左右这个差异正好能把车牌和纯文字区域区分开。stats regionprops(BW, BoundingBox, Area, Extent); boxes zeros(0, 4); for k 1:numel(stats) bb stats(k).BoundingBox; % 格式为 [x y w h] w bb(3); h bb(4); ar w / h; % 长宽比 fill stats(k).Extent; % 密实度 if ar 2.2 ar 5.5 ... stats(k).Area 800 fill 0.45 h 12 boxes(end1, :) bb; % 通过筛选记入候选 end end三个数值条件各有分工。Area 800保证候选不是小碎片h 12保证垂直方向有足够像素供后面切字符fill 0.45排掉笔画稀疏的文字区域。任何一条放宽都会让候选数量翻倍收紧则可能一个都不剩调试时建议先把结果数量打印出来看。3.2 蓝底车牌的颜色辅助判决几何筛选在光照均匀时够用遇到车身有蓝色贴纸或者广告牌背景就失效了。加一层 HSV 判定能显著降低误检。HSV 里色调 H 和亮度 V 分离蓝底车牌在 H 上集中在 0.55 到 0.65 这个窄区间而蓝色车身因为加了金属漆饱和度 S 通常更高、色调偏移更大。HSV rgb2hsv(I); Hc HSV(:,:,1); Sc HSV(:,:,2); Vc HSV(:,:,3); blue (Hc 0.52) (Hc 0.68) (Sc 0.35) (Vc 0.25); blue imclose(blue, strel(disk, 3)); % 填掉字符造成的镂空 blue bwareaopen(blue, 200); s regionprops(blue, BoundingBox, Area); [~, idx] max([s.Area]); % 取最大的蓝色区域 colorBox s(idx).BoundingBox;颜色掩膜只取最大连通域是有道理的车牌在画面里通常是唯一一块成规模的蓝色矩形取最大比取交集更抗噪。把几何框和颜色框求交并比IOU 超过 0.3 就认定两者指向同一目标否则以颜色框为准因为颜色判定的假阳性率更低。3.3 倾斜矫正用 Hough 变换估计主要边缘角度车牌倾斜一般不超过 ±15 度Hough 变换的角度搜索范围可以限制在 -20 到 20 之间这样累加器的尺寸小很多速度提升明显。houghpeaks找出累加器里最强的几个峰值houghlines把峰值还原成线段取这些线段角度的中位数作为整体倾角。用中位数而不是平均值是因为车身上可能有几条强干扰线中位数在峰值数量少的时候更稳。plate imcrop(I, mergedBox); Gp im2double(rgb2gray(plate)); Bp edge(Gp, canny, [0.08 0.2]); % 双阈值弱边 0.08 强边 0.2 [H, T, R] hough(Bp, Theta, -20:0.5:20); P houghpeaks(H, 5, Threshold, ceil(0.3 * max(H(:)))); lines houghlines(Bp, T, R, P, FillGap, 20, MinLength, 30); ang median([lines.theta]); % 主要边缘的倾角 if abs(ang) 1.5 plate imrotate(plate, -ang, bilinear, crop); endhoughpeaks的阈值取最大值的 30%太低会引入噪声峰太高可能一个峰都找不到。FillGap和MinLength控制线段的合并规则车牌边框长度通常在 100 像素以上MinLength给 30 能滤掉字符笔画形成的短线段。imrotate的角度符号容易搞反如果矫正后文字反而更斜把-ang改成ang即可。3.4 定位失败时的排查顺序现象可能原因检查位置处理方式候选框数量为 0长宽比上界太严ar判定条件上界放宽到 6.5 观察框住整辆车闭运算核太大strel尺寸改成[3 15]框偏左或偏右颜色掩膜被同色车身污染HSV 的 H 区间提高 S 下限到 0.45矫正后字符更斜角度符号取反imrotate参数去掉负号候选框高度不足车牌边框被bwareaopen删掉面积阈值降到 300排查顺序建议从候选框数量开始。数量为 0 说明前面被掐死了数量在 10 个以上说明筛选太松这两种情况的调试方向完全不同先看数量再看位置能省很多时间。4. 字符分割垂直投影法在 MATLAB 里的调参细节车牌框出来之后接下来要把 7 个字符普通蓝牌逐个切开。垂直投影法是最稳的做法把二值图的每一列求和字符所在列的投影值高间隙列的投影值接近 0波谷就是切分点。道理简单但二值化质量、边框剔除、异常宽度处理这三件事做不好切出来的字符数量经常是 6 个或者 8 个。4.1 二值化与上下左右边框的剔除先确认前景极性。蓝底白字车牌在灰度图里是暗底亮字直接imbinarize出来字符是白色前景、背景是黑色方向正确。如果是黄底黑字极性就反了需要取反。自适应二值化的Sensitivity控制局部阈值的高低。给 0.4 到 0.5 之间比较合适太低会让字符笔画断裂太高会把背景纹理也判成前景。plate imcrop(I, mergedBox); Gp im2double(rgb2gray(plate)); Gp imadjust(Gp, stretchlim(Gp, [0.02 0.98]), []); Bp imbinarize(Gp, adaptive, Sensitivity, 0.45); % 用水平投影裁掉上下边框和铆钉 rowSum sum(Bp, 2); ridx find(rowSum 0.6 * max(rowSum)); Bp Bp(ridx(1):ridx(end), :); % 用垂直投影裁掉左右边框 colSum sum(Bp, 1); cidx find(colSum 0.25 * max(colSum)); Bp Bp(:, cidx(1):cidx(end));两个比例系数 0.6 和 0.25 不是随便给的。水平方向用高比例是因为字符上下边缘那一行的投影值接近最大值只保留最饱满的带。垂直方向用低比例是因为左右边框列的投影值只有字符列的几分之一用 0.25 既能裁掉边框又不会误伤第一个字符。4.2 垂直投影与波谷切分分割的核心是把投影曲线里的「低值连续段」识别为间隙。用一个和车牌高度成比例的阈值来判定比绝对像素值更稳。colSum sum(Bp, 1); thr max(2, round(0.06 * size(Bp, 1))); # 阈值随高度自适应 gap colSum thr; d diff([0 gap 0]); # 找连续段的起止 starts find(d 1); ends find(d -1) - 1; ranges [starts(:) ends(:)]; w ranges(:,2) - ranges(:,1) 1; % 宽度过滤太窄是噪点太宽是粘连 keep w 3 w 0.3 * size(Bp, 2); ranges ranges(keep, :);thr取高度的 6%意味着只要某一列的白色像素超过整高的 6% 就认为是字符的一部分。这个比例调到 0.1 以上粘连字符之间那道浅间隙会被判成字符内部两个字符合成一个调到 0.03 以下字符内部笔画稀疏的列会被误判为间隙一个字符裂成两个。宽度过滤的两个边界来源于字符的实际宽度。单个字符宽度大约占车牌宽度的 1/8 到 1/100.3 * size(Bp,2)这个上界留了很大余量主要用来兜住数字 1 和字母 I 这种窄字符。下界 3 像素纯粹是去噪。4.3 字符归一化到统一尺寸识别环节要求输入尺寸一致模板匹配和神经网络都一样。imresize用双线性插值比最近邻更平滑对细笔画字符更友好。target [40 20]; % 高 40宽 20 chrImgs cell(size(ranges, 1), 1); for k 1:size(ranges, 1) seg Bp(:, ranges(k,1):ranges(k,2)); chrImgs{k} imresize(seg, target); % 双线性插值 end40×20 这个尺寸来自经验折中。高度 40 能保留笔画细节宽度 20 接近常见字符的宽高比。尺寸再大会让后面的特征维度上升BP 网络的输入层和权重大幅增加训练时间变长而准确率提升有限。尺寸再小数字 8 的上下两个环可能糊成一团。4.4 分割异常与参数对照现象原因涉及参数处理方向少切一个字符字符间粘连thr偏低提到高度的 0.08一个字符裂成两块笔画稀疏处被切断thr偏高降到高度的 0.04多出小碎片钉、边框残留宽度下界提到 4 像素以上首尾字符被裁掉边框剔除过度cidx比例从 0.25 降到 0.15提示分割结果最好输出成一张拼接图7 个归一化后的字符横向排开肉眼扫一眼就能看出是切少了还是切多了比逐个打印宽度数值快得多。5. 字符识别模板匹配与 BP 神经网络两条实现路线切出 7 个 40×20 的小图之后识别就是把每张图映射到 34 个类别10 个数字加 24 个字母去掉容易混淆的 I 和 O。课程设计里通常两条路线都用得上模板匹配三五十分钟能跑出结果用作基线BP 神经网络多花几个小时训练用来在报告里体现深度学习的部分。5.1 模板匹配的相似度计算与模板库构建模板匹配的关键在于相似度函数的选择。直接算像素差值平方和对尺寸和位移非常敏感把字符整体平移一两个像素分数就掉一半。用交并比IOU更稳它衡量的是两个二值形状的重合程度对轻微形变更宽容。function score iouScore(a, b) a logical(a(:)); b logical(b(:)); inter sum(a b); union sum(a | b); score inter / union; % 交集除以并集范围 [0,1] end模板库的构建质量决定上限。每个字符至少准备 5 到 8 个不同字体、不同粗细的样本取归一化后的平均或者直接保留多份识别时取最高分。模板太少的话遇到训练集里没出现过的字体正确率会掉得很厉害。单张图像的完整识别循环大致如下labels 0123456789ABCDEFGHJKLMNPQRSTUVWXYZ; best zeros(1, numel(chrImgs)); for k 1:numel(chrImgs) scores zeros(1, numel(templates)); for t 1:numel(templates) scores(t) iouScore(chrImgs{k}, templates{t}); end [~, mi] max(scores); best(k) mi; end两层循环的复杂度是字符数乘以模板数乘以像素数对 7 个字符和 200 个模板来说一次识别大约几百万次逻辑运算在 MATLAB 里跑不到一秒。这个速度足够做批量测试。5.2 BP 神经网络训练与 mapminmax 归一化用神经网络做字符分类输入是 40×20 拉平成 800 维的特征向量输出是 34 维的独热编码。中间隐层用两个节点数按样本规模给样本量在几千张时[64 32]是个不错的起点。mapminmax这一步不能省。二值图拉平后每个维度只有 0 和 1 两个取值但不同字符的白色像素比例差异很大直接送进网络会让梯度更新偏向像素多的维度。归一化把每个维度独立映射到 [0,1]同时记录映射参数测试时必须复用同一套参数不能重新计算。X zeros(800, numel(chrImgs)); for k 1:numel(chrImgs) X(:, k) double(chrImgs{k}(:)); end T full(ind2vec(labelsIdx)); % 类别索引转独热矩阵 [Xn, ps] mapminmax(X, 0, 1); % 归一化并记录映射参数 net feedforwardnet([64 32]); % 两个隐层 net.trainParam.epochs 2000; net.trainParam.goal 1e-4; net.trainParam.showWindow false; net train(net, Xn, T); % 测试阶段必须复用 ps不能重新算 Xtest mapminmax(apply, XtestRaw, ps); Y net(Xtest);epochs给 2000 是比较保守的设置配合goal为 1e-4 的误差目标通常几百轮就收敛。showWindow关掉训练窗口在批量跑实验时很有用否则每跑一次弹一个窗口会拖慢速度。注意训练集和测试集必须来自不同的拍摄批次。同一个车牌切出来的字符分到两边测试准确率会虚高十几个百分点这是课程设计里最常见的自欺欺人。5.3 混淆矩阵与识别率统计单看总准确率没用要看出错集中在哪几个字符上。confusionmat给出的矩阵对角线是正确分类非对角线是混淆对。数字 0 和字母 O、数字 1 和字母 I、数字 8 和字母 B 是最常见的三对混淆。[~, predIdx] max(Y, [], 1); [~, trueIdx] max(T, [], 1); C confusionmat(trueIdx, predIdx); acc sum(diag(C)) / sum(C(:)); [~, order] sort(sum(C, 2) - diag(C), descend); worst order(1:5); % 错误最多的五个类别把worst对应的字符拉出来单独看样本往往能发现问题要么是这类字符的模板库只有两份要么是这类字符在训练集里本来就少。针对性地补样本比盲目加大网络规模有效得多。6. 用消融实验把车牌识别课程设计的结论做实课程设计的报告里如果只写一个最终的识别率说服力很有限因为这个数字受拍摄条件、车牌数量、参数取值的影响太大。更靠谱的做法是做几组对照实验把每个环节的贡献量化出来这样即使绝对数字不高结论也是站得住的。6.1 预处理环节的消融把imadjust这一步拿掉其它代码完全不动在两组图上分别跑一组是白天顺光拍的一组是地下车库或者逆光拍的。顺光组的结果几乎不变逆光组的定位成功率通常会掉 20 个百分点以上。这个对比能直接说明对比度拉伸不是可有可无的一步只在特定光照下才起作用。具体做法是写一个开关参数function [BW, box] locatePlate(imgPath, useStretch) I imresize(imread(imgPath), [480 NaN]); G im2double(rgb2gray(I)); if useStretch G imadjust(G, stretchlim(G, [0.01 0.99]), []); end % 后续流程与前面保持一致 end跑两轮循环把useStretch分别设为true和false统计定位成功率。成功率定义为定位框与人工标注框的 IOU 大于 0.5。6.2 识别器的横向对比模板匹配和 BP 神经网络在不同样本量下的表现差别很大。样本少于 300 张时模板匹配靠人工设计的形状先验反而更稳样本超过 1000 张之后神经网络的隐层能学到字体粗细、倾斜这类模板无法表达的差异准确率会反超。实验组变量观察量预期结论预处理消融有无imadjust定位成功率顺光几乎无差逆光差 20% 以上识别器对比模板匹配 / BP单字符准确率样本 300 时模板更稳 1000 时 BP 反超结构元素消融strel从[5 21]到[9 31]候选框数量数量翻倍误检率上升但漏检下降归一化尺寸40×20 / 20×10训练时长与准确率尺寸减半时训练快约 3 倍准确率掉 2 到 4 个点这张表本身就可以直接搬进课程设计报告每一行对应的实验跑一遍大概十几分钟四组加起来一个下午能出结果。6.3 一个容易被忽略的验证技巧统计识别率时把错误样本的原始车牌图和分割结果一起保存下来命名规则用「真实车牌号_识别结果.jpg」。跑完一批数据后按文件名排序肉眼扫一遍错误列表很快就能看出规律可能是某几种字体被系统性认错也可能是某个拍摄角度下分割总是多切一个字符。按车牌整体统计和按单字符统计要分开报。整体正确率要求 7 个字符全对通常比单字符准确率低 15 到 25 个百分点这两个数字在报告里都有意义混在一起写会让人误判系统的实际水平。批量跑的时候建议把每张图的中间结果二值图、分割字符、识别结果一起存盘回头复查不用重新跑一遍流程。本文还有配套的精品资源点击获取

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询