ARTICLE DETAIL

资讯详情

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

Python+CNN车牌识别实战:从数据准备到模型部署全流程

Python+CNN车牌识别实战:从数据准备到模型部署全流程 简介针对智能交通与自动驾驶中的车牌自动识别需求基于Python与卷积神经网络CNN的项目包提供了完整的工程代码、多样化图像数据及说明文档适合计算机视觉初学者和需要快速落地识别任务的开发者。压缩包共25个文件涵盖jpg与png车牌图像样本、py训练与测试脚本、dat预处理数据、md说明文档以及配置文件和辅助资源总大小29.2MB目录结构清晰其中7z内还附有额外的子数据集方便扩展实验。项目完整覆盖数据预处理、CNN模型构建、Keras/TensorFlow训练优化、评估指标计算与部署思路等关键环节读者可对照图片和脚本直观理解卷积特征提取、字符分割与识别流程并在现有基础上调整参数或扩展车型检测等功能。目前已有206人学习借助示例图片和代码即可复现车牌识别实验是入门深度学习和图像处理任务的高质量参考资料。1. 从“车牌.zip”到可落地的识别链路PythonCNN 解决的不只是“看图说话”停车场闸机、电子警察、移动巡检车……几乎所有车牌识别系统都在做同一件事在不确定的光照和角度下把一张图里的车牌变成一串结构化字符。早期方案依赖灰度化、边缘检测和模板匹配一遇到逆光、倾斜或新能源绿牌就频繁翻车。CNN 出现后识别从“手工找特征”变成“让网络在大量标注中自己学特征”鲁棒性明显拉开差距。这里的“车牌.zip”并不是一个单一模型而是包含数据准备、模型训练、后处理和部署脚本的完整工程。适合谁想在真实场景落地车牌识别而不是只想跑通一个 demo 的 Python 开发者、算法工程师和运维。下文会按一个可复现的最小闭环来讲为什么这样选、参数怎么设、坑在哪里以及怎样让模型在本地不失控。2. 为什么选 CNN模板匹配、字符分割与端到端识别的边界在哪2.1 传统视觉在车牌识别场景的失效边界很多从 OpenCV 入门车牌识别的同学第一版算法长这样Sobel 找边缘、形态学闭运算连成连通域、按长宽比筛车牌候选然后对候选区域做字符分割最后用模板匹配识别数字字母。这套流程在固定角度、固定光照的单个停车场 demo 里确实能跑精度甚至能到九成以上。可一旦把相机装到户外情况就完全不同早晚强逆光时车牌反光灰度图上字符和底色的反差几乎消失车辆转弯时车牌带 30 度以上倾斜投影分割出来的字符互相粘连夜间补光灯过曝边缘检测会把螺栓和铆钉也当成边界。问题的本质在于传统方法把“找特征”这件事写死在代码里算子参数全是针对特定假设的。比如下面这段典型的定位逻辑看起来没什么问题实际非常脆弱import cv2 import numpy as np def locate_plate_legacy(gray): # 求水平梯度突出字符边缘 grad cv2.Sobel(gray, cv2.CV_16S, 1, 0) abs_grad np.uint8(np.abs(grad)) _, thresh cv2.threshold(abs_grad, 0, 255, cv2.THRESH_BINARY cv2.THRESH_OTSU) # 用横向闭运算把字符连成整体 kernel cv2.getStructuringElement(cv2.MORPH_RECT, (25, 7)) closed cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel) contours, _ cv2.findContours(closed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) for c in contours: x, y, w, h cv2.boundingRect(c) if 2.0 w / h 6.0 and w 80: return x, y, w, h return None这段代码里 25 乘 7 的矩形核是针对 1080p 图像调的换成 4K 相机后字符尺寸放大同一个核可能把整块车牌连成一个大连通域也可能把剪贴字符直接冲出边缘。Sobel 阈值用 Otsu 自适应已经算进步但一旦车牌上有灰尘或泥点闭运算会把污渍和字符连成一片。更别提后续字符分割通常要按投影找“谷底”而汉字内部结构复杂投影后经常多切一刀。这些坑不是靠调参能填平的因为目标域本身是非线性变化的。CNN 带给车牌识别的核心变化是把“边缘、颜色、字符结构”这些设计好的特征选择器替换成可学习的卷积核网络在大量标注样本里自己提炼什么样的特征组合最有利于分类。对逆光、模糊和倾斜它学出来的特征比手写算子稳定得多所以现在生产环境几乎不再有人用纯模板匹配做车牌识别CNN 的定位和识别成为默认选项。2.2 两段式“检测 识别”与端到端 CNN 怎么选我接触到的车牌识别工程基本分成两类架构。一类是两段式先用目标检测网络把车牌区域从整图中框出来再把裁剪区域单独送进一个字符识别网络。检测网络常用 YOLOv8n 这类轻量模型识别网络则是把车牌图输入 CNN输出“省份、字母、数字”的一系列分类结果。另一类是完全端到端代表性的如 LPRNet图像进去直接输出一整串字符不做显式字符分割。两类都能用选择取决于你的数据量和部署形态。两段式的最大优点是故障隔离清晰。检测漏了处理检测识别错字处理识别。字符级 CNN 输出每个位置的 softmax定位哪个字符错了非常直观后处理干预空间也大。缺点是流程长检测模型和识别模型各维护一套标注成本高——检测框和字符标签都要标。端到端 LPRNet 则把整个车牌字符序列识别当成一个序列学习问题用 CNN 提取特征后接双向 LSTM再用 CTC loss 对齐不定长字符输出只需要整牌标签不需要字符框标注。它的优势是标注成本低、模型小推理速度快但排错体验差一些。字符级置信度不如分类器那么直接现场某位反复出错时很难定位是网络问题还是预处理问题。如果你要部署到闸机这种算力有限、对速度有硬要求的场景我更推荐先走两段式里“检测用 YOLO、识别用轻量 CNN”的路线。识别网络不需要做得很深车牌字符集就那么大一个五层卷积加全连接的小模型就能达到单字符 99% 以上准确率整体调试体验明显更顺。反观 LPRNet虽然单模型结构更优雅但中文车牌里省份汉字和数字字母混排CTC 路径搜索在极端模糊样本上容易整串错且错一个字符往往牵连位置推断排错成本反而更高。2.3 框架选型与项目骨架PyTorch 训练、ONNX 部署市场上 Python 车牌识别的开源工程十份里有八份用 PyTorch剩下是 TensorFlow 或 PaddlePaddle。选 PyTorch 不完全是性能原因更多是生态和调试体验。torch 的动态图在车牌这种输入尺寸不完全固定的任务里写起来自然断点调试能看到中间张量。TensorFlow 2 也完全能做但如果你想把模型转到 ONNX 部署PyTorch 的torch.onnx.export成熟度高很多遇到算子不通的情况社区帖子也最多。我的项目骨架通常按四个目录组织plate_project/ ├── data/ # 原始图像、标注、训练验证集 ├── detector/ # 车牌检测模型YOLO训练与推理 ├── recognizer/ # 字符识别 CNN 训练脚本、数据加载器 └── deploy/ # ONNX 导出、量化、推理服务、前后处理detector 和 recognizer 两套模型分开后续任何一个升级都不影响另一个。两段式方案的识别数据加载器核心是按字符序列构造标签并把标签转成长度对齐的张量这一点比端到端简单得多。部署阶段再把两个模型都导出成 ONNX用 ONNX Runtime 统一加载既不用在服务进程里装完整版 PyTorch也能拿到跨平台的推理性能。常见做法是训练用 PyTorch部署用 ONNX Runtime二者只差一层转换不用动原始网络定义。先想清楚为什么这样拆再谈代码实现检测模型负责空间定位识别模型负责语义理解两部分解耦之后现场新装一个高位相机导致车牌倾斜变大时只需要在识别模型的数据增强里把透视变换幅度加大重训识别网络即可不用动检测部分。反过来如果检测在新场景漏检严重就单独补充负样本或调 NMS 阈值不碰识别逻辑。这种“先选型再写码”的顺序能避免多数新手把训练脚本写得一团乱麻。很多人一上来只看模型结构忽略了数据分布对精度的影响结果样本稍微偏移模型就在真实场景大幅掉点。下一章我会直接把可复跑的数据准备和训练参数讲透这些细节比模型结构更能决定项目成败。3. 从零跑通最小车牌识别系统数据准备到模型训练3.1 环境准备Python 版本、依赖与 GPU 验证解压一份车牌识别工程后第一件事往往不是读模型代码而是把环境支起来。这里有一个老生常谈但依然高频的坑python 版本不匹配。很多老工程用旧版torch或tf.keras写的拿到新机器直接pip install会因 Python 3.11 移除了distutils而报错。我一般建议用 Conda 固定环境Python 版本选 3.9 或 3.10两者对 PyTorch、TensorFlow 和 ONNX Runtime 的兼容性都最好。训练代码如果是纯 PyTorch用 3.10 往往是最省心的选项。依赖安装顺序也很重要先装 PyTorch 再装其他包因为 torch 的 wheel 会带特定版本的 numpy后装的 numpy 可能把版本顶掉。下面的命令是常见做法conda create -n plate python3.10 -y conda activate plate pip install torch torchvision --index-url https://download.pytorch.org/whl/cu121 pip install opencv-python onnxruntime onnx pyyaml tqdm如果你的机器没有 NVIDIA GPU只有 CPU 或集成显卡可以把 torch 的安装源换成 CPU 版训练慢一点但能跑。装完后一定要用下面这段代码验证环境避免训练到一半才发现 CUDA 根本不可用import torch, cv2 print(torch:, torch.__version__, cuda:, torch.cuda.is_available(), torch.cuda.get_device_name(0) if torch.cuda.is_available() else ) print(opencv:, cv2.__version__)不验证的后果我很清楚有同事在 GPU 服务器上跑了一整天训练最后一看日志里devicecpu整个实验白做。这种低级错误浪费的时间比训练本身多得多。3.2 自制数据集真实车牌采集与合成数据增强车牌识别数据集最常见的问题是类别不均衡。中文车牌字符集包含省份简称、字母、数字其中省份约 30 多个字符数字字母 34 个。开源车牌数据集里广东、北京的车牌特别多小省份样本很少字母和数字里形近字如 0 和 O、1 和 I 分布也差异明显。如果直接拿去训练模型对小省份简称和形近字的错分率会显著偏高。常见做法是先收集真实数据再把合成数据作为补充。真实数据来源覆盖不同角度、光照和昼夜场景手动框出车牌并记录字符串标签。合成数据则是在随机背景上渲染车牌字符加字体、透视变换、光照扰动。我通常采用这样的增强管线和参数import cv2 import numpy as np import imgaug.augmenters as iaa aug_pipeline iaa.Sequential([ iaa.Affine(rotate(-12, 12), shear(-8, 8)), iaa.PerspectiveTransform(scale(0.0, 0.08)), iaa.AdditiveGaussianNoise(scale(0, 0.04 * 255)), iaa.MotionBlur(k(3, 7)), iaa.LinearContrast((0.7, 1.3)), ]) def load_plate_sample(path): img cv2.imread(path) img cv2.cvtColor(img, cv2.COLOR_BGR2RGB) img cv2.resize(img, (94, 24)) # 统一到识别网络输入尺寸 return img参数说明旋转和透视变换的幅值不宜过大。旋转超过正负 12 度、透视 scale 超过 0.08 时合成样本扭曲程度已经超过真实相机能拍出的范围模型学到奇怪的空间形变反而降低真实场景精度。MotionBlur 和噪声是模拟夜间低照度和运动拖影的关键这两项对现场提升最明显。imgaug 每次调用会随机取区间内数值且序列整体在同一个随机状态下执行保证坐标同步变换这也是它比自行写 numpy 仿射变换更稳的原因。数据量上我的经验是检测网络至少准备 1 万张以上的整图识别网络至少 5 万张以上的车牌裁剪图。如果只有几千张训练集太薄模型再先进也白搭。标签格式统一成 JSON 或 CSV每行记录图像路径和车牌字符串下面是一个典型的数据加载器片段import json from torch.utils.data import Dataset, DataLoader class PlateDataset(Dataset): def __init__(self, meta_file, augNone): with open(meta_file, r, encodingutf-8) as f: self.samples [json.loads(line) for line in f] self.aug aug def __len__(self): return len(self.samples) def __getitem__(self, idx): s self.samples[idx] img cv2.imread(s[image]) img cv2.cvtColor(img, cv2.COLOR_BGR2RGB) img cv2.resize(img, (94, 24)) if self.aug: img self.aug(imageimg) img torch.from_numpy(img).permute(2, 0, 1).float() / 255.0 label s[plate] # 如 京A12345 return img, label这里的aug传入上一步定义好的 imgaug 流水线就能在训练时随机增强大幅扩展有效样本量。注意resize放在增强之前还是之后量级差别很大我把 resize 放在增强之前增强算子作用在统一尺寸上仿射旋转不会产生大量超出图像边界的区域。3.3 构建轻量 CNN 识别网络结构与字符集映射两段式方案的识别网络非常简单不需要 ResNet 这种深层结构。车牌图像本身低分辨率、字符区域相对规整一个 4 到 5 层的轻量 CNN 就够了。我常用的结构是三层卷积加两层全连接输入 94 乘 24 的 RGB 图像输出长度等于字符集大小的分类概率每个位置对应一个字符。关键点是把字符集映射表统一管理省份简称、字母、数字按固定顺序排好训练和推理共用同一张表避免两边字符 index 不一致。下面是构建识别网络的核心代码这里我选择一个带全局平均池化的版本它对不同车牌宽高比更鲁棒import torch.nn as nn class PlateCharCNN(nn.Module): def __init__(self, num_classes): super().__init__() self.features nn.Sequential( nn.Conv2d(3, 32, 3, padding1), nn.BatchNorm2d(32), nn.ReLU(inplaceTrue), nn.MaxPool2d(2), nn.Conv2d(32, 64, 3, padding1), nn.BatchNorm2d(64), nn.ReLU(inplaceTrue), nn.MaxPool2d(2), nn.Conv2d(64, 128, 3, padding1), nn.BatchNorm2d(128), nn.ReLU(inplaceTrue), nn.AdaptiveAvgPool2d((1, 4)), ) self.classifier nn.Sequential( nn.Linear(128 * 4, 256), nn.ReLU(inplaceTrue), nn.Dropout(0.3), nn.Linear(256, num_classes), ) def forward(self, x): x self.features(x) # [B, 128, 1, 4] x x.view(x.size(0), -1) return self.classifier(x) # [B, num_classes]参数说明AdaptiveAvgPool2d((1, 4))是这里的关键它把最后一个卷积输出特征图的高度压成 1宽度固定成 4等于在特征维度上做了尺度归一化。车牌字符有 7 个新能源车牌可能是 8 位不同批次输入宽度可能不同自适应池化能避免全连接层因输入尺寸变化直接报错。BatchNorm 和 Dropout 一起用能明显抑制过拟合小数据集上效果尤其明显。如果把网络最后一层的输出维度和车牌的字符位置一一对应起来则是另一种设计位置感知的字符分类器。它把车牌固定为 7 个位置每个位置独立分类。这个方案在字符对齐上更简单但要求预处理时把车牌严格裁剪成固定区域稍有错位就可能整体错位识别。我在真实项目里更常用基础版本整张车牌一次分类输出一个序列配合字符级别的注意力或动态规划对齐字符顺序信息保留得更好。3.4 训练参数标签编码、学习率调度与早停训练一个车牌字符分类器损失函数常用交叉熵但要注意标签编码方式。车牌字符串长度固定为 7 或 8直接把字符串每个字符转成 index 作为预测目标即可。若你选 LPRNet 这类端到端网络就要用 CTC loss并给标签预留空白符。这里我以更易上手的“位置无关整串分类”举例标签编码和训练循环如下import torch class PlateCollator: def __init__(self, char_map): # char_map: {京: 0, ..., 0: 32, ...} self.char_map char_map def __call__(self, batch): images, plates zip(*batch) images torch.stack(images) # 标签转成 id 序列不足 8 位补 -1训练时在 loss 里 mask 掉 labels torch.full((len(plates), 8), -1, dtypetorch.long) for i, p in enumerate(plates): for j, ch in enumerate(p): labels[i, j] self.char_map[ch] return images, labels训练时 loss 需要忽略标签为 -1 的位置PyTorch 的CrossEntropyLoss(ignore_index-1)正好支持。学习率我习惯先用 1e-3 跑 3 到 5 个 epoch观察 loss 下降趋势不降就把学习率降到 3e-4 或 1e-4 重新启动。完整训练脚本最关键的是 early stopping记录验证集准确率连续 10 个 epoch 不提升就保存当前最优权重后停止。这个机制能为你省下大量无效训练时间。best_acc 0.0 plateaus 0 for epoch in range(60): train_one_epoch(model, train_loader, optimizer, criterion) val_acc evaluate(model, val_loader, char_map) if val_acc best_acc: best_acc val_acc torch.save(model.state_dict(), best_plate.pt) plateaus 0 else: plateaus 1 if plateaus 10: print(fearly stop at epoch {epoch}, best_acc {best_acc:.4f}) break这个循环里我没有把scheduler.step()写进去因为车牌识别任务我更推荐用 OneCycle 或 CosineAnnealing而不是固定步长衰减。OneCycle 先升后降前 30% 训练用较高学习率跳出局部最优后面逐步收敛配合 AdamW 的情况下稳定性和最终精度都优于固定学习率。训练完成后用置信度阈值过滤低质量预测结果整牌准确率的参考基线一般要做到 97% 以上才值得进入部署阶段。这一章的内容已经足够跑通一个最小系统接下来的部署避坑才是真正拉开差距的地方。4. 部署与避坑车牌识别系统常见故障的排查顺序4.1 中文车牌字符不全导致误识别补样本还是造样本现象训练时用的车牌数据集里省份简称只有十多个模型在停车场识别“京”“沪”没问题一遇到“桂”“赣”这类样本就开始乱猜甚至把“云A12345”识别成“A12345”或“漏A12345”。原因开源车牌数据集大多来自个别地区采集省份分布严重偏向东中部省份小省份的样本量可能只有个位数。字符识别网络本质是一个统计分类器训练集中没见过或极少见的字符它在决策边界上完全没有依据输出的 softmax 往往只是在已知类别里找一个“最像”的。解决要么补充真实样本要么生成特定省份的合成样本。合成数据特别适合这一步把目标省份简称用字体渲染到空白车牌底板上再叠加自然背景和透视变形扩充几千张。注意字体要尽量贴近真实车牌字体否则模型学到的是伪特征。合成样本占比控制在总数据量的 30% 以内不要喧宾夺主。上线前最好先做一次字符频次统计from collections import Counter counter Counter() for plate in all_plates: counter.update(plate) weak_chars {ch: n for ch, n in counter.items() if n 500} print(字符样本不足, weak_chars)把频次低于 500 的字符逐个记下来再有针对性地补数据。这比看整体准确率更直观因为整牌准确率会被高频字符的高正确率掩盖而低频字符的错误对一个车主来说就是 100% 的失败。4.2 蓝牌、绿牌、黄牌混用BGR 转灰度会丢颜色先验现象蓝牌车在蓝色天空背景下漏检新能源绿牌在灰度图里字符与底色反差很小识别准确率骤降黄牌大货车经常被误切区域。原因不少工程为了省算力把检测输入从彩色图直接cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)。灰度图丢掉了颜色通道而车牌底色是最强的先验特征。CNN 如果输入是三通道可以自己学到“蓝色对应车牌”这种概念输入只剩单通道时它只能依赖边缘和字符形状性能上限被预处理砍了一截。解决检测和识别都保留三通道输入。如果实在要压缩计算量先把 RGB 转 HSV在色调通道上做一次颜色判断区分蓝牌、绿牌和黄牌后再分别走不同分支hsv cv2.cvtColor(img, cv2.COLOR_BGR2HSV) blue_mask cv2.inRange(hsv, (100, 120, 80), (130, 255, 255)) blue_ratio blue_mask.mean() / 255.0 if blue_ratio 0.05: plate_type blue elif (cv2.inRange(hsv, (35, 80, 80), (85, 255, 255)).mean() / 255.0) 0.05: plate_type green颜色分类本身成本很低却能显著减少后续误识别。部署时注意把输入管道固定为 RGB 顺序很多道路监控相机直接输出 BGR模型训练时用 RGB推理时忘了通道顺序互换会发生精度掉 5 个点以上的诡异问题。这类问题最难排查因为模型结构没变代码看起来也对就是因为通道顺序反了。4.3 识别速度不够先查预处理再查模型现象在边缘盒子上跑车牌识别单帧处理耗时 300 到 500 毫秒达不到 25 帧每秒的实时要求道闸开启有明显延迟。原因很多人第一时间怪 CNN 模型太重其实瓶颈往往在预处理。OpenCV 的图像缩放、仿射变换和大核高斯模糊在 CPU 上执行也很贵加上检测模型和识别模型串行推理整体延迟被放大模型推理本身可能只占三分之一时间。解决先用cv2.getTickCount()单独统计各环节耗时找出真正热点t0 cv2.getTickCount() detections detector.run(frame) t1 cv2.getTickCount() for box in detections: crop warp_plate(frame, box) rec recognizer.run(crop) t2 cv2.getTickCount() freq cv2.getTickFrequency() print(detect ms:, (t1 - t0) / freq * 1000) print(recognize ms:, (t2 - t1) / freq * 1000)常见优化手段把检测输入尺寸从 640 降到 512用cv2.WARP_INVERSE_MAP配合预处理使用 ONNX Runtime 或 OpenVINO 替代原始 PyTorch。对于支持 OpenCL 的集成显卡或部分 NPU 平台推理后端优先选 OpenVINO它内置算子融合和缓存机制比通用 ONNX Runtime 快不少。如果现场机器只有 x86 CPU 且模型已经轻量化可以用 int8 量化把识别模型从 FP32 压一半体积精度损失通常在 0.5% 以内。4.4 现场相机集成登录、抓拍与图像过曝的排错顺序现象车牌识别系统部署到停车场相机单独 web 后台登录不进去或者抓拍图像全黑、全部过曝导致识别率和测试时差很远。原因这类问题大概率不在模型而在相机的视频流参数或网络配置。很多一体化工控相机默认 IP 段和电脑不在同一网段需要手动调一致图像过曝则是快门、增益和宽动态配置不适配夜间环境。解决先检查网线连接和相机 IP 是否能 ping 通再看相机 SDK 的取流协议设置。抓拍参数方面夜间优先开启 HDR 或宽动态快门速度固定到 1/100 到 1/250 秒之间抑制运动模糊如果车牌反光严重略微降低增益。相机调试通过后再回来评估算法不要一上来就怀疑模型数据不够。这类排错顺序极其重要能让你少走许多弯路。4.5 验证集当测试集的陷阱跨场景测试不可省现象模型在验证集上整牌准确率 98%现场一跑只有 85%差距惊人。原因验证集和训练集来自同一采集批次光照、相机角度、车牌分布几乎一样。模型的泛化能力被高估了它很可能记住了背景特征而不是车牌语义特征。解决划分验证集时按“来源”分割而不是随机打乱。同一个停车场同一天的图片要么全在训练集要么全在验证集。更严苛的做法是留一个完全没参与训练的新场景作为测试集比如从另一个城市或另一个相机厂商的数据中抽 1000 张。只有跨场景测试保持 95% 以上的准确率我才认为模型具备上线资格。5. 进阶技巧字符级置信度过滤是上线前最后一道闸门车牌识别系统上线后运营方最在意的往往不是平均准确率而是“会不会把车 A 识别成车 B”。整牌准确率掩盖了错一字的后果错一个字符导致扣费异常比整牌识别不出来更麻烦。所以我做车牌识别模型评估时一定会加一个字符级置信度输出识别每个字符时把 softmax 向量里最大的值抽出来作为该字符的可信度。以下是推理脚本里的一个操作习惯import torch def predict_with_confidence(model, tile, id_to_char): model.eval() with torch.no_grad(): logits model(tile) # [1, num_classes] probs torch.softmax(logits, dim-1).squeeze(0) conf, idx torch.max(probs, dim-1) char id_to_char[idx.item()] return char, conf.item()返回的conf如果低于 0.85就不要把这个字符当作最终结果。常见做法是触发重新识别或直接通知平台进入人工审核如果连续两帧的识别结果只在低置信度字符位置不同再结合车辆颜色、车型等辅助信息做仲裁能显著降低整体误識率。这个过滤逻辑还可以做成规则引擎比如省份简称的置信度阈值放低到 0.8而数字字母的阈值提高到 0.9因为形近字集中在数字字母段。我自己的教训是第一次上线时只盯着整牌准确率结果客户反馈有月卡车辆在场内出现误识别扣费最后排查发现是字母“I”和数字“1”在夜间低置信度时被随机切换加了这个字符级过滤后才彻底杜绝。从那以后我无论做多小的规模实验都会把字符级置信度存进日志方便事后复盘。这个习惯希望你也能保留无论你是刚解压一份车牌识别工程的学生还是要为车牌识别系统做技术选型的集成商先把置信度过滤这块短板补上再去追逐更高准确率指标才是真正能落地的路径。希望帮到你。本文还有配套的精品资源点击获取
返回列表