ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

基于YOLOv8和LPRNet的车牌识别系统实战

基于YOLOv8和LPRNet的车牌识别系统实战 简介计算机视觉中目标检测与识别是经典问题而车牌识别作为智慧交通的典型应用常面临复杂光照、角度畸变等挑战。基于深度学习的YOLO算法凭借强大的特征表达能力在车牌定位任务中表现出高精度与高鲁棒性配合LPRNet轻量识别网络可完成端到端的车牌字符读取。本文从数据准备、模型训练、指标调优到部署推理系统梳理了基于YOLOv8和LPRNet搭建可定制车牌识别系统的完整流程并针对“训练指标全为0”等常见坑点给出排查方案为开发者提供从0到1的实战参考。 最近接到一个车牌识别项目需求时我的第一反应不是赶紧写代码而是先纠结要不要直接用现成的商业SDK。坦白讲停车场道闸、电子警察这些场景车牌识别已经被做到非常成熟第三方算法公司提供的SDK开箱即用识别率也很漂亮。但客户给的条件很现实要能自己训练、能改模型、后续要适配新能源绿牌和特殊车型不能黑盒闭源。于是我把技术路线从买SDK换成了基于YOLO自己搭一套检测识别系统也就是最终整理成的这个项目包YOLO负责从视频帧或图片里把车牌区域找出来再用一个轻量识别网络把车牌上的汉字、字母、数字读出来。这套组合下来检测部分交给YOLO识别部分交给LPRNet两者各管一段效果稳定且完全可定制。如果你也在做类似的视觉项目或者刚接触YOLO想找一个能落地的实战案例这篇内容应该能帮你少走不少弯路。1. 从零选定技术路线车牌识别为什么用YOLO而不是传统视觉算法1.1 车牌识别到底在拆解什么问题很多人一开始会把车牌识别当成一个单一任务其实它天然包含两个子任务第一步是车牌检测也就是在整张图像里定位哪一块区域是车牌第二步是车牌字符识别也就是把定位出来的车牌图像转换成京A12345这样的字符串。这两个子任务面临的难点完全不同。检测阶段要应对的是复杂背景车身颜色、道路标线、灯光反射、行人遮挡都可能干扰定位。而字符识别阶段要应对的是图像本身的质量角度倾斜、透视变形、模糊、反光、甚至车牌本身污损。如果直接用整张图做端到端识别模型需要同时学会找车牌和读车牌训练难度和失败概率都会成倍增加。所以我在这个项目里老老实实采用两阶段思路先用YOLO检测车牌位置裁剪出车牌图像再做字符识别。这样每个模型都只解决一个问题定位精确后续识别也能做图像矫正和增强整体鲁棒性反而更高。1.2 YOLO方案与传统图像处理方案的实际对比传统方式里很多人第一反应是OpenCV的轮廓检测加颜色过滤。思路是车牌有固定颜色蓝底白字、黄底黑字、绿底黑字先做颜色空间转换提取蓝色或黄色的像素区域再找轮廓、筛选宽高比定位车牌。听上去简单但实际落地会碰到一堆问题。首先是颜色受光照影响极大。白天的蓝色和傍晚昏暗光线下的蓝色在HSV空间里范围完全不一样。只要室外场景的光照条件一变阈值就失灵。其次是车身贴膜、装饰条、路牌的颜色都可能和车牌颜色接近产生大量误检。最后一旦遇到倾斜角度大、部分遮挡的车牌轮廓提取很容易碎成好几块根本构不成完整的四边形。YOLO解决这些问题的方式完全不同。它基于深度学习通过大量标注样本学习车牌区域的纹理、边缘、颜色组合特征而不是依赖人工设计的颜色阈值。换句话说传统方法是在猜规则YOLO是在学规律。实测下来同一个测试集上传统颜色轮廓方法在正常光照下的召回率勉强到90%一旦加入夜间、逆光、倾斜样本召回率直接跌破70%。而YOLO模型在这些场景下mAP50能做到95%以上。1.3 为什么最终选择YOLOv8作为检测底座当前YOLO系列已经发展到YOLOv11甚至更新的版本但我在这个项目里选择的是YOLOv8。原因很直接它在精度、速度、生态成熟度之间取了一个非常理想的平衡点。YOLOv5虽然更老更稳定但结构相对过时一些新的改进没有跟上YOLOv11更先进但部分配套工具链和第三方部署案例还没有完全沉淀项目工期紧张时踩坑成本高。YOLOv8是anchor-free的也就是不需要像YOLOv5那样预先聚类anchor框模型自己预测目标的中心点和宽高。这一点在车牌这种宽高比相对固定的目标上很合适少了一个需要调优的环节训练时也更省心。另外YOLOv8自带的数据增强、模型导出、日志可视化工具都做得很完善从训练到部署的路径非常顺滑。# YOLOv8训练命令简单直接 yolo train dataplate.yaml modelyolov8n.pt epochs100 imgsz640 batch16 device0如果你手里的设备性能有限可以用yolov8n或者yolov8s这样的轻量版本如果对精度要求更高比如需要识别远处的小目标车牌可以选择yolov8m甚至yolov8l。我项目里最终用的是yolov8s在普通工业电脑上推理速度大约20毫秒一帧精度也够用。2. 车牌数据从哪来CCPD筛选、自采标注与xml转YOLO格式的完整处理2.1 CCPD数据集怎么用、怎么筛训练目标检测模型数据永远是最关键的。有一个公开数据集非常适合起步就是CCPDChina City Parking Dataset它是从城市停车场监控里截取的真实场景图片包含超过25万张车牌图像覆盖了不同光照、角度、天气条件。但CCPD有一个需要特别注意的问题它的标注信息是直接写在文件名里的比如025-95_113-154383_386473-386473_177454_154383_363402-0_0_22_27_27_33_16-37-15.jpg文件名里依次包含了车牌角度、四个角点坐标、车牌字符等信息。这意味着它不能直接拿来训练YOLO需要写脚本解析文件名转换成标准的YOLO文本框格式。另外CCPD里的图片分辨率普遍偏高很多是横向720p到1080p的街景图直接整图训练会消耗大量显存。我通常会先按一定比例缩小到1280像素以内再做训练集和验证集的划分。筛选的时候还有一个实用小技巧CCPD里不同子目录代表的场景复杂度不同像ccpd_weather和ccpd_night子集难度明显更高把这些困难样本按比例混入训练集能显著提高模型的泛化能力。2.2 自采数据标注与xml转YOLO格式公开数据集解决的是有数据可用的问题但如果你的实际场景很特殊比如小区地库入口有独特的光照或者使用的是某种非标字体车牌那还是得自己采集数据补齐。自采数据我用的是LabelImg这个工具它可以画矩形框导出VOC格式的xml标注文件。这里有一个新手非常容易卡住的地方LabelImg默认导出的是xml即VOC格式但YOLO训练要求的是txt格式的标注文件两者格式完全不同。VOC格式里记录的是xmin, ymin, xmax, ymax也就是框的左上角和右下角坐标YOLO格式记录的是归一化后的中心点坐标和宽高。转换脚本逻辑很简单但写起来有一些细节要注意。import os import xml.etree.ElementTree as ET def convert_xml_to_yolo(xml_path, out_dir, classes): tree ET.parse(xml_path) root tree.getroot() img_w int(root.find(size/width).text) img_h int(root.find(size/height).text) out_lines [] for obj in root.iter(object): cls_name obj.find(name).text if cls_name not in classes: continue cls_id classes.index(cls_name) box obj.find(bndbox) xmin float(box.find(xmin).text) ymin float(box.find(ymin).text) xmax float(box.find(xmax).text) ymax float(box.find(ymax).text) x_center (xmin xmax) / 2.0 / img_w y_center (ymin ymax) / 2.0 / img_h width (xmax - xmin) / img_w height (ymax - ymin) / img_h out_lines.append(f{cls_id} {x_center:.6f} {y_center:.6f} {width:.6f} {height:.6f}) txt_path os.path.join(out_dir, os.path.splitext(os.path.basename(xml_path))[0] .txt) with open(txt_path, w) as f: f.write(\n.join(out_lines)) classes [plate]这个脚本里有几个关键点值得强调第一坐标必须除以图片实际宽高做归一化否则YOLO训练时会把坐标当成像素值导致loss爆炸或者指标一直为0第二类别ID必须从0开始LabelImg里如果习惯性给类别命名为1就会造成类别ID错位第三如果一张图里只有一个类别yolo的class id固定为0。这一套脚本处理好之后下一步就是按比例划分数据集YOLO要求的目录结构是images/train、images/val和labels/train、labels/val一定不能放错位置。2.3 数据增强的度怎么把握YOLO自带的训练流程里已经内置了Mosaic、随机翻转、HSV扰动等数据增强策略。默认配置对于一般目标检测任务已经不错但针对车牌识别这个具体场景我需要额外注意两点。第一点是不要过度使用水平翻转。车牌上的汉字和字母是有方向性的京A12345翻转之后字符顺序会颠倒虽然检测任务只关注有没有车牌框这种语义错误对检测影响不大但如果后续识别任务需要复用标注框就要小心。第二点是HSV颜色扰动要克制车牌颜色是识别辅助信息之一如果颜色偏移太夸张会让模型学到错误的颜色特征。我自己通常的做法是只开启轻微的亮度和对比度扰动模拟不同光照环境同时保留Mosaic和随机仿射变换来增强模型对角度和尺度的鲁棒性。数据增强的度要以你实际场景的多样性为准而不是盲目堆强度。3. 实战训练YOLO关键参数、anchor调整与指标全为0排查3.1 输入分辨率与anchor尺寸的选择训练YOLO模型输入分辨率直接影响小目标检测效果。车牌在监控画面里往往只占很小一块区域如果直接把整图缩放到640x640车牌区域可能只剩二三十个像素宽识别难度会非常大。所以我把训练分辨率从默认的640提高到了960或者1280视显存情况而定。不过分辨率提高的同时模型的推理耗时也会增加。这个trade-off在实际项目里要反复权衡。我的经验是如果相机距离车牌比较近比如停车场出口杠杆处640到960就够了如果相机架得高、视野大比如园区入口那就必须上1280否则远处车辆的车牌会小到完全无法检测。关于anchor我前面提到YOLOv8是anchor-free的理论上不需要手动聚类anchor框但如果你用的是YOLOv5还是建议在自己的数据集上重新聚类一次。车牌的长宽比通常在2.5到4.5之间和COCO数据集里通用目标的形状差异很大直接沿用默认anchor会导致定位框不稳定。YOLOv5里可以使用utils/autoanchor.py自动重新计算anchor或者用kmeans_anchors脚本。YOLOv8虽然不需要这一步但如果你后续尝试修改网络结构或换检测头依然要关注anchor的匹配逻辑。3.2 训练超参数与迁移学习策略我在训练时用的是一套比较保守的参数组合适合大多数情况。初始学习率0.01使用SGD优化器加余弦退火衰减权重衰减0.0005动量0.937。batch size根据地上的显存调整如果使用RTX 3090或4090batch size可以开到32甚至64如果使用消费级显卡8G显存16左右比较安全。迁移学习是提升效果的关键一步。不要从零开始训练直接用YOLOv8官方在COCO数据集上预训练好的权重作为起点。COCO里有80类通用物体虽然里面没有车牌但模型在COCO上学到的边缘、纹理、颜色特征对车牌检测是有帮助的。实践中从预训练权重开始训练比从零开始训练能节省大量时间最终精度也更高。# plate.yaml 数据集配置文件 path: /data/vehicle_plate train: images/train val: images/val nc: 1 names: 0: plate这里有个很容易被忽略的坑nc后面的数字是类别数如果写错训练时就会出现loss为nan或者mAP一直为0的情况。我调试过几个项目发现不少指标全为0的问题根源就是nc和names没配对。3.3 训练指标全是0的完整排查链路热搜词里有人问yolo训练指标全是0这个问题我自己也踩过而且踩得挺深。第一次训练时控制台打印的epoch循环正常loss也在下降但mAP和precision、recall全部显示0看起来像模型完全没学到东西。排查了一整天最后定位到三类原因。第一类是上述提到的标注格式问题XML转TXT时坐标没有归一化导致训练时目标框坐标超出[0,1]范围模型压根没收到有效监督信号。排查方法很简单随机打开几个labels目录下的txt文件看看坐标是否都在0到1之间有没有明显超出。第二类是类别ID不匹配data.yaml里写的类别名和标注txt里的类别ID对不上比如标注文件第一列是1但数据配置里只有0号类别训练时就找不到对应类。第三类是数据集划分乱套images和labels目录对不上或者train和val里出现了同一张图导致验证集数据泄漏指标显示异常。遇到指标全为0的情况我现在的排查顺序是先看标注txt内容是否正常再看data.yaml的路径和类别配置最后看train.txt/val.txt里的图片路径是否存在。这个过程听起来枯燥但效率最高比盲目调参要靠谱得多。4. 检测框之后的另一半车牌矫正与LPRNet字符识别4.1 为什么不直接端到端识别如果读者接触过一些OCR项目可能会想为什么不直接用PaddleOCR这类现成工具或者训练一个端到端的图像到字符串模型这是因为车牌识别和自然场景文字识别有个本质区别车牌字符的排列非常规则但车牌区域的几何变形可能很严重。直接对YOLO检测到的原始裁剪框做OCR如果车牌本身有透视旋转字符就会是歪的识别率会明显下降。所以我的处理流程是YOLO检测出车牌框之后先用车牌的四角点做一个透视矫正把车牌区域拉正成规整的矩形然后再送进字符识别网络。四角点可以从YOLO的多关键点检测获得也可以用OpenCV对裁剪区域做边缘检测来求解。import cv2 import numpy as np def order_points(pts): rect np.zeros((4, 2), dtypefloat32) s pts.sum(axis1) rect[0] pts[np.argmin(s)] rect[2] pts[np.argmax(s)] diff np.diff(pts, axis1) rect[1] pts[np.argmin(diff)] rect[3] pts[np.argmax(diff)] return rect def four_point_transform(image, pts): rect order_points(pts) (tl, tr, br, bl) rect width_top np.linalg.norm(br - bl) width_bottom np.linalg.norm(tr - tl) max_width max(int(width_top), int(width_bottom)) height_left np.linalg.norm(tr - br) height_right np.linalg.norm(tl - bl) max_height max(int(height_left), int(height_right)) dst np.array([ [0, 0], [max_width - 1, 0], [max_width - 1, max_height - 1], [0, max_height - 1]], dtypefloat32) M cv2.getPerspectiveTransform(rect, dst) warped cv2.warpPerspective(image, M, (max_width, max_height)) return warped有了这个矫正步骤后续的字符识别准确率能提升好几个百分点。这个细节看似不起眼却是我在项目里反复对比之后得出的结论值得每一位做车牌识别的人重视。4.2 新能源绿牌与双层黄牌的特殊处理国内车牌不只有一种规格。新能源车牌是渐变绿色字符排列和普通蓝牌一致但宽度略大挂车等大型车辆的车牌是双层的上面一层是省份简称加登记编号下面一层是另一段编号这让YOLO检测框的宽高比和普通车牌完全不同。针对双层车牌我在项目里单独加了处理逻辑如果YOLO检测出的框宽高比小于1.5就认为是双层黄牌此时不能直接当作普通一列车牌来识别需要把检测框拆成上下两个区域分别送进识别模型再拼接结果。这个逻辑用OpenCV实现不难但它说明了一个问题车牌识别不是一个模型通吃所有真正稳定的系统需要构建在规则和模型共同配合之上。绿牌的处理相对简单主要是确保训练数据里包含足够多的绿色车牌样本让YOLO能准确把绿牌检测出来。CCPD里绿牌占比不高所以针对新能源车单独补充了约5000张标注图像训练后绿牌召回率从不足80%提升到了97%左右。4.3 LPRNet的搭建与训练要点车牌字符识别网络我选的是LPRNet它在学术界和工业界都很成熟特点是没有RNN结构轻量可以处理变长输入配合CTC损失函数使用。输入图像通常是宽94像素、高24像素的灰度图输出是车牌字符序列。LPRNet的核心思想是先把整张车牌图像通过卷积网络提取特征然后把特征序列按时序方向做分类最后用CTC解码得到字符序列。车牌字符集合固定包括省份汉字、24个字母去掉I和O、10个数字再加一个背景空白符总共约70个类别。训练LPRNet时要注意样本的车牌字符长度是固定的7位不包括双层车牌但CTC可以处理这种情况。我在训练时对每张车牌图像做了随机亮度扰动、轻微模糊、随机裁剪模拟真实场景。损失函数用CTC loss优化器选Adam学习率0.001大概训练20个epoch就能收敛到98%以上的字符准确率。# LPRNet字符集定义示例 CHARS [京, 沪, 津, 渝, 冀, 豫, 云, 辽, 黑, 湘, 皖, 鲁, 新, 苏, 浙, 赣, 鄂, 桂, 甘, 晋, 蒙, 陕, 吉, 闽, 贵, 粤, 青, 藏, 川, 宁, 琼, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F, G, H, J, K, L, M, N, P, Q, R, S, T, U, V, W, X, Y, Z]5. 走出实验室模型转换、推理加速与恶劣场景调优5.1 从PyTorch到ONNX再到TensorRT的转换训练好模型只是第一步真正落地时模型的推理速度和部署方式同样重要。YOLO原生是PyTorch框架但很多生产环境根本不会安装PyTorch而且PyTorch的CPU推理效率比较低。所以项目里我把模型导出成ONNX格式再根据目标平台转成TensorRT或者OpenVINO。导出过程本身很简单YOLO官方提供了统一的export命令。yolo export modelbest.pt formatonnx dynamicTrue导出之后用ONNX Runtime做验证如果输出结果和PyTorch一致就可以考虑TensorRT了。TensorRT是NVIDIA显卡上的高性能推理引擎能显著提升吞吐量。转换命令如下开启FP16精度可以让推理速度再翻一倍左右。trtexec --onnxbest.onnx --saveEnginebest.trt --fp16在转换的过程中我遇到过一个典型的坑如果导出ONNX时没有设置dynamicTrue而模型输入分辨率是固定的960x960那部署时所有图片都必须resize到960x960否则推理会直接报错。实际项目中不同相机分辨率差异很大所以建议导出时打开动态维度虽然会增加一点点推理开销但换来了灵活性完全值得。5.2 多语言环境下的推理集成项目交付时不同的客户对技术栈要求不一样有的用C有的用Java有的前端在用Python。YOLO模型导出成ONNX或者TensorRT之后这几门语言里都能调用。Python环境里最简单的是用ONNX Runtimeimport onnxruntime as ort import cv2 import numpy as np session ort.InferenceSession(best.onnx, providers[CUDAExecutionProvider, CPUExecutionProvider]) image cv2.imread(car.jpg) # 预处理resize、归一化、BGR转RGB按模型输入要求构造blob ... outputs session.run(None, {session.get_inputs()[0].name: blob})Java端可以用DJL或者直接通过HTTP方式调用Python推理服务。我在实际项目里选择的是把YOLO检测和LPRNet识别统一封装成一个FastAPI服务Java、C#、前端都通过接口调用这样做的好处是算法更新时服务端替换模型即可客户端代码完全不用动。from fastapi import FastAPI, UploadFile import numpy as np import cv2 app FastAPI() app.post(/plate_recognition) async def plate_recognition(file: UploadFile): data await file.read() img cv2.imdecode(np.frombuffer(data, np.uint8), cv2.IMREAD_COLOR) # 调用YOLO检测 矫正 LPRNet识别 result run_plate_recognition(img) return result如果是在视觉软件里集成比如VisionPro一般可以通过导出ONNX模型并使用对应的深度学习推理工具导入。不过坦率说这种工业视觉软件对自定义模型的兼容性不如自家SDK好更稳妥的做法还是C封装动态库再通过混合调用接入。5.3 夜间、反光、雨雾场景的调整策略模型在干净阳光下的测试集上跑出99%的精度并不难真正考验系统稳定性的是夜间、反光、雨雾这些恶劣场景。在这些情况下图像对比度低车牌区域还可能被灯光打得到处是耀斑YOLO很容易漏检。我的处理思路分三个层次。第一个层次是在图像预处理端解决问题对暗光图像做自适应直方图均衡化或者增强亮度的操作把车牌区域的对比度拉起来。第二个层次是在训练数据层面解决专门收集夜间红外相机图像和现场补光灯图像加入训练集让模型见过这些光照模式。第三个层次是在系统逻辑层面解决如果单帧检测置信度太低可以基于连续视频帧做多帧投票同一块车牌在连续N帧里出现M次才判定为有效检出这样能大幅降低偶发漏检带来的影响。ROI区域设置也很重要。在固定相机的场景下比如停车场入口车牌出现的区域其实是相对有限的。部署时用配置工具预先划定几个ROI区域YOLO只对这些区域做推理不仅减少了计算量还能顺带屏蔽很多背景干扰。6. 项目包目录解读与可扩展的实用方向6.1 解压后项目结构解读项目标题里的.zip代表这是个完整工程包分享出来主要是希望后来者能直接拿来运行和学习。我解压之后一套标准的工程结构大致是这样的vehicle_plate_yolo/ ├── dataset/ # 数据集及划分脚本 │ ├── images/ │ ├── labels/ │ └── split_data.py ├── models/ # 模型定义 │ ├── detect/ # YOLO检测相关文件 │ └── lprnet/ # LPRNet字符识别相关文件 ├── weights/ │ ├── best.pt # YOLO检测权重 │ ├── best.onnx # 导出的ONNX模型 │ └── lprnet.pth # 车牌识别权重 ├── scripts/ │ ├── xml2yolo.py # 标注格式转换脚本 │ ├── train_detect.py # 训练YOLO检测模型 │ ├── train_lprnet.py # 训练LPRNet识别模型 │ └── detect_and_ocr.py # 检测识别完整流程 ├── deploy/ │ ├── fastapi_server.py # HTTP推理服务 │ ├── trt_build.sh # TensorRT转换脚本 │ └── openvino_export.py # OpenVINO转换脚本 └── requirements.txt拿到任何一个类似的工程包建议先看README或者requirements文件确认依赖环境。然后用自己的一张车牌图片跑通detect_and_ocr.py再逐步调整参数换数据集重新训练。6.2 后续可以做的几个扩展方向这个项目本身已经能完成车牌检测和识别但如果你在自己的业务里用到它有几个扩展方向是很有价值的。第一个方向是车辆品牌和车型识别。在车牌识别的同时用另一个YOLO分类头或者单独的分类模型对车身区域做车型识别这在停车场管理、出入口控制系统里非常有用。不过这里要提醒一句如果动了YOLO的检测头比如把回归头替换成分类头要谨慎评估对原有性能的影响。检测头改动之后原来预训练权重里的特征提取层可能还能沿用但头部的训练需要更多数据也更容易出现不稳定的情况。热搜里问yolo换检测头有风险吗答案是有风险但可控只要数据给足、训练策略留出足够余量。第二个方向是做车辆跟踪。在视频流里YOLO检测出车牌后用ByteTrack或DeepSORT对车辆进行跟踪可以在车辆没有清晰车牌的帧也能保持轨迹连续等到车牌清晰帧再补全识别结果。这能大幅提升整套系统在动态场景下的实用性。第三个方向是模型轻量化。如果最终部署在低算力边缘设备上比如Jetson Nano或者树莓派可以考虑把YOLO主干网络换成MobileNet或VanillaNet这类轻量结构或者在TensorRT的基础上再用INT8量化。我在另一个项目里尝试过用VanillaNet替代YOLOv8的默认主干推理速度提升了约40%精度只下降了1到2个百分点对很多业务来说完全够用。6.3 我的一点点经验总结最后说说我做完这个项目后的一些体会。车牌识别这个方向看起来被做烂了但真正自己从数据到训练再到部署完整做一遍还是会碰到非常多的细节问题。这些细节不在论文里也不在开源项目的README里只能在真实场景里一点点踩出来。比如YOLO检测的置信度阈值默认0.25在很多场景下偏保守会导致一些模糊的车牌被判成背景但如果调得太低又会出现大量误检。实际调优时我常常针对白天和夜晚分别设置两套阈值效果比一套阈值硬跑全时段要好得多。再比如字符识别阶段的置信度校准LPRNet的Softmax输出未必能真实反映识别错误的概率。如果只追求单字符准确率最终整牌准确率会被每个字符的错误率连乘放大7个字符的单字符准确率99%听起来很高但整牌准确率会掉到93%左右。所以训练时我会额外关注整牌级别的评估指标而不是只看字符准确率。这种问题很难通过换一个更大的模型彻底解决最适合的路径是稳定可靠的检测模型配合精准的矫正逻辑再加上一个轻量但训练扎实的识别网络最后用工程上的规则把置信度和边界case兜住。你说它复杂吗确实不复杂。但这个组合能把一个爬满各种坑的车牌识别系统稳稳定定地跑到生产环境里。如果你准备拿这个项目包做二次开发我的建议是不要急着改网络结构先把流程完整跑通再用自己的场景数据重新训练一遍检测和识别模型你会发现大部分精度问题其实都出在数据分布和场景适配这个层面而不是模型结构本身。本文还有配套的精品资源点击获取
返回列表