共计 2510 个字符,预计需要花费 7 分钟才能阅读完成。
数据集初探
CCPD 数据集包含超过 10 万张中国车牌图像,覆盖了晴天、雨天、雾天等多种天气条件,以及车牌倾斜、遮挡、模糊等现实场景。这个数据集特别适合用来训练鲁棒性强的车牌检测模型,但处理过程中也会遇到一些挑战。
新手常见痛点
- 标注文件解析困难 :CCPD 使用 XML 格式存储标注信息,与 YOLO 等现代框架要求的 txt 格式不兼容
- 光照条件差异大 :夜间低光照和强反光场景同时存在
- 长宽比极端样本 :有些车牌宽高比达到 4:1,容易造成模型漏检
数据预处理实战
XML 转 YOLO 格式脚本
import xml.etree.ElementTree as ET
import os
def convert_ccpd_to_yolo(xml_path, output_dir):
"""
将 CCPD 的 XML 标注转换为 YOLO 格式
:param xml_path: XML 文件路径
:param output_dir: 输出目录
"""
tree = ET.parse(xml_path)
root = tree.getroot()
# 获取图像尺寸
size = root.find('size')
width = int(size.find('width').text)
height = int(size.find('height').text)
# 准备输出内容
yolo_lines = []
for obj in root.iter('object'):
# 车牌类别固定为 0(假设只有一个类别)cls_id = 0
# 获取边界框坐标
bndbox = obj.find('bndbox')
xmin = int(bndbox.find('xmin').text)
ymin = int(bndbox.find('ymin').text)
xmax = int(bndbox.find('xmax').text)
ymax = int(bndbox.find('ymax').text)
# 转换为 YOLO 格式(中心点坐标和宽高,归一化)x_center = ((xmin + xmax) / 2) / width
y_center = ((ymin + ymax) / 2) / height
w = (xmax - xmin) / width
h = (ymax - ymin) / height
yolo_lines.append(f"{cls_id} {x_center:.6f} {y_center:.6f} {w:.6f} {h:.6f}")
# 写入输出文件
base_name = os.path.splitext(os.path.basename(xml_path))[0]
output_path = os.path.join(output_dir, f"{base_name}.txt")
with open(output_path, 'w') as f:
f.write('\n'.join(yolo_lines))
图像增强技巧
- CLAHE 处理 :解决光照不均问题
import cv2
def apply_clahe(image):
# 转换到 LAB 颜色空间
lab = cv2.cvtColor(image, cv2.COLOR_BGR2LAB)
l, a, b = cv2.split(lab)
# 只在 L 通道应用 CLAHE
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
cl = clahe.apply(l)
# 合并通道并转回 BGR
limg = cv2.merge((cl,a,b))
enhanced = cv2.cvtColor(limg, cv2.COLOR_LAB2BGR)
return enhanced
- Albumentations 增强流水线
import albumentations as A
transform = A.Compose([A.RandomBrightnessContrast(p=0.5),
A.HueSaturationValue(p=0.5),
A.Rotate(limit=15, p=0.5),
A.RandomResizedCrop(height=640, width=640, scale=(0.8, 1.0), ratio=(1.5, 4.0), p=0.5),
A.CoarseDropout(max_holes=8, max_height=32, max_width=32, p=0.3)
], bbox_params=A.BboxParams(format='yolo'))
YOLOv5 模型训练
模型选择建议
- 对于嵌入式设备:选择 YOLOv5s
- 服务器端部署:选择 YOLOv5m 或 YOLOv5l
- 高精度要求:YOLOv5x+ 更大的输入尺寸 (1280×1280)
关键训练参数
# data.yaml
train: ../train/images
val: ../valid/images
nc: 1 # 类别数
names: ['license_plate']
# hyp.yaml
lr0: 0.01 # 初始学习率
lrf: 0.2 # 最终学习率 = lr0 * lrf
warmup_epochs: 3
warmup_momentum: 0.8
Warmup 策略实现
# 在 YOLOv5 的 train.py 中修改
for epoch in range(start_epoch, epochs):
# Warmup 阶段
if epoch < warmup_epochs:
lr = lr0 * (epoch / warmup_epochs) ** 2
for param_group in optimizer.param_groups:
param_group['lr'] = lr
避坑指南
- JPEG 压缩伪影 :CCPDv2 版本存在压缩质量问题,建议使用 CCPD2019 或添加去块滤波预处理
- 验证集构建 :必须包含各种天气和时间段的样本,比例与训练集一致
- 极端长宽比 :在数据增强中添加 RandomResizedCrop 时,保持 ratio 参数与车牌实际比例匹配
效果对比

左:原始图像 右:CLAHE 处理后
训练过程中的损失函数变化
思考与延伸
随着新能源车牌的普及,传统车牌检测模型可能面临新挑战:
1. 新能源车牌字符更多(8 位 vs 传统 7 位)
2. 底色和字体颜色变化更大
3. 双行排列的特殊样式
你认为应该如何改进现有模型来适应这些变化?可以从数据增强策略、网络结构改进、后处理逻辑等角度思考。
正文完
