1. CCPD数据集概述与下载指南
CCPD(Chinese City Parking Dataset)是目前国内规模最大、标注最完善的开源车牌数据集之一。我第一次接触这个数据集是在2019年做智能交通项目时,当时为了找合适的车牌数据翻遍了国内外平台,直到发现CCPD才真正解决了数据瓶颈问题。
这个数据集分为两个主要版本:
- CCPD2019:包含25万+蓝色普通车牌图像
- CCPD2020:专为新能源车设计的绿色车牌数据集
数据集最让我惊喜的是其丰富的场景覆盖:
- 不同天气条件(雨雪雾)
- 各种拍摄角度(水平倾斜最高50度)
- 多种光照情况(过曝/欠曝)
- 运动模糊等真实场景干扰
下载方式很简单:
# CCPD2019 (12.26GB) wget https://example.com/ccpd2019.zip # 替换为实际下载链接 # CCPD2020 (865MB) wget https://example.com/ccpd2020.zip实测发现百度云下载速度更快,建议用官方提供的百度云链接。下载后记得校验MD5值,我遇到过两次下载中断导致文件损坏的情况。
2. 数据标注解析实战
CCPD最特别的是其"文件名即标注"的设计。刚开始用的时候觉得这种设计很反人类,但熟悉后发现其实非常高效。来看个典型文件名示例:
025-95_113-154&383_386&473-386&473_177&454_154&383_363&402-0_0_22_27_27_33_16-37-15.jpg用Python解析非常方便:
def parse_filename(filename): parts = filename.split('-') return { 'ratio': parts[0], # 车牌区域占比 'angle': list(map(int, parts[1].split('_'))), # 水平/垂直倾斜角 'bbox': [list(map(int, p.split('&'))) for p in parts[2].split('_')], # 边界框 'vertices': [list(map(int, p.split('&'))) for p in parts[3].split('_')], # 四顶点坐标 'plate_num': decode_plate(parts[4]), # 车牌号码 'brightness': int(parts[5]), # 亮度值 'blurriness': int(parts[6].split('.')[0]) # 模糊度 }车牌号码的解码需要特别注意:
provinces = ["皖", "沪", "津", "渝", "冀", "晋", "蒙", "辽", "吉", "黑", "苏", "浙", "京", "闽", "赣", "鲁", "豫", "鄂", "湘", "粤", "桂", "琼", "川", "贵", "云", "藏", "陕", "甘", "青", "宁", "新"] def decode_plate(plate_str): codes = list(map(int, plate_str.split('_'))) province = provinces[codes[0]] chars = [chr(ord('A')+x) if x<26 else str(x-26) for x in codes[1:]] return province + ''.join(chars)3. 数据预处理技巧
3.1 图像增强方案
在车牌识别任务中,我常用的增强组合是:
transform = transforms.Compose([ transforms.ColorJitter(brightness=0.3, contrast=0.3), # 应对光照变化 transforms.RandomRotation(10), # 增强旋转鲁棒性 transforms.RandomPerspective(distortion_scale=0.2), # 模拟视角变化 GaussianBlur(kernel_size=3) # 抗模糊 ])3.2 数据清洗经验
CCPD虽然标注质量整体不错,但仍有约3%的脏数据需要处理。我通常用以下规则过滤:
- 检查边界框是否超出图像范围
- 验证车牌号码是否符合编码规则
- 剔除亮度/模糊度极值样本
def is_valid_sample(metadata): # 检查边界框 x1, y1 = metadata['bbox'][0] x2, y2 = metadata['bbox'][1] if not (0 <= x1 < x2 < 720 and 0 <= y1 < y2 < 1160): return False # 检查车牌号码 plate = metadata['plate_num'] if len(plate) not in (7,8) or not plate[0] in provinces: return False return True4. 模型训练实战
4.1 YOLOv5检测模型配置
推荐使用以下配置进行训练:
# yolov5s_ccpd.yaml nc: 1 # 只有车牌一个类别 depth_multiple: 0.33 width_multiple: 0.50 anchors: - [10,13, 16,30, 33,23] # P3/8 - [30,61, 62,45, 59,119] # P4/16 - [116,90, 156,198, 373,326] # P5/32启动训练命令:
python train.py --img 640 --batch 32 --epochs 100 --data ccpd.yaml --cfg yolov5s_ccpd.yaml --weights yolov5s.pt4.2 LPRNet识别模型优化
针对车牌识别任务,我对原始LPRNet做了三点改进:
- 增加空间注意力模块
- 调整CNN通道数适配车牌长宽比
- 使用Focal Loss解决字符类别不平衡
关键修改部分:
class EnhancedLPRNet(nn.Module): def __init__(self, lpr_max_len=8): super().__init__() self.backbone = nn.Sequential( nn.Conv2d(3, 64, 3, 1), nn.BatchNorm2d(64), SpatialAttention(), # 新增注意力 nn.ReLU(), # ... 其他层保持不变 ) self.loss = FocalLoss(gamma=2) # 替换原始CrossEntropy5. 模型部署与性能优化
5.1 TensorRT加速实践
将PyTorch模型转为TensorRT能获得3-5倍加速:
# 转换脚本示例 builder = trt.Builder(TRT_LOGGER) network = builder.create_network() parser = trt.OnnxParser(network, TRT_LOGGER) # 加载ONNX模型 with open("lprnet.onnx", "rb") as f: parser.parse(f.read()) # 配置优化参数 config = builder.create_builder_config() config.set_memory_pool_limit(trt.MemoryPoolType.WORKSPACE, 1 << 30) engine = builder.build_engine(network, config)5.2 端侧部署技巧
在树莓派等边缘设备上,我推荐:
- 使用量化后的TFLite模型
- 开启ARM NEON加速
- 采用多线程流水线处理
实测性能对比:
| 设备 | 原始模型 | 优化后 | 提升 |
|---|---|---|---|
| Jetson Nano | 12 FPS | 28 FPS | 2.3x |
| Raspberry Pi 4 | 3 FPS | 9 FPS | 3x |
6. 常见问题解决方案
问题1:小尺寸车牌检测效果差
- 解决方案:在YOLOv5中添加小目标检测层
- 修改模型配置:
# 添加P2检测头 head: [[-1, 1, Conv, [256, 1, 1]], [-1, 1, nn.Upsample, [None, 2, 'nearest']], [[-1, 3], 1, Concat, [1]], [-1, 3, C3, [256, False]], [-1, 1, Conv, [256, 3, 2]], [[-1, 4], 1, Concat, [1]], [-1, 3, C3, [512, False]], # ... 原有结构 ]问题2:新能源车牌识别率低
- 根本原因:CCPD2020数据量较少
- 解决方案:
- 使用迁移学习,先用CCPD2019预训练
- 添加新能源车牌数据增强:
# 模拟绿色车牌色调 def green_plate_aug(img): hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) hsv[:,:,0] = hsv[:,:,0] * 0.7 # 调整色相 return cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)在实际项目中,建议定期用bad case分析工具找出模型弱点,有针对性地补充训练数据。我开发了一个自动化分析工具,可以自动聚类识别错误的样本类型。