简介本资源面向计算机视觉学习者与智能交通方向开发者提供一套基于YOLOv8的车牌检测与识别完整实战方案帮助读者从零搭建可运行的车牌识别系统解决车牌定位、字符分割与字符识别等核心问题。压缩包共55个文件约32.93MB包含23张jpg与13张png图像样本、3个ipynb实战笔记、3个yaml配置、2个pt权重文件、2段mp4演示视频以及pb模型、txt说明、csv数据与md文档等覆盖数据准备、模型训练到推理部署的完整链路。目前已有298人学习下载。项目源码可直接用于实际环境部署与测试配套教程详细讲解数据集准备、模型训练与性能评估流程并涉及光照、角度、遮挡等复杂条件下的识别处理思路适合作为课程设计、毕业设计或工业落地的参考案例。1. 车牌识别项目拆包YOLOv8 检测加识别这套源码到底能不能直接跑路上跑的车越来越多卡口、停车场、园区门禁对车牌识别的需求早就不是新鲜事但真正自己从零搭一套能用的系统坑比想象中多。这份资源是一套基于 YOLOv8 的车牌检测加车牌识别实战项目压缩包里带了完整源码、训练好的权重文件、演示视频和一份从环境配置到推理部署的流程教程。它解决的不是YOLOv8 是什么这种科普问题而是我拿到一份能跑的代码怎么把它改成自己场景能用的东西。适合两类人一是刚接触目标检测想找个完整项目练手的开发者二是有车牌识别需求、想快速验证方案可行性的工程师。包里能看到License and Car Detection.ipynb、License Datection.ipynb两个主 notebook还有fingerprint.pb、variables这类 TensorFlow 格式的模型文件以及demo.mp4、demo_target.mp4两段演示素材说明作者至少把检测和识别两条链路都跑通过一遍。下面按资源是什么、怎么用、坑在哪的顺序拆开讲。2. 环境搭建与依赖梳理从 requirements.txt 到能跑通第一帧2.1 先看清包里有什么再动手拿到压缩包别急着pip install先把目录结构过一遍。这个项目的文件组织大致分四块notebook 主程序、模型权重、演示素材、依赖清单。License and Car Detection.ipynb是检测加识别的完整流程License Datection.ipynb偏向纯检测环节Formats.ipynb大概率是做模型格式转换或输入输出格式验证用的。fingerprint.pb配合variables目录是 TensorFlow 的冻结图格式说明项目里除了 YOLOv8 的 PyTorch 权重还涉及一次格式转换或跨框架推理。requirements.txt是环境入口README.md是操作说明。先确认这些文件都在再往下走。常见做法是先建虚拟环境再装依赖避免和系统里已有的 torch 版本打架。我一般用 conda 建一个 Python 3.9 或 3.10 的环境YOLOv8 对这两个版本兼容性最稳。conda create -n plate_yolov8 python3.10 -y conda activate plate_yolov8 pip install -r requirements.txt这段命令的逻辑很直白建环境、激活、按清单装包。参数上唯一要注意的是 Python 版本3.8 以下装 ultralytics 容易报类型注解相关的错3.11 以上部分依赖轮子还没跟上。装完之后用pip list确认ultralytics、torch、opencv-python三个核心包都在版本不用强求最新能对上requirements.txt里的约束就行。2.2 验证 YOLOv8 推理链路是否通环境装好之后别直接上项目的 notebook先用官方最小示例验证一下 YOLOv8 本身能不能跑。这一步是为了把环境问题和项目代码问题分开不然后面报错你分不清是谁的锅。from ultralytics import YOLO # 加载预训练模型首次运行会自动下载 model YOLO(yolov8n.pt) # 对演示图片做一次推理 results model(dog.jpeg) # 打印检测结果摘要 for r in results: print(r.boxes.cls, r.boxes.conf)逻辑说明YOLO(yolov8n.pt)加载的是 COCO 预训练的 nano 版本体积小、推理快适合先验证链路。model(dog.jpeg)直接传图片路径就能出结果返回的results里包含边界框、类别、置信度。参数上如果你机器没有独立显卡YOLOv8 会自动走 CPU速度慢但能跑通。这一步能出框说明 torch 和 ultralytics 都没问题可以进项目代码了。如果这一步就报错八成是 torch 版本和 CUDA 驱动不匹配或者 opencv 装成了 headless 版本导致显示相关功能缺失。2.3 把项目 notebook 跑起来的正确顺序项目里的 notebook 不建议从头到尾一键运行中间涉及模型加载和视频处理的单元格耗时较长容易卡住。我的习惯是按块执行先跑 import 和配置块再跑模型加载块然后跑单张图片推理块最后才跑视频处理块。License and Car Detection.ipynb里如果有路径写死的单元格比如直接指向作者本机的某个目录需要改成你解压后的实际路径。demo_target.mp4和demo.mp4就是给你做视频推理测试用的先拿这两个文件验证别急着换自己的数据。提示notebook 里如果出现cv2.imshow相关代码在服务器或无显示环境下会报错改成cv2.imwrite保存结果再查看。3. 车牌检测与识别链路拆解检测框怎么出、字符怎么读3.1 检测阶段YOLOv8 负责把车牌框出来车牌识别的第一步永远是检测框不准后面识别全是白搭。这个项目用 YOLOv8 做检测输出的是车牌的边界框坐标。YOLOv8 相比前几代在 neck 部分用了 PAN-FPN 结构做多尺度特征融合对小目标——也就是远处的小车牌——召回率有明显提升。检测阶段的输入一般是整张图或视频帧输出是若干个带置信度的框。实际跑的时候置信度阈值和 NMS 的 IoU 阈值是两个关键参数。置信度阈值设太低误检多会把不是车牌的区域也框进来设太高漏检多远处车牌直接消失。我一般从 0.25 起步根据实际场景微调。NMS 的 IoU 阈值默认 0.45 左右如果同一块车牌出了多个重叠框可以适当调低。from ultralytics import YOLO model YOLO(best.pt) # 项目训练好的车牌检测权重 results model.predict( sourcedemo.mp4, conf0.25, # 置信度阈值低于此值的框丢弃 iou0.45, # NMS 的 IoU 阈值控制重叠框合并 saveTrue, # 保存带框的结果视频 device0 # 有显卡用 0没有就写 cpu )逻辑说明source可以是图片、视频路径或摄像头编号。conf和iou是最常调的两个参数saveTrue会把画了框的结果存到runs/detect/目录下。device参数显式指定能避免一些环境下自动选择出错的问题。跑完之后去输出目录看结果视频重点看远处车牌有没有被框住、有没有把车身其他文字区域误框成车牌。3.2 识别阶段从车牌图到字符串的两条路检测框出来之后识别环节有两条常见路线。一条是字符分割加分类先把车牌图做灰度化、二值化、垂直投影把每个字符切出来再送进一个小的 CNN 分类器逐字识别。另一条是端到端的序列识别比如 CRNN 或 CTC 解码直接输入车牌图输出字符串省掉分割步骤。这个项目的 notebook 里两种思路可能都有涉及具体看License and Car Detection.ipynb里识别部分的实现方式。字符分割路线的坑在于中国车牌有蓝牌、黄牌、绿牌、白牌多种底色二值化的阈值不能一刀切。蓝牌用固定阈值还行黄牌和绿牌就容易切歪。端到端路线省心一些但需要足够的标注数据来训练序列模型。如果你只是拿项目做验证建议先用作者提供的权重跑通再考虑换自己的数据微调。import cv2 import numpy as np # 假设 plate_img 是检测框裁剪出来的车牌区域 gray cv2.cvtColor(plate_img, cv2.COLOR_BGR2GRAY) # 自适应阈值比固定阈值更抗光照变化 binary cv2.adaptiveThreshold( gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 19, 9 # 块大小和常数根据车牌分辨率调整 ) # 垂直投影找字符分割点 projection np.sum(binary, axis0)逻辑说明adaptiveThreshold的块大小取奇数19 是一个经验值车牌图分辨率高就调大低就调小。THRESH_BINARY_INV让字符变白、背景变黑方便后续投影。垂直投影求和后字符之间的间隙会表现为投影值接近零的区域据此切分。这套方法对蓝牌效果稳定黄牌和新能源绿牌需要额外做颜色通道分离再处理。3.3 检测与识别的衔接裁剪、矫正、再送入识别检测框和识别模块之间不是直接传图就完事。车牌在图中往往有倾斜直接裁剪出来的图字符是歪的识别率会掉。常见做法是在裁剪后加一步透视矫正找到车牌的四个角点做透视变换把它拉正。角点定位可以用轮廓检测加多边形拟合也可以用检测框的旋转角度做仿射变换。# 假设 pts 是车牌区域的四个角点顺序为左上、右上、右下、左下 dst_pts np.array([[0, 0], [width, 0], [width, height], [0, height]], dtypenp.float32) M cv2.getPerspectiveTransform(pts.astype(np.float32), dst_pts) plate_warped cv2.warpPerspective(plate_img, M, (width, height))逻辑说明getPerspectiveTransform根据源角点和目标矩形算出变换矩阵warpPerspective执行变换。width和height一般按车牌标准比例设中国蓝牌是 440×140 毫米按这个比例缩放就行。矫正之后的车牌图再送识别字符分割和分类的准确率都会明显提升。这一步不做后面识别错了你都不知道是分割的锅还是分类的锅。4. 用自己的数据跑起来标注、训练与参数调整4.1 数据标注格式与 YOLOv8 的对接项目自带的权重能识别通用车牌但你的场景如果有特殊角度、特殊光照或者非标准车牌就得自己标数据微调。YOLOv8 用的是 YOLO 格式的标注每张图对应一个.txt文件每行是类别 中心x 中心y 宽 高坐标都归一化到 0 到 1 之间。标注工具用 labelme 或 labelImg 都行导出时选 YOLO 格式。标注完的数据目录结构要按 YOLOv8 的要求组织dataset/ images/ train/ val/ labels/ train/ val/images/train/放训练图labels/train/放对应的标注文件文件名一一对应只是扩展名不同。val 目录同理。这个结构写错训练时直接报找不到标签。4.2 训练参数怎么设才不白跑YOLOv8 的训练入口很简洁但参数设不对跑一晚上出来的模型可能还不如预训练的。关键参数有这么几个epochs控制训练轮数小数据集 100 到 300 轮起步imgsz是输入分辨率车牌检测建议至少 640远处车牌多的话可以上 1280batch看显存8G 显存跑 640 分辨率大概能上 16lr0是初始学习率微调预训练模型时设小一点0.001 到 0.01 之间。yolo detect train \ datadataset.yaml \ modelyolov8n.pt \ epochs200 \ imgsz640 \ batch16 \ lr00.01 \ pretrainedTrue \ projectplate_train \ nameexp1逻辑说明data指向数据集配置文件里面写清楚 train 和 val 的路径以及类别数和类别名。model指定从哪个权重起步用yolov8n.pt做迁移学习比从零训快得多。pretrainedTrue确保加载预训练权重。project和name控制输出目录方便对比不同实验。训练过程中重点看mAP50和mAP50-95两个指标前者是 IoU 0.5 时的平均精度后者是 IoU 从 0.5 到 0.95 的平均后者更能反映框的精准度。4.3 训练完怎么验证和导出训练结束后权重存在plate_train/exp1/weights/best.pt和last.pt。best.pt是验证集上表现最好的那一轮last.pt是最后一轮。一般用best.pt做推理。验证的时候别只看指标拿几张训练集里没有的图实际跑一下看框的位置和置信度是否合理。yolo detect val modelplate_train/exp1/weights/best.pt datadataset.yaml这条命令会在验证集上重新算一遍指标输出每个类别的 precision、recall 和 mAP。如果某个类别指标特别低回去看标注是不是有问题或者这类样本是不是太少。导出成 ONNX 格式方便后续部署yolo export modelplate_train/exp1/weights/best.pt formatonnx imgsz640导出的 ONNX 模型可以脱离 ultralytics 环境运行适合集成到 C 或其他推理框架里。5. 避坑与排查那些让你白跑一晚上的问题5.1 检测框位置对但识别结果乱码现象检测阶段框得很准但识别出来的字符顺序错乱或者多出无关字符。原因通常是字符分割时把车牌边框或螺丝孔也切进去了或者分割阈值不对导致字符粘连。解决方法是先可视化分割结果把二值化后的图存下来看确认每个字符被独立切开。如果粘连调小自适应阈值的块大小如果多切加一步基于字符宽高比的过滤把明显不是字符的区域去掉。5.2 训练 loss 不降或震荡现象训练开始后 box_loss 和 cls_loss 一直在高位震荡mAP 不涨。原因可能是学习率太大、batch 太小导致梯度噪声大或者标注文件里有大量错误框。解决方法是先把lr0降到 0.001 试几十轮同时用yolo detect train的rectTrue参数开启矩形训练减少填充干扰。标注问题的话写个脚本统计每张图的框数量和框面积分布异常值挑出来人工复查。5.3 视频推理速度慢到无法接受现象单张图片推理很快换成视频后每帧要好几秒。原因通常是每帧都重新加载模型或者没开 GPU。解决方法是把模型加载提到循环外面只加载一次确认device0生效用torch.cuda.is_available()检查 GPU 是否可用。如果必须用 CPU把输入分辨率降到 416 或 320牺牲一点精度换速度。5.4 换了自己的数据后 mAP 暴跌现象用项目自带权重跑演示视频效果很好换成自己标注的数据训练后指标反而很差。原因一般是训练集和验证集分布不一致或者验证集里混入了训练集的图。解决方法是确保 train 和 val 按场景或时间段划分不要随机打乱后切分。另外检查类别名是否和dataset.yaml里写的一致类别对不上时训练不会报错但指标会乱。5.5 模型导出 ONNX 后推理结果和 PyTorch 不一致现象PyTorch 下检测框正常导出 ONNX 后用 onnxruntime 跑框的位置偏移或置信度变化。原因通常是导出时的输入尺寸和推理时不一致或者预处理里的归一化参数没对齐。解决方法是导出时固定imgsz推理时用同样的尺寸和归一化方式。YOLOv8 默认归一化是除以 255如果 ONNX 推理时忘了这步结果肯定不对。6. 进阶技巧把识别准确率再往上推一档跑通基础流程之后想进一步提升效果有几个方向可以试。第一个是检测和识别的联合优化不要等检测框完全稳定再训识别而是把检测裁剪出的图做数据增强——随机透视、亮度扰动、运动模糊——再喂给识别模型让识别模块对检测误差有容忍度。第二个是后处理规则约束中国车牌有固定的字符位数和字符集识别结果出来后用正则做一次校验比如蓝牌是省份简称字母5位数字字母不符合的按置信度次高的候选替换。这个规则层能捞回不少低级错误。第三个方向是模型量化与加速。如果部署在边缘设备上PyTorch 模型直接跑可能帧率不够。用 ONNX Runtime 的量化工具把 FP32 转成 INT8速度能翻倍精度掉一两个点。量化时要用一批真实场景的图做校准校准集覆盖的光照和角度越全量化后的精度损失越小。from onnxruntime.quantization import quantize_dynamic, QuantType quantize_dynamic( model_inputbest.onnx, model_outputbest_int8.onnx, weight_typeQuantType.QUInt8 )逻辑说明quantize_dynamic做动态量化权重转成 8 位整数推理时激活值动态量化。weight_type选QUInt8是无符号 8 位适合大多数场景。量化后的模型体积约为原来的四分之一CPU 推理速度提升明显。量化完一定要在验证集上重新跑一遍指标确认精度下降在可接受范围内。还有一个容易被忽略的点是输入分辨率的选择。训练时用 640推理时如果场景里车牌普遍较大可以降到 416 换速度如果车牌小且远升到 1280 换精度。这个权衡没有标准答案拿一段典型视频分别跑三个分辨率统计识别准确率和帧率选拐点。从那以后我每次拿到一个新的检测加识别项目都强制先跑通官方最小示例再跑项目自带演示最后才换自己的数据。这三步顺序乱了出了问题根本定位不到是哪一层。希望帮到你。本文还有配套的精品资源点击获取