资讯动态

MATLAB夜间车牌识别:图像增强、字符分割与参数调优全流程

发布时间:2026/10/13 14:21:06 来源:尧图企业网站定制
简介一份面向夜间环境的MATLAB车牌识别项目仿真程序专为图像处理入门者、高校学生及算法爱好者设计。程序完整覆盖从图像预处理到车牌定位识别的典型流程先将彩色图转灰度图并计算灰度直方图再依据夜间光线特点选择合适的阈值完成二值化随后借助边缘检测与连通组件分析锁定车牌区域最后通过字符分割与匹配输出识别结果。资源包共4个文件以主程序脚本为核心附带示例图片、访问链接及数据库支撑文件压缩包仅37KB便于快速下载与运行。目前已有240人学习使用。通过研读程序源码与运行效果可掌握灰度直方图分析、全局与自适应阈值算法、二值化处理等关键知识点并学习MATLAB图像处理函数库如graythresh、imbinarize、bwlabel等的实际应用为后续深入研究车牌识别或目标检测打下扎实基础。1. 夜间车牌识别难点不在识别而在“能不能让车牌先显形”夜间车牌识别仿真程序听起来像是算法问题实际上 70% 的工作量在“让车牌先显形”。白天光照均匀车牌是边界清楚、对比度足够的矩形到了夜里车灯、路灯、补光灯把画面搅成一锅粥车牌底色严重偏色字符边缘要么被强光吞掉要么淹没在噪点里。很多处理流程在白天测试集上准确率接近 100%换到夜间场景直接跌到一半以下问题大多不是识别模型不行而是车牌定位环节没扛住夜间的光照条件。这个选题特别适合课程设计、毕业设计或者课题预研它能顺带把数字图像处理的主干流程全部串起来而且每一步都可以用 MATLAB 可视化窗口观察中间结果。先按传统图像处理流程把第一版跑通后续再决定要不要接深度学习也会更清楚瓶颈到底在前端还是后端。2. 从成像到可见夜间图像增强与车牌区域定位2.1 夜间图像为什么直接二值化会翻车先看直方图和亮度分布夜间图像在成像端有三个明显特征整体亮度低、动态范围大、噪声点多。直接对灰度图做全局二值化比如用 graythresh 求 Otsu 阈值通常得到一张要么全是黑、要么全是白斑的图因为夜间图像直方图中背景和目标几乎叠在一起阈值会把大量背景划成前景。我拿到夜间车牌图的第一件事永远是先看直方图确认这张图是整体偏暗还是明暗两极分化。全局直方图均衡化做一次之后再看如果直方图变成均匀分布不代表对比度真的恢复了它只是把灰度重新排列了一遍夜间车灯造成的局部过曝区域仍然存在。常见做法是先用自适应直方图均衡化恢复局部对比度。MATLAB 的 adapthisteq 把图像分成若干小块在每个块内部做对比度拉伸这对夜间光照不均非常有效。img imread(night_plate.jpg); gray rgb2gray(img); % 自适应直方图均衡8x8小块内分别增强ClipLimit限制局部对比度放大倍数 enhanced adapthisteq(gray, NumTiles, [8 8], ClipLimit, 0.02); % 查看灰度分布判断是否需要继续调整 figure; subplot(2,2,1); imshow(gray); title(原图灰度); subplot(2,2,2); imhist(gray); title(原图直方图); subplot(2,2,3); imshow(enhanced); title(增强后); subplot(2,2,4); imhist(enhanced); title(增强后直方图);这段代码做的事情是转灰度图、局部对比度增强、把增强前后的图像和直方图摆在一起对比。NumTiles 设成 [8 8] 表示图像被切分成 8×8 块以 640×480 的输入为例每块大约 80×60 像素块内独立均衡这样能避免车灯的高亮区域影响整张图的对比度。ClipLimit 设成 0.02 是一个比较保守的拉伸强度可以防止局部增强过头把噪点放大。块数越多细节恢复得越细腻但计算量也越大块边界可能出现明暗割裂感通常 [4 4] 到 [12 12] 都可以图像分辨率越高块可以越多。ClipLimit 建议从 0.01 到 0.05 之间试0.1 以上很容易出现白边和伪影。如果增强之后直方图仍然是明显的两极分布说明存在严重过曝或欠曝区域下一步就需要做光照分量校正。这里有一个轻量方案用一个大尺寸的高斯滤波器估计图像背景亮度再以指数拉伸的方式把前景拉回中间灰度。bg imgaussfilt(gray, 15); % 基于背景亮度估计每个像素的gamma值暗区提高、亮区压暗 gamma log(0.5) ./ log(bg ./ 255 0.01); corrected 255 .* (gray ./ 255).^gamma; corrected uint8(corrected);这段代码用局部背景亮度估计一个 gamma 映射对暗区做指数增益、对亮区做压缩。实际操作中不需要每张图都用只有当 adapthisteq 之后字符和底色对比度仍然不够时才会加进去。gamma 计算里的 0.01 是为了防止除零如果你的图像分辨率很高、背景尺度很大可以把 imgaussfilt 的 sigma 从 15 提高到 30让背景估计更平滑。增强完成后再做边缘检测就比直接在原始夜图上做稳定得多。Sobel 边缘检测对噪声极其敏感夜间原图里的传感器噪点会被当成边缘导致后续车牌区域候选框变成几十个增强以后字符和底色的对度拉开边缘图里的假边缘才会明显少下去。这里有一个容易忽略的经验如果边缘图上车牌字符连成一片、内部全是白色说明增强强度太大ClipLimit 要往下降如果车牌边框断裂成好几段说明增强不够或者边缘阈值太高需要先把 ClipLimit 调上去而不是急着改 Sobel 阈值。2.2 用颜色和边缘先锁定车牌“嫌疑区”夜间车牌定位不能只靠单一特征。只看边缘车灯、路牌、车身反光都会形成矩形轮廓只看颜色夜间偏色会让蓝色车牌的 H 值范围变得很不可靠。常见方案是双重判据先用 HSV 空间的蓝色范围圈出候选区域再与边缘检测结果做逻辑与然后形态学闭运算把分散边缘连成整块最后按几何特征筛选。hsv rgb2hsv(img); % 蓝色区域H在蓝到紫区间S不低于0.15V不超过0.9排除高光 maskBlue (hsv(:,:,1) 0.55 hsv(:,:,1) 0.75) ... (hsv(:,:,2) 0.15) (hsv(:,:,3) 0.9); edgeMap edge(enhanced, sobel, 0.08); % 先膨胀把字符边缘连起来再用横向矩形结构元做闭运算 candidate imdilate(maskBlue edgeMap, strel(rectangle, [5 5])); candidate imclose(candidate, strel(rectangle, [15 9])); % 连通域几何属性筛选 cc bwconncomp(candidate); stats regionprops(cc, BoundingBox, Area, Extent); boxes reshape([stats.BoundingBox], 4, []); areas [stats.Area]; imgArea size(img, 1) * size(img, 2); ratio boxes(:,3) ./ max(boxes(:,4), 1); validIdx find(ratio 2.2 ratio 4.5 ... areas imgArea*0.002 areas imgArea*0.03 ... [stats.Extent] 0.6); validBoxes boxes(validIdx, :); imshow(insertShape(img, Rectangle, validBoxes, LineWidth, 2));这段代码里有几个参数值得反复微调。HSV 里的 V 阈值 0.9 非常关键它能把车灯和白色反光滤掉因为车灯虽然可能发蓝但亮度值接近 1蓝底车牌即使在车灯照射下底色平均亮度也很少到 1。S 阈值 0.15 是为了容忍夜间低照度导致的饱和度下降如果设得太高偏白的蓝色车牌会被漏掉如果设得太低灰白色车身噪声也会混进来。Sobel 阈值 0.08 是一个相对边缘强度的取值判断标准是边缘图上不能充满碎点如果碎点太多就调大边缘断裂就调小。闭运算结构元 [15 9] 是专门为车牌长宽比设计的。横向长度 15 能把字符之间的间隔和边缘断裂处搭起来纵向宽度 9 又能避免把路肩、栏杆这类横向线条也连进来。如果候选区域出现大量横贯整图的块多半是闭运算纵向尺寸太大改成 [15 5] 试试如果车牌内部边缘还是断得太厉害把闭运算前的膨胀尺寸改成 [7 5] 更有效。几何筛选用宽高比 2.24.5、面积占整图 0.2%3%、Extent 大于 0.6 三个条件能用最简单的方式去掉车灯和反光条。国内常见车牌宽高比是 3.14 左右但夜间图像里车牌可能因为拍摄角度发生透视变形所以范围放宽到 2.24.5。面积上下限都用相对值而不是绝对像素这样不同分辨率摄像头拍的图都能适用。筛选后如果还有多个候选框可以按蓝色像素占比排序取蓝色像素占比最高的那个。这一步做完基本就能拿到一个包含车牌区域的矩形框接下来就是把这个矩形“切”成字符。3. 字符分割与归一化把车牌“切”成能认的字3.1 投影分割为什么夜间字符粘连更严重定位到车牌矩形区域之后下一步是把它切成单个字符。最常见的方法是先灰度化和二值化再做水平投影和垂直投影水平投影找字符行的上下边界垂直投影找每个字符的左右边界。白天图像字符和底色对比度高投影曲线会出现清晰的峰谷交替夜间字符边缘因为反光断裂相邻字符又可能被过曝光斑粘在一起投影谷底被噪声填平分割点就会选错。字符分割错了后面识别器再强也救不回来所以这一步我会把中间变量全部显示出来而不是闷头调参数。plateGray rgb2gray(plateImg); % 自适应阈值比全局阈值更抗夜间光照不均 plateBin imbinarize(plateGray, adaptive, ForegroundPolarity, dark, Sensitivity, 0.45); plateBin imopen(plateBin, strel(rectangle, [2 2])); rowProj sum(plateBin, 2); rows find(rowProj 0); top rows(1); bottom rows(end); plateBin plateBin(top:bottom, :); colProj sum(plateBin, 1); % 投影值超过最大投影10%的列认为是字符区 isChar colProj max(colProj) * 0.1; % 连续True区间转成字符左右边界二值化用 imbinarize 的 adaptive 模式是夜间分割的关键。ForegroundPolarity 设成 dark意思是把较暗像素当作前景。对蓝底白字车牌来说蓝色底在灰度变换后偏暗、白色字符偏亮所以把暗色当前景反而能把字符轮廓从亮背景里分离出来如果设成 bright得到的就是蓝色底区域字符变成空白投影分割也会跟着反向。Sensitivity 0.45 是折中值太大会把噪点和底色颗粒当字符太小会导致字符内部出现孔洞和断笔。对分辨率较低的车牌图建议降到 0.3 左右再配合 imopen 去掉孤立噪点。分割时最常遇到的是字符粘连。一种补救是先腐蚀一次再投影用 1×2 的矩形结构元腐蚀把两个字符之间若有若无的连接线断开代价是字符笔画会细一圈另一种是改用 bwlabel 直接提取连通域再用 regionprops 的 BoundingBox 判断每个块的宽高。我通常把两种方法都写进流程里先投影法拿到粗切点再逐块检查宽度如果某个块宽度超过平均宽度的两倍就按垂直投影谷底拆成两个如果某个块宽度小于平均宽度的一半就判定为噪声丢弃。投影分割还有一个隐蔽问题车牌边框。二值化后车牌边框和字符一样都是暗色前景水平投影会把边框算进去导致 top 和 bottom 不准。处理方法是在二值化之后、投影之前先去掉外边框比如用 imopen 配合较大的横向结构元保留字符区域或者先做连通域分析去掉与外接矩形边缘重叠的连通域。这个细节很容易被忽略很多仿真程序分割正确率低不是投影算法不行是边框污染了投影数据。3.2 归一化与模板匹配用最少的样本把识别率拉起来分割得到的字符块尺寸各不相同夜间光照变化还会让同一字符的笔画粗细不同识别前必须统一尺寸。模板匹配是最适合 MATLAB 仿真实验的识别方式不需要训练字符库只包含数字、字母、省简称几十个模板足以完成基础识别。归一化目标尺寸根据字符宽高比设定字母数字建议用 40×20中文字符建议单独用 40×40。resized imresize(charImg, [40 20], bilinear); % 归一化后再二值化保证和模板的二值化方式一致 resized imbinarize(resized, adaptive, Sensitivity, 0.4); cc normxcorr2(resized, tmpl); mscore max(cc(:));normxcorr2 计算归一化互相关直白地说就是在模板图像里滑动搜索字符图像看哪个位置最像然后返回相似度峰值。用它而不是直接算像素差是因为归一化相关对整体亮度变化不敏感夜间车牌同一字符可能半亮半暗直接做差会把字符的亮度差异误判成内容差异。模板匹配的坑在模板库的构建。直接从网上找的字符截图通常跟实际识别图像里的字体、笔画粗细不一致匹配分数会整体偏低。更可靠的做法是先收集一组已经分割好的标准字符图统一灰度化、二值化、归一化后再存成 .mat 文件保证模板和待识别字符来自同一套生成流程。同一个字符如果既存了粗体又存了细体匹配时取最高分即可但数量多了反而可能造成干扰。function buildTemplates(srcDir, outPath) files dir(fullfile(srcDir, *.png)); for i 1:length(files) im imread(fullfile(srcDir, files(i).name)); im imresize(im, [40 20]); im imbinarize(im, adaptive, Sensitivity, 0.4); tmpl im; label files(i).name(1:end-4); save(fullfile(outPath, [label .mat]), tmpl); end end这段模板构建脚本有几个关键约定。srcDir 里的源文件名必须直接以字符内容命名比如 “A.png”、“京.png”脚本会取文件名作为模板标签。二值化方式和前面识别流程要保持一致如果一个用 adaptive、一个用全局阈值模板和待识别字符的形态就可能对不上。归一化尺寸写 40×20如果你的字符源图本身包含上下边框建议先把边框裁剪掉再归一化否则模板里会残留一条横向黑线干扰匹配分数。字符分割后的顺序也需要专门处理。正常车牌顺序是省简称汉字 字母 数字但连通域分析返回的块顺序是随机的必须按每个块中心 x 坐标从左到右排序。排序后把结果拼接成字符串这就是最终识别输出。核对顺序这一步在白天图像上可能觉得多余但夜间分割常会带出一个车牌边框碎片它的中心 x 坐标比首字符还靠左如果不排序就会把边框当成字符。常见做法是按中心 x 坐标排序后再用宽度比例过滤异常边界块保证输出字符串里没有明显过宽或过窄的“伪字符”。4. 工况参数与识别器调优让夜间识别从“能跑”到“能看”仿真程序能跑通是一回事能在一组夜间图上稳定输出是另一回事。这一章要讲的是三个调整点二值化灵敏度、形态学结构元、面积阈值。每个都有很具体的影响路径不到万不得已不要同时改几个参数否则很容易陷入“改了阈值误检变大再改结构元字符断裂”的死循环。4.1 三个决定成败的关键参数二值化阈值、形态学结构元、最小车牌面积先看二值化阈值。准确说是 imbinarize 的 Sensitivity。它决定了多暗的像素算前景Sensitivity 越大前景就越多。夜间图像光照不均同一个字符在暗区可能笔画发灰在亮区可能笔画发白如果 Sensitivity 过小发白的笔画会被漏掉字符变成虚线如果过大底色的噪声会被当成前景字符连成一片。经验是先把 Sensitivity 设 0.4然后只看单个字符的垂直投影一个字符的垂直投影应该是平滑的倒 U 形如果出现很多毛刺说明 Sensitivity 偏大如果投影高度突然掉到接近 0说明偏小。形态学结构元的尺寸和方向需要跟车牌形状匹配。车牌是横向矩形字符间隙主要在水平方向因此闭运算结构元一般选横向矩形常用 [15 9] 或 [15 5]。车载摄像头拍摄的车牌可能存在透视变形横向间距被压缩这时候 [15 5] 比 [15 9] 更不容易把相邻字符连起来。结构元太大会让分割阶段直接崩溃因为字符粘连成一整块结构元太小车牌内部边缘连不起来候选框会碎成几段。判断标准就是画出来看候选框应该完整覆盖车牌但不能比车牌四周多出太多。最小车牌面积这个参数常被忽略。很多同学喜欢写死一个像素值比如 area 5000换一张分辨率更大的图马上失效。正确做法是用相对面积也就是车牌区域占整图面积的比例。一般白天车牌占比 0.0030.02夜间因为灯光干扰和透视变形范围放宽到 0.0020.03。设下限是为了滤除远处的小灯点设上限是为了把近处的大面积车身反光滤掉。这个参数与 HSV 的 V 阈值配合使用V 阈值滤高光面积上限滤大色块两个参数覆盖的场景并不重叠。params struct(clipLimit, 0.02, ... sensitivity, 0.45, ... sobelThresh, 0.08, ... areaMin, 0.002, ... areaMax, 0.03);这里把这些参数集中成一个结构体是为了后面做批量测试时方便循环。每次调参只改一个字段运行完记录准确率改回原值再试下一个字段这是排除参数交互影响最有效的方式。4.2 先抑制眩光再检测边缘夜间预处理顺序可以省一半调试时间夜间图像往往同时存在车灯过曝和暗部细节丢失两种情况。如果一上来就做边缘检测车灯边缘会被检测成高亮的轮廓圈车牌字符的边缘反而因为过曝被吞没。我的习惯是先做一次光照归一化再进入边缘检测和颜色判断。光照归一化不一定要用复杂的模型用一个大尺度闭运算估计背景亮度再把偏离背景太远的像素向背景拉回即可。bg imclose(gray, strel(disk, 20)); under gray bg * 0.75; over gray bg * 1.25; grayCorr gray; grayCorr(under) bg(under); grayCorr(over) bg(over);这段代码做的事情是用半径为 20 的圆形结构元做闭运算得到局部背景亮度估计。灰度值低于背景亮度 75% 的像素判定为暗部过暗替换成背景亮度高于背景亮度 125% 的像素判定为高光眩光也替换成背景亮度。这样车牌字符的笔画不会被完全抹掉但车灯造成的极端亮区和夜色造成的极端暗区会被拉回到正常范围后续的边缘检测阈值就可以固定在一个更窄的区间里。要注意的是这个预处理只对局部极端值做替换不会改变车牌本身的结构。背景估计的圆形结构元半径如果太小会把车牌字符的笔画当成背景导致字符被填平如果太大背景估计失去局部性眩光区域仍然存在。半径在 15 到 30 之间根据图像分辨率缩放原则是结构元尺寸至少要比车牌字符笔画粗 3 倍以上但又小于车牌短边。这样灯光和阴影会被平滑掉字符和底色的局部对比保留下来。眩光抑制之后整个流程顺序就是灰度化 → 自适应直方图均衡 → 光照归一化 → HSV 颜色分割 边缘检测 → 形态学闭运算 → 几何筛选。顺序变了参数也会跟着变。比如先生成颜色分割再做光照归一化颜色分割的 V 阈值就必须重新标定因为归一化已经改变了亮度分布。4.3 用批量测试代替肉眼调参一组图像跑出准确率曲线单张图像调参的致命问题是“看着这张图调好了换下一张直接崩”。所以在参数定下来之前一定先建立一个 2030 张的验证集里面包含不同距离、不同角度、不同灯光方向的车牌图然后写一个循环批量跑每次只记录定位成功、分割成功、识别成功三个数字。通过对比三段准确率才能知道瓶颈在哪里。testFiles dir(testSet/*.jpg); for k 1:length(testFiles) img imread(fullfile(testSet, testFiles(k).name)); try [box, chars] runNightPlatePipeline(img); fprintf(%s: 定位%.1f 分割%.1f 识别%s\n, testFiles(k).name, ... iou(box, truth(k).box), segAcc(chars, truth(k).chars), chars); catch ME fprintf(%s: 失败 - %s\n, testFiles(k).name, ME.message); end end这个循环把整条流水线封装成函数 runNightPlatePipeline它负责返回候选框和识别字符串。定位是否成功用 IoU 判断即候选框和真值框的重叠程度分割是否成功是比较分割出的字符数量和真值数量是否一致识别成功就是字符串完全相同。三个指标分开统计之后很容易看到如果定位准确率只有 60%就别浪费时间调模板匹配先把光照归一化参数找对。批量跑完再把失败图像单独拿出来看中间变量把失败原因按“定位失败”“分割失败”“识别失败”分类按出现次数最多的类别去调对应环节的参数这才是有效的调参路径。批量测试还能暴露出单张测试永远看不出来的问题就是参数对分辨率敏感。同一个 Sensitivity 在 640×480 图上效果好在 1920×1080 图上可能完全失效。这时候把输入图像统一缩放到宽度 640再送进流程会让后续所有参数都变得更加可复用。很多成熟的仿真程序都在入口做这个预处理不仅仅是为了速度更是为了把阈值和结构元尺寸固定在同一个尺度上。提示不要同时改多个参数每次只动一个并且用曲线记录结果否则很难判断是哪次改动提升了准确率。5. MATLAB夜间车牌识别避坑指南五个踩过就忘不掉的坑5.1 车灯亮斑被当成车牌边缘检测把高光轮廓当成了矩形现象候选框圈在车灯或者白色反光条上裁剪下来的图片整块发白字符区域根本不存在。原因车灯在图像中是一个高亮区域其边缘在 Sobel 边缘检测里非常清晰形成了完整矩形或近圆形轮廓如果 HSV 颜色分割的 V 阈值没有排除高亮区域车灯的蓝白色区域也会被当成候选蓝底。解决在颜色分割时把 V 上限定在 0.850.9只保留亮度适中的蓝色区域在几何筛选时增加 Extent 判断车灯亮斑的 Extent 通常远大于 0.8而车牌字符区域是分散的一般在 0.60.8如果候选框内蓝色像素占比不足 30%直接丢弃。这三个条件加在一起能滤掉绝大多数灯斑误检。5.2 蓝底车牌被识别成“白底”色温偏黄导致蓝色通道失效现象肉眼看清是蓝底白字但 HSV 分割的蓝色掩膜只有零散几块车牌框要么偏移要么只框住一半。原因夜间路灯偏暖色调相机会自动白平衡导致车牌蓝底被补偿成青白色或灰白色B 通道绝对值明显下降H 值偏离蓝色范围。解决不要只看 HSV 的 H 范围改用相对颜色判据计算 B 通道与 R、G 通道最大值的差blueDiff B - max(R, G)只要差值大于阈值就认为是蓝色区域。这种判据对整体亮度不敏感只要图像里还有蓝色分量就能识别。常用阈值是 1525配合 V 阈值排除高光基本能覆盖夜间色温偏移的情况。blueDiff double(rgbImg(:,:,3)) - max(double(rgbImg(:,:,1)), double(rgbImg(:,:,2))); maskBlue (blueDiff 20) (hsv(:,:,2) 0.1);5.3 字符断裂和粘连同时出现垂直投影怎么切都不对现象分割出的字符列表要么比真值多要么比真值少有时候两个字符被切成一个“日”形块。原因夜间车牌字符在阴影区域断笔在灯光区域又半过曝自适应二值化 Sensitivity 若取固定值无法同时适应亮区和暗区。过曝区域字符边缘互相融合暗区笔画大量空洞投影曲线的谷底被噪声填平。解决先用 1×2 的矩形结构元腐蚀一次把微弱粘连断开再用 bwlabel 提取连通域统计每个块的宽度中位数把宽度明显大于中位数 1.8 倍的块按垂直投影谷底拆分把宽度明显过小的块丢弃。如果还是不行把 Sensitivity 从 0.45 降到 0.35并增加一步光照归一化让整张车牌图的亮度先拉平再二值化。5.4 仿真图像测试很漂亮真实夜间照片一测就崩现象用仿真图或者白天缩曝光模拟的夜间图流程跑得又快又准换到真实夜色下用手机或摄像头拍的图定位率大跌有些图甚至连字符都切不出来。原因仿真图没有体现真实夜间成像的噪声、模糊和眩光。夜间传感器在低照度下会产生大量亮度噪声车牌轻微运动或手抖会造成模糊这些都会让边缘检测和二值化同时失真。这就是夜间图像调参最容易遇到的玄学仿真集上的准确率再高也不能证明实拍集有效。解决把验证集拆成“仿真图”和“实拍图”两组分别统计准确率。从头就把所有参数放在实拍图上调至少要有 20 张不同角度、不同距离的真实夜间车牌图否则程序只能叫“能跑”不能叫“可用”。如果实拍图不足就先做图像预处理增强再定位不要反过来改识别部分。5.5 英文数字识别高、中文汉字识别低模板匹配对中文不太够用现象字母和数字识别率接近 95%省简称汉字识别率只有 60% 左右经常把“京”认成别的字。原因汉字笔画多、结构复杂归一化到 40×20 后笔画糊成一团模板匹配只考虑了整体像素相似没有利用汉字的笔画特征。汉字模板的字体和实际车牌字体不一致时相关性会大幅下降。解决把汉字单独用 40×40 或 60×60 尺寸归一化避免长宽变形太厉害在模板库里为每个汉字准备两种不同笔画粗细的模板匹配时取最高分同时补充一个笔画密度特征比如用连通域数量作为汉字类别的粗判先把候选汉字缩小到 23 个再和模板做精确匹配。这样能明显提高汉字识别率而不需要额外投入分类器训练。6. 把夜间识别仿真做到可交付一种按阶段统计准确率的验证方法仿真程序做出来之后最容易被问的问题是“你的准确率到底是多少”。如果只说“感觉大部分都能识别”别人没法复现你的结论。我会在流程最后加一个验证脚本按定位、分割、识别三个阶段分别统计准确率并把这个结果连同中间变量一起保存。这样的好处是你可以指着曲线告诉别人“定位率 85%分割率 90%最终识别率 78%瓶颈在逆光下的车牌定位。” 而不是笼统地说精度不高。results [0 0 0]; % 定位、分割、识别 for k 1:N if locOK(k), results(1) results(1) 1; end if segOK(k), results(2) results(2) 1; end if recOK(k), results(3) results(3) 1; end end fprintf(定位率 %.1f%% 分割率 %.1f%% 识别率 %.1f%%\n, ... results(1)*100/N, results(2)*100/N, results(3)*100/N);在实际项目中我更习惯把验证集再拆分细一点正常夜间路灯、正对车灯、侧向眩光、雨天反光四组。正对车灯那组往往是识别率最低的因为车牌被灯光直接打亮蓝色信息丢失严重这正好对应避坑指南里颜色判据失效的场景。调试的时候先处理正对车灯这一组把蓝色判据和眩光抑制跑稳再回头看其他组整体准确率就会明显上升。如果某组图始终有几个样本过不去我通常不会继续调参数而是把这些样本单独保存观察到底是定位阶段跑偏了还是字符断裂在分割阶段就被切错了。这种按阶段记录的习惯是我从翻车里总结出来的血泪经验单张调参调得再漂亮也不如一个能自动复现失败流程的脚本有用。把这些中间结果和验证脚本一起放进你的仿真工程里后续换数据、换分辨率、换摄像头都能快速重新评估而不是从头再把流程跑一遍。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑