尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

基于OpenCV与Python的车牌识别系统完整实现与调优指南

基于OpenCV与Python的车牌识别系统完整实现与调优指南 简介这是一套基于OpenCV与Python实现的完整车牌识别系统源码专为计算机、人工智能、自动化等专业学生毕业设计及课程实践打造解决图像采集、车牌定位、字符分割与OCR识别等核心视觉任务。资源包共48个文件含6个核心Python脚本如main_VLPR.py、img_recognition.py、config.py、21张实拍车牌JPG/PNG测试图、15张标注与中间结果图、2个预训练SVM模型文件svm.dat、svmchinese.dat及1份Word设计手册整体压缩包29.42MB结构清晰模块职责明确便于逐层理解与调试。已有485人学习下载项目经实际答辩验证评审分高达98分所有代码均通过本地环境测试可直接运行。读者可获得从图像预处理、形态学操作、轮廓筛选到中文字符识别的全流程实现附带调试脚本debug.py与数学工具函数img_math.py特别适合初学者入门实践或进阶者二次开发。 车牌识别这个题目是很多计算机视觉方向毕业设计的首选。但说实话网上能搜到的所谓“源码”大多只能跑通一两张样板图换个场景就失灵。我当年做这个项目时也踩了不少坑从最初照抄知乎代码到后面自己重构了整个流程前后花了差不多三周时间。这篇就把我最终沉淀下来的实现思路、可运行的完整管线、以及调参过程中的关键教训全部写出来直接可以当作你毕业设计项目的骨干代码来用重点是不光给代码也讲清楚每一行背后的“为什么”。先说清楚这个项目到底做了什么用 Python OpenCV 实现一个车牌识别系统输入一张包含车牌的图片输出车牌号码字符串。流程包括车牌定位、字符分割、字符识别三个核心阶段全程不依赖第三方商用SDK全部逻辑基于 OpenCV 自带函数完成。项目代码量控制在800行左右难度适中适合作为本科毕业设计的核心内容。1. 为什么选车牌识别当毕业设计项目边界与验收标准选毕业设计题目有个很现实的原则难度要落在“跳一跳够得着”的区间内。车牌识别恰好符合这个标准它既有图像预处理、边缘检测、轮廓分析这些传统CV知识又能往深度学习的YOLO车牌检测、字符识别CNN方向延伸。更重要的是这个项目的结果非常直观——摄像头对着车牌拍一张屏幕上打印出“京A12345”老师一眼就能看懂你在做什么。1.1 一套车牌识别系统的真实工作量很多人以为车牌识别就是一个函数的事拿到需求以后才发现问题层层叠叠。一个完整的基于OpenCV的传统方案包含下面这些子任务图像采集与输入处理支持单张图片、视频帧或摄像头实时流车牌定位在整张图中找到车牌所在的矩形区域车牌校正处理拍摄角度倾斜导致的平行四边形失真字符分割把车牌区域中的多个字符切分成单字符图片字符识别对单个字符进行分类并输出最终字符串。这五个任务每一个都能拆出不少细节。比如车牌定位就有颜色空间法、边缘检测法、形态学方法三种常见路线字符识别又有模板匹配、SVM分类、CNN分类三种不同技术档次。把这些技术组合起来整个项目就足够撑起一篇结构完整的毕业论文了。1.2 毕业答辩时的验收维度根据我当年答辩的经验老师主要从四个维度评估这类项目验收维度具体指标常见扣分点功能完整性能输入图片、输出车牌字符串只能处理固定的一张图识别准确率测试集上准确率尽量高光照变化后识别失败鲁棒性换角度、换距离、换天气仍能工作只在特定尺寸图片下有效技术解释力每个步骤的原理能讲清楚代码跑通但原理一问三不知需要特别提醒的是第四点。每年都有不少同学从网上找到全套源码结果代码能跑但被问到“为什么这里用闭运算而不是开运算”就卡壳了。所以我这篇不打算只给代码而是把每个关键步骤的选型逻辑、参数依据、调试经验都摊开说清楚这样就算你拿到的不是这份代码也仍然能用自己的话把原理讲明白。2. 技术方案定型OpenCVPython选型分析与环境搭建先做技术选型对比。传统方案里最常见的替代品是YOLO检测加CRNN识别商用方案则是各种云平台的车牌识别API。为什么最终还是选了OpenCVPython手工造轮子核心原因有三条一是毕业设计需要体现对图像处理基础原理的理解直接套YOLO反而让很多传统CV知识点没法展示二是模板匹配和传统图像处理路线不需要准备大量标注数据一台没有GPU的笔记本就能开发调试三是代码逻辑完全可控每一步中间结果都能保存成图片答辩演示的时候非常有说服力。2.1 三条技术路线对比技术路线开发成本效果上限可解释性论文好写程度OpenCV 传统图像处理低中高晴天效果好复杂场景一般强每个环节都能可视化好写章节清晰YOLO CRNN中高高各类场景都稳定弱黑盒模型难解释需要补充大量神经网络内容商用云API极低高但依赖网络和费用几乎为零不好写论文容易变成使用说明如果你是做毕设而不是做产品我强烈推荐第一条路线。传统方案识别率会比深度学习方案低几个百分点但换来的是每一步都能打开图片看效果。这种“可调试性”在开发阶段太重要了我整个调试过程几乎都是围绕中间可视化来定位问题的。2.2 环境准备与版本选择开发环境建议如下都是经过我实机验证的组合# 创建虚拟环境建议Python 3.8~3.10 python -m venv lpvenv # Windows下激活 lpvenv\Scripts\activate # 安装依赖 pip install opencv-python4.8.0.74 numpy1.24.3 matplotlib这里要注意两点。第一是opencv-python和opencv-contrib-python这两个包不要同时装否则容易产生符号冲突。第二是Python版本不要用3.11以上部分旧版OpenCV函数在Python 3.11下会报编译相关错误用3.8到3.10之间最稳妥。2.3 源码目录结构建议写毕业设计源码不要把所有函数堆在一个文件里否则后面改逻辑和写论文都很痛苦。我建议按下面的结构组织lpr_system/ ├── main.py # 主入口支持图片/视频/摄像头 ├── config.py # 全局参数配置颜色阈值、轮廓筛选参数 ├── preprocess.py # 图像预处理模块 ├── locate.py # 车牌定位模块 ├── segment.py # 字符分割模块 ├── recognize.py # 字符识别模块 ├── utils.py # 可视化、日志、绘图辅助函数 ├── templates/ # 字符模板库 │ ├── chars/ # 模板图片存放目录 │ └── gen_templates.py # 从字体生成模板的脚本 ├── test_images/ # 测试图片集合 └── output/ # 中间结果输出目录这样的分层结构有非常实际的好处你在定位模块里改了一个形态学参数只需要重新跑定位函数而不用每次从入口重新执行全流程写论文的时候按模块描述系统设计完全对应源码结构老师查代码的时候也方便对照。哪怕是只有几百行的小项目这种组织方式也能帮你减少很多重复劳动。3. 识别管线解剖从图像输入到字符串输出的四段式设计整个系统的处理逻辑可以抽象成一条流水线。我拿一张典型的停车场入口照片作为例子说明图像在系统内部经历了哪些变化。3.1 四阶段管线总览车牌识别系统的完整处理链路如下图像预处理原始BGR图像转灰度图做降噪、增强对比度为后续检测创造干净输入车牌定位利用颜色特征或边缘特征找到车牌粗定位区域输出车牌的包围矩形或旋转矩形字符分割在车牌区域内部做二值化按字符投影规律切出单个字符图片字符识别用模板匹配或分类器对每个字符图片判断类别最后组合成车牌字符串。这四步并不是完全独立的前一步的输出质量直接决定后一步的效果。实际编码时我把每个阶段的输出都保存到output/目录下这样一旦某张图识别失败可以快速定位是定位偏了、分割碎了还是识别错了。3.2 顺序为什么不能乱有人可能会动心思能不能先做字符识别再根据识别结果反推车牌位置理论上可以但工程上不可行。字符识别对输入图片质量要求很高正脸、清晰、尺寸统一的标准字符都容易受噪声干扰直接在复杂背景里找字符误检率会高到你怀疑人生。所以标准的处理逻辑永远是“先定位区域、再处理区域内细节”用一个逐步收缩的注意力机制来降低问题的复杂性。这个思路和人的视觉习惯其实很像。你远远看到一辆车并不会先去读它的车牌号码而是先锁定“车头附近那个蓝色小块”走近了才去分辨上面的数字。OpenCV定位车牌的过程本质上就是这个逻辑的计算机化版本。4. 车牌定位HSV颜色模型与形态学处理的配合车牌定位是整个系统中最重要的模块也是准确率的第一道关口。定位一旦偏了后面分割和识别做得再好也没用。这一节我们实现一个能工作在“蓝底白字”标准车牌上的定位器同时兼顾黄底车牌和新能源绿色车牌的扩展空间。4.1 先用颜色空间筛选不要上来就边缘检测网上很多教程喜欢直接用Canny边缘检测找车牌因为车牌区域字符边缘密集在边缘图上会形成高响应区域。但实际测试会发现车灯、散热格栅、前保险杠纹理同样会产生大量边缘误检率极高。正确做法是先利用车牌颜色信息做一次粗定位过滤掉大部分噪声背景。我选用HSV颜色空间来筛蓝色。HSV对颜色的描述更接近人的感知而且对光照亮度变化不太敏感。标准蓝底车牌的Hue大概在100到124之间Saturation和Value则需要根据实际图片微调import cv2 import numpy as np def locate_by_color(image): # 将BGR图像转换到HSV空间 hsv cv2.cvtColor(image, cv2.COLOR_BGR2HSV) # 蓝色车牌的HSV范围可根据现场图片微调 lower_blue np.array([100, 80, 80]) upper_blue np.array([124, 255, 255]) mask cv2.inRange(hsv, lower_blue, upper_blue) return mask运行这段代码后原图中蓝色像素变成白色其他区域变成黑色。你会看到除了车牌天空、蓝色车身、某些广告牌也可能被保留下来。这没关系下一步就是用形态学操作把分散的蓝色像素聚合成连通区域。4.2 形态学闭运算把碎片焊接成一个整体车牌上的字符是白色的字符间隙是蓝色的如果只筛颜色掩膜上会出现大量细碎的空洞和断裂。这时需要对掩膜做一次闭运算先膨胀再腐蚀。膨胀能把字符笔画区域的空洞填满腐蚀能把被放大的边界收回来最终得到一个完整的矩形亮斑。def preprocess_mask(mask): # 定义一个稍大的结构化元素把碎片区域连接起来 kernel cv2.getStructuringElement(cv2.MORPH_RECT, (17, 5)) # 先闭运算填充字符间隙 closed cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel) # 再做一次开运算去掉零散小噪点 opened cv2.morphologyEx(closed, cv2.MORPH_OPEN, kernel) # 最后膨胀一次让目标区域更加明显 dilated cv2.dilate(opened, kernel, iterations2) return dilated关于核尺寸的选择我这里用了宽17高5的矩形核主要是照顾车牌宽高比3比1左右的特点。闭运算的核一定要“宽”不能“方”因为车牌字符是水平排列的水平方向的连接需求远大于垂直方向。如果核太接近正方形很容易把相邻车牌的蓝色区域都并到一起。4.3 轮廓查找与矩形宽高比筛选形态学处理后的掩膜图像上车牌区域会成为一个白色的“大斑块”。接下来调用cv2.findContours找出所有连通域的外轮廓再用几何特征过滤掉明显不符合车牌形状的区域def extract_plate_boxes(mask, image_shape): contours, _ cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) img_h, img_w image_shape[:2] boxes [] for cnt in contours: x, y, w, h cv2.boundingRect(cnt) # 面积过滤不能太小噪声也不能太大整块蓝色物体 area w * h if area img_w * img_h * 0.001 or area img_w * img_h * 0.3: continue # 宽高比过滤标准车牌约3.14留出弹性范围 aspect w / h if aspect 2.0 or aspect 5.5: continue # 矩形填充度过滤矩形内白色像素占比不能太低 roi mask[y:yh, x:xw] fill_ratio cv2.countNonZero(roi) / area if fill_ratio 0.3: continue boxes.append((x, y, w, h)) return boxes这里三个过滤条件背后都对应着实际经验。面积设0.001是过滤掉几十个像素的小噪点宽高比2.0到5.5是对标准车牌3.14比例的适当放宽因为相机拍摄角度会改变透视后视觉宽高比填充度大于0.3是防止把“口字形”轮廓误判比如某些车辆商圈的镂空标志。做完过滤后候选区域可能仍然不止一个。为了保险起见我不会直接取面积最大的那个而是把所有候选框按面积降序排列依次送入后面的分割和识别模块识别结果置信度高者胜出。这种“多候选轮流验证”的思路能大幅提高定位召回率。5. 字符分割垂直投影法与连通域分析定位到车牌区域之后下一个难点是把这个矩形区域里的多个字符精确切分出来。对于标准蓝底白字车牌排列规则是“省份汉字 发牌机关字母 分隔圆点 5位序号”实际字符数量固定为7个。但只要拍摄角度稍微倾斜或者二值化阈值选取不当分割就会出错而一旦分割出错字符识别模块再强也救不回来。5.1 分割是整套系统的木桶短板我调参时的深刻感受是定位做得再好分割一碎全盘皆输。字符粘连、字符断裂、车牌边框干扰、铆钉噪声每一种情况都能让分割结果形态各异。分割模块我重构过三版第一版直接按固定宽度均分效果惨不忍睹第二版只做垂直投影能处理常规图像第三版加了自适应阈值和投影清洗才算把稳定性提上来。5.2 垂直投影法实现步骤垂直投影法的核心逻辑很简单把二值化车牌图像沿水平方向压缩统计每一列上的白色像素数量得到一个一维数组。字符区域因为笔画密集投影值高字符间隙因为空白多投影值低。通过寻找投影波形的波峰和波谷就能确定字符的左右边界。def segment_chars(plate_bin): # 统计每列白色像素个数 h, w plate_bin.shape col_sum np.sum(plate_bin, axis0) # 找出投影值大于阈值的列作为有效字符区域 threshold h * 0.1 in_char False char_regions [] start 0 for i in range(w): if col_sum[i] threshold and not in_char: in_char True start i elif col_sum[i] threshold and in_char: in_char False end i if end - start 3: # 宽度过小的片段直接丢弃 char_regions.append((start, end)) # 剔除明显过宽的“跨字符粘连”区域粗切割后再精切 return char_regions这段代码输出的是每个候选字符的起始列和结束列。但实际图像中字符和字符之间偶尔会有轻微粘连导致两个字符被分到一个区域。我的做法是先按平均宽度把过宽区域切成均匀的几份再做一轮基于连通域的精分割把粘连点沿垂直方向切开。5.3 汉字字符的特殊处理汉字和字母数字在结构上有明显差异。汉字笔画复杂内部有大量封闭区域垂直投影后可能出现同一字符内部断裂的情况。比如“京”字左右结构明显投影波形可能呈现两个峰如果直接按波谷分割就会把一个汉字切成两半。解决这个问题有两种常用做法一是引入先验知识——车身位一共7个字符第一个字符一定是汉字因此优先保护最左侧的字符区域不被拆分二是在分割后加一个宽度校验如果一个候选区域宽度明显小于其他字符宽度的1.5倍就把它和相邻区域合并。我更推荐第二种思路因为它不依赖汉字位置先验也能处理新能源车牌多一位字符的情况。6. 字符识别模板匹配的落地步骤与SVM/CNN扩展思路分割完成后每个字符都被保存成一张几十像素宽的窄条图片。接下来就是字符识别模块。这个模块有两种主流方案传统模板匹配和机器学习分类器。毕设阶段我建议先用模板匹配跑通全流程再考虑扩展。6.1 模板匹配为什么适合毕业设计模板匹配的思路非常朴素准备一组标准字符图片模板库把待识别字符与每个模板比较相似度相似度最高的模板对应的字符就是识别结果。OpenCV里的cv2.matchTemplate和cv2.minMaxLoc组合就能完成这件事。模板库的获取是第一个坑。我的建议是用PIL.ImageFont直接加载操作系统的中文字体把所有省份简称和常用字母数字渲染成图片再统一缩放到固定的40x90像素尺寸。这样生成的模板干净、风格统一不会出现拍照后的光照差异。def recognize_char(char_img, templates): # 将待识别字符缩放到与模板一致 char_resized cv2.resize(char_img, (40, 90), interpolationcv2.INTER_AREA) best_score -1 best_char for char, templ in templates.items(): # 模板匹配这里用相关系数法 result cv2.matchTemplate(char_resized, templ, cv2.TM_CCOEFF_NORMED) _, score, _, _ cv2.minMaxLoc(result) if score best_score: best_score score best_char char return best_char, best_scoreTM_CCOEFF_NORMED对线性光照有一定鲁棒性它会先减掉区域均值再计算相关性匹配分数稳定在-1到1之间。如果遇到识别分数偏低比如低于0.5说明输入图片质量太差可以直接判为“不确定”不要强行输出结果。6.2 识别后处理校验与纠错得到7个字符的识别结果后不能直接打印输出。车牌字符排列有严格规则可以利用这些规则做校验纠错import re def verify_plate(chars): text .join(chars) # 中国大陆车牌基本规则 # 第1位必须是汉字省份简称第2位必须是字母发牌机关 # 后续5位通常是字母和数字混合但第一位不可能是I和O if len(text) ! 7: return text, False if not re.match(r^[\u4e00-\u9fa5]$, text[0]): return text, False if not re.match(r^[A-Z]$, text[1]): return text, False if not re.match(r^[A-Z0-9]{5}$, text[2:]): return text, False return text, True这个校验至少能拦住两类错误一是中文字符被误识别为英文字母导致第一位校验失败二是分割阶段多切或少切导致整体长度不是7位。如果程序发现长度不对或者格式不合法可以自动进入“二次候选框识别”流程换一个候选区域重新走一遍分割和识别。这个策略在测试集上能多挽回3到5个百分点的准确率。6.3 从模板匹配升级到SVM/CNN的扩展路径如果你想让项目的技术含量再上一个台阶可以预留一套扩展接口。模板匹配的问题在于它对字体变化、笔画粗细非常敏感同一个字换成黑体、宋体都有可能影响匹配分数。更可靠的做法是提取字符的HOG特征然后训练一个SVM分类器。SVM的训练在CPU上几分钟就能完成适合毕设场景。如果要做深度学习路线可以找一个轻量的CNN模型比如LeNet-5把字符图片放进去做分类。论文里可以把模板匹配和CNN做对比实验用准确率曲线说明深度学习方法的优势这样的内容结构很容易拿高分。7. 实测踩坑与调参心得光线变化、角度倾斜和误检代码写完之后真正的挑战才刚刚开始。我在自建测试集上跑了三轮完整测试第一轮准确率只有63%大量问题集中在光照不均、车牌倾斜和背景误检上。这一节把这些坑及其解决过程详细写出来。7.1 光照不均导致的定位失败直方图均衡化的正确用法我的第一版预处理流程很粗暴直接灰度化、高斯模糊、Sobel边缘检测。结果在阳光直射的测试图上车牌区域的蓝色被强光洗成淡蓝色HSV色相虽然变化不大但饱和度和明度范围偏移导致inRange掩膜把车牌过滤掉了。另外有些图整体偏暗车牌区域明度和背景几乎黏在一起。针对这类问题我引入了直方图均衡化。但需要注意直接对全图做cv2.equalizeHist容易把噪声放大导致后续轮廓筛选出现大量小碎片。更稳的做法是先用cv2.split把HSV的V通道分离出来只对V通道做均衡化再合并回去。实测这个方法对阴影、逆光场景提升明显。def enhance_v_channel(hsv): h, s, v cv2.split(hsv) # 对亮度通道做CLAHE限制对比度避免噪声放大 clahe cv2.createCLAHE(clipLimit2.0, tileGridSize(8, 8)) v_eq clahe.apply(v) hsv_eq cv2.merge([h, s, v_eq]) return hsv_eq记住是CLAHE而不是全局均衡化。全局equalizeHist在背景复杂时会让背景蓝色像素的饱和度产生剧烈波动反而干扰颜色筛选。CLAHE把图像分成小格子分别处理能保持局部对比度更适合车牌这类局部特征集中的场景。7.2 倾斜车牌怎么校正停车场拍摄到的车牌很少是完全水平的多数带5到10度的倾斜。如果直接把倾斜的车牌区域送去分割字符投影波形会互相重叠分割结果基本不可用。解决办法是用cv2.minAreaRect找到车牌轮廓的最小外接旋转矩形然后根据矩形的角度把图像旋转回水平状态。def deskew_plate(plate_img): gray cv2.cvtColor(plate_img, cv2.COLOR_BGR2GRAY) _, bin_img cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY cv2.THRESH_OTSU) contours, _ cv2.findContours(bin_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) if not contours: return plate_img # 取面积最大的轮廓计算旋转矩形 cnt max(contours, keycv2.contourArea) rect cv2.minAreaRect(cnt) angle rect[-1] # 角度归一化处理避免90度方向错误 if angle 45: angle angle - 90 if angle -45: angle angle 90 # 以车牌中心为旋转中心旋转至水平 center tuple(np.array(rect[0], dtypeint)) mat cv2.getRotationMatrix2D(center, angle, 1.0) rotated cv2.warpAffine(plate_img, mat, plate_img.shape[:2][::-1], flagscv2.INTER_CUBIC, borderModecv2.BORDER_REPLICATE) return rotated这个函数初看简单但angle的方向判断很容易出错。minAreaRect返回的角度范围是-90到0需要根据实际轮廓方向做一次转换。我把这个模块放在定位和分割之间单独作为一个处理步骤打印旋转前后的图对比方便调试。7.3 车灯、广告牌和背景纹理的误检扩大测试集以后我发现程序经常把以下三类东西误判为车牌夜间开启的车灯区域蓝色光晕蓝色广告牌或店铺招牌车辆前脸的蓝色装饰条。单纯靠宽高比过滤挡不住它们因为这些区域的形状和车牌确实接近。我给出的解决方案是引入“内容验证”这一环。在候选区域被认定为车牌之前先对其内部做二值化统计字符边缘的密集程度。真正的车牌区域内字符边缘密度高且分布均匀而广告牌和车灯区域要么边缘稀疏要么纹理杂乱无章。具体做法是基于二值化图像计算水平方向梯度的标准差如果标准差太小说明区域内太平滑基本不是车牌。7.4 参数调优的经验记录方法在调参过程中我注意到HSV阈值、形态学核大小、轮廓宽高比范围这几个参数对结果影响极大。建议你用参数表格的方式记录每一次实验否则隔一天你就忘了某个参数是在哪张图上调的。我的做法是写一个config.py把所有可调参数集中管理再用一组固定的测试图片做回归测试。改动参数后跑一遍全量测试集记录准确率变化用离线实验数据判断参数是否值得保留。这个方法非常朴素但对毕业设计特别重要。答辩时老师很可能会问“你的参数是怎么确定的”如果你能拿出测试集准确率对比表说明你系统性地调过参拿分会容易很多。8. 毕业设计交付前的测试准备与答辩演示建议代码功能做完离交付还差一步系统性的测试验证和演示设计。这一步做得好的话即使实际准确率不是特别高答辩效果也能大幅提升。8.1 用不完美的图片验证鲁棒性很多毕业设计源码的演示图片都是精心挑选的“友好图”正面、清晰、光照均匀。但答辩现场老师很可能随手拿出一张手机照片让你的系统识别。所以准备测试集的时候一定要包含“不友好”的情况含有复杂背景的图片街道、停车场、高速路口逆光或夜间拍摄的图片车牌倾斜超过15度的图片远距离拍摄、车牌占比很小的图片不同颜色的车牌蓝牌、黄牌、新能源绿牌。我建议准备50到80张图片其中正常情况占六成困难情况占四成统计各阶段准确率并画柱状图。柱状图这种可视化材料放进论文比任何文字描述都有说服力。8.2 展示Demo的保守策略演示Demo时有一个原则不要让程序运行一张完全没验证过的随机图片。你可以准备2到3张自己测试过且识别率高的图片作为“稳定演示”再准备1到2张略有挑战性的图片作为“对比演示”。运行时把中间结果图依次弹出来从原图、颜色掩膜、形态学结果、车牌定位框、字符分割图、识别输出让评审老师看到整个系统的工作过程和逻辑链条。如果演示时识别失败千万不要慌张。我遇到过的情况是定位框偏了导致分割错乱处理方式是直接在图上面打印出定位框坐标告诉老师“这里轮廓筛选的宽高比阈值限制了候选框我可以现场调参数再跑一次”。然后把config.py里的宽高比上限从5.5改成6.0重新运行很多时候就能成功。这种“现场调参”反而给老师留下临场应变能力强的印象。从选题到交付这个车牌识别系统项目我前后花了大概三周。第一周做图像预处理和车牌定位第二周做字符分割和识别第三周专门用来处理各种边缘情况和准备测试材料。回头复盘最核心的经验就一句话不要迷信“一次性跑通所有图”的完整源码把每个阶段的中间结果可视化出来问题会自己浮出水面。你如果正在做这个课题建议按我写出来的模块顺序逐步实现、逐个调试每完成一个模块就保存一批测试样例这样到系统集成的时候各个模块的表现你心里都有底。本文还有配套的精品资源点击获取
返回列表