[深度学习] CCPD数据集实战:从数据解析到模型训练全流程
·
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 True
4. 模型训练实战
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.pt
4.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) # 替换原始CrossEntropy
5. 模型部署与性能优化
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分析工具找出模型弱点,有针对性地补充训练数据。我开发了一个自动化分析工具,可以自动聚类识别错误的样本类型。
更多推荐




所有评论(0)