首页 / 资讯中心 / 文章详情

OpenCV车牌识别实战:从图像处理管线到参数调优

OpenCV车牌识别实战:从图像处理管线到参数调优 ★ FEATURED ARTICLE
简介基于OpenCV的车牌识别系统完整代码包面向想动手实践计算机视觉与图像处理的开发者帮助掌握车牌定位、字符分割、OCR识别等核心技术。系统实现覆盖图像预处理灰度化、二值化、噪声去除、Canny边缘检测、形态学操作、字符分割以及SVM/CNN分类的完整流程可迁移至停车场管理、智能交通等实际场景也可用于毕业设计与课程项目。压缩包共23个文件含Python源码、预训练dat模型、样本图片及字符训练数据集其中7z包存储训练材料jpg/png用于测试验证整体体积约14.56MB目录层次清晰便于直接运行与二次开发。已有1175人学习下载。代码提供预测脚本和训练数据并配有README说明配置与运行方式深入阅读后不仅能复用现有模型还能基于OpenCV自行训练字符识别器为后续视觉项目打下扎实基础。1. 车牌识别项目能跑多远:先看清它是什么解压一个名为「基于Opencv的车牌识别系统代码.zip」的压缩包很多人第一件事就是找到 main.py 直接跑看到一张图里框出了车牌、打出了字符就以为完事了。基于OpenCV的车牌识别系统本质上是一条经典图像处理管线定位车牌区域、矫正视角、分割字符、逐个识别不依赖深度学习也能在普通摄像头画面里拿到可用的结果。它解决的是非常具体的落地场景——停车场出入口、小区门禁、实验室Demo以及白天、夜间、倾斜视角下车牌号的自动读取。这个方向适合刚入门计算机视觉的开发者快速建立直觉也适合想验证传统视觉方案性价比的工程师。真正值得投入的不是某个算法有多深而是你能借此把「图像预处理→特征提取→决策输出」这条链路完整走通这份经验在后续做缺陷检测、OCR、目标定位时都能复用。2. OpenCV车牌识别从图像处理管线看懂它的识别逻辑在动手改代码之前得先弄清楚系统里每个环节在干什么。一套经典的OpenCV车牌识别流程通常长这样输入彩色图像 → 灰度化 → 去噪 → 边缘检测 → 形态学闭运算 → 轮廓查找与筛选 → 透视矫正 → 字符分割 → 字符识别。每一环的输出都是下一环的输入参数只要有一个环节不匹配后面全白费。这也是为什么很多人拿到的“能跑代码”一换图片就翻车——不是代码写错而是管线里某个阈值只对它原来那批图片有效。理解这条管线比读懂任何一个单独函数都重要。2.1 车牌定位为什么边缘检测比颜色分割更可靠车牌定位的核心任务是回答一个问题画面里哪个区域是车牌。刚接触 CV 的人最容易想到颜色分割——车牌是蓝底、黄底或绿底把颜色筛出来不就行了但现实里这个思路坑很多不同省份的车牌底色有差异新能源车是渐变绿老式车有黄底黑字蓝牌在白平衡不准的摄像头下可能偏紫偏青。再加上夜间补光灯、日光偏色、阴影遮挡单纯靠 HSV 阈值切颜色要么把深色车身的纹理切进来要么把反光区域漏掉。边缘检测要稳定得多。车牌区域内部字符笔画密集字符边缘和车牌边框共同形成一簇高梯度响应在整张图里这种“纹理密度”非常有辨识度。用 Sobel 或 Canny 提取边缘之后再做一次形态学闭运算把断开的边缘连接成块车牌候选区域就浮出来了。闭运算的结构元素我用的是宽大而扁的矩形核比如 (17,3)因为车牌本身的宽高比接近 3:1 到 5:1字符横向排布横向的间隙需要用宽核去弥合竖向的间隙本来就不大核太高反而会把上下无关边缘也并进来。实际工程里最稳的做法不是二选一而是分层先用边缘做粗定位得到候选矩形再用颜色做二次确认判断这个矩形内部的主色调是否落在车牌底色范围内。蓝牌要求蓝色像素占比超过某个阈值绿牌则换绿色通道阈值。这样颜色判断只作用于小区域不受全图光照影响那么大边缘漏检时颜色方案还能兜底。这条原则我基本每做一个传统视觉项目都会复用——先用鲁棒的特征缩小范围再用局部的强特征做确认比任何单一特征一条路走到黑都可靠。定位结果里还藏着一个容易被跳过的操作透视矫正。车牌不总正对镜头车辆斜着进、摄像头仰拍拍下来的车牌就是梯形。OpenCV 里先拿到轮廓的外接矩形再用 cv2.minAreaRect 得到带角度的最小外接框通过角点排序算出透视变换矩阵 cv2.getPerspectiveTransform把梯形拉回正矩形。这一步不做后面的字符分割绝对会出问题斜着的字符做垂直投影时边界叠在一起切出来的全是歪的。2.2 字符分割与识别的常见技术路线字符分割的目标是“粤A12345”切出 7 个独立字符然后逐个识别。传统 OpenCV 项目里有两条主流路线垂直投影分割和连通域分割。垂直投影的做法是把车牌区域二值化后按列统计黑色像素数量字符之间存在像素低谷低谷位置就是切分点。这个方案实现简单、速度极快但怕三件事字符粘连、边框干扰、车牌倾斜。只要二值化做得不够干净边框像素和字符连成一片低谷消失切分就错位。连通域分割走的是另一条路先在二值图上找所有轮廓用宽高比、面积、填充率过滤噪声剩下那些像字符的轮廓按 x 坐标排序。它比投影法更擅长处理单个字符内部的断裂因为每个字符会独立形成一个外接矩形但对字符粘连的场景同样棘手粘连后的两个字符会形成一个超宽的矩形宽高比直接超出字符过滤区间于是被当成噪声扔掉一丢就是两个字符。识别环节传统方案最常用的是模板匹配。提前准备一套标准字符模板汉字、字母、数字把分割出来的字符图缩放到模板同尺寸用 cv2.matchTemplate 或者直接计算像素差取相似度最高的类别作为结果。模板匹配的好处是完全不需要训练冷启动最快缺点是字体一变、笔画粗细一变相似度就往下掉。想要更高鲁棒性可以换成 HOG 特征加 SVM或者把最后的识别交给轻量 CNN。但这里说句实话识别率的天花板在分割不在分类。定位框歪了、分割切偏了、字符带边框残边换什么分类器都救不回来。这套流程还有一个容易被忽视的全局问题每一步的中间结果最好都可视化出来。我习惯在定位、矫正、分割、识别四个节点各存一张调试图改参数时一眼就能看出是哪一环断了。很多人调参像玄学就是因为从头到尾只看最终打印的字符串中间坏在哪一步全靠猜。把中间结果摊开看参数调整就有了明确的方向。3. 在本地跑通最小可用版代码结构与核心模块这一章直接落到可运行的代码。基于OpenCV的车牌识别系统代码压缩包不管里面长什么样一个能稳定复现的传统方案我都会把项目拆成四个文件入口脚本、定位模块、分割模块、模板目录。这样的结构最利于排查定位出错看定位图分割出错看分割图不会在几百行代码里来回翻。下面给出的是我常用的一套最小实现能跑通蓝牌场景也方便你在这个骨架上继续加颜色校验和透视矫正。3.1 环境准备与项目文件组织Python 环境和依赖用虚拟环境隔离避免污染系统级 Python。OpenCV 和 NumPy 两个包就够跑完这条管线不需要额外的深度学习框架。python -m venv venv source venv/bin/activate # Windows 下用 venv\Scripts\activate pip install opencv-python numpy建议的项目目录结构如下plate_recognition/ ├── main.py # 入口读图、串联定位与识别 ├── plate_locate.py # 车牌定位模块 ├── char_split.py # 字符分割与识别模块 └── templates/ # 字符模板图片目录main.py 只做流程编排不写具体算法plate_locate.py 负责从原图里找车牌并返回裁剪图char_split.py 负责把裁剪图切成字符并和模板比对。这样每个文件的职责单一换数据集时只需要调对应文件的参数不需要动整条链路。3.2 车牌定位形态学预处理与轮廓筛选的落地代码定位模块用 Sobel 加形态学闭运算提取候选区域再用轮廓的几何特征过滤。下面是完整代码带关键注释。# plate_locate.py import cv2 import numpy as np def locate_plate(img): # 1. 灰度化去掉颜色信息降低计算量 gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 2. 高斯模糊去噪核太小去不掉噪点太大会抹掉字符边缘 gray cv2.GaussianBlur(gray, (5, 5), 0) # 3. 用 Sobel 提取水平边缘因为车牌字符横向排列水平梯度最明显 sobelx cv2.Sobel(gray, cv2.CV_64F, 1, 0, ksize3) abs_sobelx np.uint8(np.absolute(sobelx)) _, edges cv2.threshold(abs_sobelx, 60, 255, cv2.THRESH_BINARY) # 4. 闭运算先膨胀再腐蚀把断开的字符边缘连成块 kernel cv2.getStructuringElement(cv2.MORPH_RECT, (17, 3)) closed cv2.morphologyEx(edges, cv2.MORPH_CLOSE, kernel) # 5. 提取轮廓RETR_EXTERNAL 只取外轮廓避免内部字符干扰 contours, _ cv2.findContours(closed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 6. 用宽高比、面积过滤候选框 candidates [] for cnt in contours: x, y, w, h cv2.boundingRect(cnt) area w * h ratio w / h if area 2000 and 2.5 ratio 5.5: candidates.append((x, y, w, h)) # 7. 按面积从大到小排序取最大候选作为车牌区域 if not candidates: return None candidates.sort(keylambda r: r[2] * r[3], reverseTrue) x, y, w, h candidates[0] return img[y:y h, x:x w]这段代码里最值得关注的参数有三个。Sobel 的 ksize3 是梯度核大小ksize 越大越平滑但小字符的边缘会被抹掉二值化阈值 60 控制在 40 到 80 之间阈值越低边缘越多候选框越多CPU 开销也越大闭运算核 (17,3) 的宽度 17 是根据车牌字符间距估的间距大约在 8 到 15 像素之间核宽必须大于最大间隙才能把字符连成一个整体。面积阈值 2000 是按 VGA 分辨率定的如果处理的是 1080p 原图这个值要放大到 8000 以上否则大量的树叶、路面纹理区域也会进入候选。3.3 字符分割与模板匹配识别拿到车牌裁剪图之后下一步是二值化、切字符、和模板比对。这里给出最简实现默认车牌已经比较正暂不做透视矫正。# char_split.py import cv2 import numpy as np def preprocess_plate(plate_img): # 转为灰度后直接用 OTSU 自动阈值二值化 gray cv2.cvtColor(plate_img, cv2.COLOR_BGR2GRAY) _, binary cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY cv2.THRESH_OTSU) # 车牌的字符是深色背景是浅色所以反色让字符变成白色 binary cv2.bitwise_not(binary) return binary def segment_chars(binary): # 找字符轮廓过滤掉噪声后按 x 坐标排序 contours, _ cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) chars [] for cnt in contours: x, y, w, h cv2.boundingRect(cnt) area w * h # 字符宽高比通常在 0.3 到 1.0 之间数字1稍微窄一点但不会小于0.2 if h 15 and 0.3 w / h 1.0 and 500 area 5000: chars.append((x, y, w, h)) chars.sort(keylambda r: r[0]) return chars def recognize_char(char_img, templates): # 统一缩放到 20x40和模板保持一致 char_img cv2.resize(char_img, (20, 40)) best_score -1 best_label None for label, tmpl in templates.items(): tmpl cv2.resize(tmpl, (20, 40)) score cv2.matchTemplate(char_img, tmpl, cv2.TM_CCOEFF_NORMED)[0][0] if score best_score: best_score score best_label label return best_label, best_scoresegment_chars 里的过滤条件是这套代码的“隐形参数”。h 15 是字符最小高度低于这个值的多半是噪声或车牌边框残留0.3 w/h 1.0 是字符宽高比约束汉字和字母通常偏窄数字偏宽这个区间能挡掉横向细条和竖向细条面积区间 500 到 5000 同样按裁剪图尺寸定如果你把车牌裁剪图缩放过这两个数要按比例重新算。template 匹配部分我建议模板来源用两种途径混合一是用你自己这张测试车牌切出来的字符二是用标准字库渲染出的字符截图。前者对当前场景匹配度高后者能增强对字体的泛化能力两种混合后的识别结果通常比单一来源稳。匹配方法选了 TM_CCOEFF_NORMED它对亮度变化不敏感字符笔画粗细不一致时也比 TM_SQDIFF 抗干扰。main.py 把这些模块串起来并输出识别结果和调试图方便定位问题。中间结果的保存是小成本大收益的习惯强烈建议保留。4. 把识别率从 80% 拉到 95%必调的 5 组参数跑通最小版本只代表“某些图片能识别”并不代表系统立在了一个可靠的水平上。从能跑到跑得稳差别全在参数上。下面这 5 组参数是我调了无数批图片后的核心经验按影响程度排序列出每组给出常用范围和调试方向。4.1 预处理灰度化、去噪、锐化的顺序不能乱预处理顺序比大多数人想的更敏感。我的固定顺序是灰度化 → 去噪 → 锐化 → 边缘检测。去噪放在锐化前面是因为锐化会放大噪声先去噪可以让锐化作用在干净的图像上去噪核大小直接影响边缘质量核太大比如 7x7会让字符边缘变钝Canny 找不到闭合轮廓核太小比如 3x3噪声压不住边缘图会花掉。高斯模糊的 sigma 参数也值得注意。OpenCV 的 GaussianBlur 里 sigma 可以设 0让函数自己根据核大小推算一般核 (5,5) 就够用。如果画面里车牌区域占比小、远处拍摄导致字符本身就模糊我通常会在去噪后用一次拉普拉斯锐化增强边缘sharp cv2.addWeighted(gray, 1, cv2.Laplacian(gray, cv2.CV_64F), 0.3, 0)这里的 0.3 是增强强度。在 0.2 到 0.5 之间调整超过 0.5 会出现明显的光晕反而让字符边缘出现双线。锐化适合中远景摄像头近距离拍的大车牌本身边缘清晰锐化收益小、风险大可以直接跳过。4.2 Canny 双阈值与形态学核大小Canny 的两个阈值低阈值控制边缘的“灵敏度”高阈值控制“确定性”。我的常用起点是 50 和 150但夜间图我会把低阈值降到 30因为夜间车牌边缘对比度低阈值太高直接检测不到任何边缘白天背光场景则把高阈值提到 180避免车身高光区域产生大量伪边缘。形态学闭运算的核大小是定位环节最需要反复试的参数。核宽是连接字符间隙的关键间隙小于核宽才会被填上核高是防止上下噪声合并的关键核太高会把车灯、保险杠边缘一起并入候选块。我的参考值是 (17,3)输入分辨率约 640x480 时核宽在 15 到 20 之间。另外一个容易忽略的细节闭运算在做完一次之后如果候选区域仍然破碎可以做第二次闭运算而不是把第一次的核调大。核一次性调太大会连同背景里的文字、栏杆一起融成块定位框直接偏走。4.3 轮廓筛选宽高比、面积、矩形度的边界轮廓筛选是过滤误检的主要关卡也是参数边界最清晰的一组。参数常用范围说明宽高比2.5 ~ 5.5标准车牌约 3.1 到 4.5新能源六位牌稍长轮廓面积按分辨率比例缩放面积太小是噪声太大会把整辆车框进来矩形度0.6 ~ 0.9轮廓面积与外接矩形面积之比矩形度过低说明形状不是矩形填充率0.3 ~ 0.8轮廓区域内白色像素占比太低说明区域内部纹理稀疏面积没有万能值我给一个按输入宽度缩放的经验公式假设输入图像宽 W车牌通常占图像宽度的 8% 到 15%高度约为宽度的 1/3所以最小面积可以设在 WW0.002 左右。1080p 图像这个值大约在 4000 到 6000 之间比 480p 的 2000 大不少。矩形度是很多人忽略的指标它能把“车牌轮廓其实是四边形”这个先验用上路牌、灯箱、车头这些不规则区域会在矩形度上显著偏低。4.4 字符分割二值化方法与字符宽高约束分割环节最影响识别率的参数其实是二值化。OTSU 全局阈值在车牌图像光照均匀时表现极好但遇到反光、强阴影就会失效因为全局阈值只有一个顾了亮区就顾不了暗区。我常用的升级方案是自适应阈值binary cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 51, 10)blockSize 是自适应窗口的大小必须是奇数。窗口大小决定局部阈值的统计范围字符笔画宽度约 8 到 12 像素时窗口 51 比较合适窗口太小字符内部会被切成黑白斑块窗口太大自适应退化成全局阈值。C 值 10 是减去的常量控制阈值整体下移还是上移字符比背景暗时设正值反色后设负值。需要说明的是OTSU 更快自适应阈值更稳两者没有绝对优劣。先跑 OTSU发现字符边缘有断裂、且有明显光照不均时再切自适应阈值。字符宽高比过滤范围 0.3 到 1.0这个区间有个已知盲区数字“1”单独出现时宽高比会降到 0.15 左右容易被过滤掉。处理方式是把这个下界放宽到 0.2再用面积下限拦住真正的噪声。另外车牌里有汉字汉字宽高比接近 0.8 到 1.0和数字 8 很像靠几何无法区分这是分割正常、识别混淆的典型场景需要识别阶段的模板去兜底。4.5 识别模板匹配的相似度阈值模板匹配的最终输出不是直接返回最高分结果而是要设置一个最低接受阈值。低于阈值就判定为“不认识”而不是硬给一个错误结果。我的常用值是 0.6低于 0.6 的结果基本不可信。阈值在 0.6 到 0.8 之间调想要高正确率、宁可拒绝也不误判就调高想要高召回、接受一定错误率就调低。跟阈值直接相关的一个坑是“模板只做了一套”。同一字符在不同字体、不同车牌上差异很大比如字母 A 在有些牌子上是尖顶有些是平顶。我的做法是为同一个字符准备 3 到 5 套模板匹配时取所有模板中的最高分。模板数量翻倍对速度影响不大但识别率提升很明显。另外一个提升细节是匹配前把字符图和模板都做一次归一化补丁外的白色区域可能包含残边匹配时用掩码只计算字符主体区域能减少边框残留的干扰。5. 落地实战中的避坑清单做车牌识别最容易翻车的 5 个场景这一章是拿真实现场数据换回来的经验每一条都对应一次真实的调参回退。按「现象 → 原因 → 解决」写方便你对照自己的报错或错误结果直接定位。5.1 蓝牌能识别、绿牌全废现象同一套代码蓝牌识别率很高新能源绿牌要么定位不到、要么字符分割后全部错乱。原因这套代码的预处理和颜色确认逻辑完全围绕蓝牌设计灰度化对绿色车牌的对比度天生不友好绿色在灰度图上的亮度值接近背景色字符边缘不明显如果定位环节还有颜色二次确认只查蓝色像素占比绿牌直接在第一轮就被拒掉。解决先确认定位环节是否把绿牌候选框选出来了如果连框都没有问题在边缘检测和颜色确认如果框选出来了但分割错问题在二值化。建议在颜色确认环节按候选区域主色调选择不同通道的阈值蓝牌查蓝色像素、黄牌查黄色像素、绿牌查绿色像素。在二值化环节对绿牌单独降低 OTSU 的前景背景反转判定或者改用自适应阈值。5.2 车牌倾斜超过 15 度现象定位框看起来很准但输出的字符序列整体偏斜相邻字符在垂直投影中粘连识别结果出现“A2”变“AH”之类的错误。原因字符分割默认做了垂直投影而垂直投影的前提是字符行水平排列。倾斜超过 15 度后第一个字符和最后一个字符的纵向位置差很大投影分界被拉模糊。解决在分割前加入透视矫正。用 cv2.minAreaRect 拿到带角度的最小外接矩形排序角点后做透视变换。这个操作对倾斜、俯拍视角的车牌几乎是一劳永逸的方案矫正后再做垂直投影分割准确率会有一个非常直观的跃升。注意角点排序要稳定先按 y 坐标分上下两组再按 x 坐标分左右避免透视矩阵算出负值导致图像翻转。5.3 夜间补光灯下的反光现象白天正常晚上开启补光灯后车牌上几个字符丢失识别结果少一位。原因补光灯在车牌表面形成高光反射区域车牌本身是金属材质反光区域亮度过高OTSU 全局阈值被高光拉偏低灰度部分的字符被判定为背景直接消失。解决换自适应阈值优先尝试 ADAPTIVE_THRESH_GAUSSIAN_C让局部区域自己决定阈值如果反光区域过大自适应也压不住可以在预处理阶段对高光区域做 mask 提取用 cv2.inpaint 把反光区域修补成周边颜色再接正常二值化。另一个备选做法是拉低 Canny 的低阈值让弱边缘保留下来这个改动能减少反光带来的边缘断裂但会引入更多噪声需要同时收紧轮廓筛选的矩形度条件。5.4 字符粘连与边框干扰现象分割结果出现一个超宽矩形里面包含两个字符或者最左侧的字符框把车牌边框一起框进去。原因二值化后字符之间的缝隙被噪声填充或者车牌边框和第一个字符像素相连。闭运算在定位阶段用来连接边缘是好事但如果连着做了多次闭运算、核又偏大字符间隙也会被填上边框没有先消除时边框像素让第一个字符的外接矩形横向拉长宽高比超出过滤区间。解决分割之前先做一次边框消除。常见做法是把裁剪图的边缘一圈腐蚀掉或者把最外层 5 像素置为背景色如果字符粘连用一次小核开运算核 3x3断开缝隙。边框消除会顺带把字符的毛刺去掉但要小心腐蚀次数过多导致字符主体变细模板匹配时相似度下降。做完这一步再看分割结果通常好很多。5.5 把路牌、广告牌当车牌现象画面里有带文字的指示牌或广告灯箱时代码返回一个“车牌号”而且位置就在文字区域。原因文字密集区域的纹理特征和车牌非常像——有大量字符、有规则的排列、宽高比可能也落在过滤范围内颜色确认如果没有开启或者广告牌底色恰好是蓝绿色误检就发生了。解决从三个层次拦截。定位层加上颜色确认要求候选区域内部车牌底色像素占比超过 30%这个步骤能把大量白底、红底广告牌滤掉。分割层识别的字符数固定是车牌位数比如蓝牌 7 个字符由于汉字、字母、数字的字符宽度分布有规律可以对分割结果做数量校验少于或多于预期位数的候选直接放弃。识别层把最终识别出的字符串做规则校验第 1 位必须是汉字第 2 位必须是字母后面必须是字母或数字不符合规则就拒绝输出。这三层叠加后误检率能降到可接受范围。6. 最后一步用批量测试集量化你的系统表现做到这一步系统能在单张图上跑通了但“单张能跑”和“系统可用”之间还差一个指标闭环。我强烈建议你花半小时做一套最简易的真值测试准备几十张覆盖白天、夜间、倾斜、远近不同距离的车牌图手工标注每张图的真实车牌号存成一行一个“文件名 车牌号”的文本文件然后写一个批量评估脚本把识别率量化出来。# evaluate.py import os import cv2 from plate_locate import locate_plate from char_split import preprocess_plate, segment_chars, recognize_char def load_gt(gt_file): gt {} with open(gt_file, r, encodingutf-8) as f: for line in f: parts line.strip().split() if len(parts) 2: gt[parts[0]] parts[1] return gt def run_eval(img_dir, gt_file, templates): gt load_gt(gt_file) correct_plate 0 correct_char 0 total_char 0 failures [] for fname, truth in gt.items(): path os.path.join(img_dir, fname) img cv2.imread(path) plate locate_plate(img) if plate is None: failures.append((fname, truth, no_plate)) continue binary preprocess_plate(plate) chars segment_chars(binary) pred .join(recognize_char( binary[y:yh, x:xw], templates)[0] for x, y, w, h in chars) if pred truth: correct_plate 1 else: failures.append((fname, truth, pred)) total_char len(truth) correct_char sum(1 for a, b in zip(pred, truth) if a b) print(f牌照级准确率: {correct_plate / len(gt):.2%}) print(f字级别准确率: {correct_char / total_char:.2%}) for fname, truth, pred in failures: print(f失败案例: {fname} 真值{truth} 输出{pred})这段脚本输出的两个指标各有用途牌照级准确率代表系统在真实场景里“一次给对”的概率这是给业务方看的字符级准确率代表分割和识别每个环节的健康度这是给你自己调参用的。字符级高、牌照级低说明问题出在偶尔有一位识别错误模板库或相似度阈值方向出了问题两个指标都低说明问题出在更前端的定位或分割换识别模型也没用。跑评估时的图片数量至少 50 张覆盖度比数量更重要。每轮改完参数重跑一次把准确率记下来再动下一个参数这是最有效的调参习惯。我自己早期最大的教训就是拿两三张图试看着能过就收工结果换到夜间批量数据当场崩掉后来强迫自己“改一个参数必须重跑完整套测试集”识别率才真正稳定下来。这个习惯养成了后面接任何新数据集、新场景你都知道怎么快速判断系统状态也能更清楚地判断基于OpenCV的车牌识别系统的传统视觉方案够不够用。希望帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?
咨询建站