共计 3116 个字符,预计需要花费 8 分钟才能阅读完成。
背景介绍
CCPD(Chinese City Parking Dataset)是目前最全面的中文车牌识别数据集之一,由国内研究团队收集整理。它包含超过 30 万张真实场景下的车牌图像,覆盖多种天气条件、光照变化和拍摄角度。数据集的主要特点包括:

- 高多样性:包含普通蓝牌、新能源绿牌、使馆黑牌等常见车牌类型
- 精细标注:每张图片提供车牌位置、字符内容、车牌颜色等完整标注信息
- 真实场景:所有图片均来自实际道路和停车场,具有典型的复杂背景
在车牌识别任务中,CCPD 因其规模和质量成为业界标杆数据集,常用于验证算法在真实场景下的表现。
数据下载
官方下载地址为 GitHub 项目页面:CCPD-GitHub。但由于服务器位于国外,国内开发者可能会遇到下载速度慢的问题。以下是几种解决方案:
- 使用国内镜像源:部分高校和研究机构提供了数据集镜像
- 分卷下载:官方提供了按省份划分的数据子集,可以分批下载
- 云盘备份:技术社区中常有爱好者分享的百度网盘 / 阿里云盘链接
建议下载完整版 CCPD2019 数据集(约 12GB),包含最丰富的样本类型。
数据预处理
标注格式解析
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 解析代码示例:
import re
from pathlib import Path
def parse_ccpd_filename(filename):
"""解析 CCPD 文件名中的标注信息"""
stem = Path(filename).stem
parts = stem.split('-')
# 解析车牌号码
plate_number = parts[-2].replace('_', '')
# 解析车牌区域坐标 (x1,y1,x2,y2)
bbox = list(map(int, parts[2].split('&') + parts[3].split('&')))
# 解析角点坐标
corners = list(map(int, re.split('[&_]', parts[1])))
corners = [(corners[i], corners[i+1]) for i in range(0, 8, 2)]
return {
'plate_number': plate_number,
'bbox': bbox,
'corners': corners
}
图像增强技巧
针对车牌识别任务,推荐以下预处理流程:
- 透视变换:利用角点信息将车牌区域校正为矩形
- 直方图均衡化:改善低光照条件下的图像质量
- 随机模糊 / 噪声:增强模型对模糊图像的鲁棒性
- 颜色空间转换:针对不同颜色车牌使用不同的预处理通道
import cv2
import numpy as np
def preprocess_plate(image, corners):
"""根据角点进行透视变换"""
# 源角点(从图像中检测的车牌四角)src_pts = np.array(corners, dtype=np.float32)
# 目标角点(标准矩形)width, height = 136, 36 # 车牌标准宽高比
dst_pts = np.array([[0,0], [width,0],
[width,height], [0,height]], dtype=np.float32)
# 计算透视变换矩阵并应用
M = cv2.getPerspectiveTransform(src_pts, dst_pts)
warped = cv2.warpPerspective(image, M, (width, height))
# 转换为灰度图
gray = cv2.cvtColor(warped, cv2.COLOR_BGR2GRAY)
# 直方图均衡化
equalized = cv2.equalizeHist(gray)
return equalized
模型训练
推荐模型架构
对于车牌识别任务,推荐以下两种架构:
- CRNN(CNN+RNN+CTC):适合端到端识别,无需字符分割
- 两阶段检测 + 识别:先用 YOLO 检测车牌,再用 CNN 识别字符
训练代码片段
以下是 CRNN 模型的 PyTorch 训练示例:
import torch
import torch.nn as nn
from torch.utils.data import DataLoader
class CRNN(nn.Module):
def __init__(self, num_chars):
super().__init__()
# CNN 特征提取
self.cnn = nn.Sequential(nn.Conv2d(1, 64, 3, padding=1), nn.ReLU(), nn.MaxPool2d(2),
nn.Conv2d(64, 128, 3, padding=1), nn.ReLU(), nn.MaxPool2d(2),
nn.Conv2d(128, 256, 3, padding=1), nn.BatchNorm2d(256), nn.ReLU(),
nn.Conv2d(256, 256, 3, padding=1), nn.ReLU(),
nn.MaxPool2d((2,1))
)
# RNN 序列建模
self.rnn = nn.LSTM(256, 128, bidirectional=True, num_layers=2)
# 输出层
self.fc = nn.Linear(256, num_chars+1) # +1 for CTC blank
# 关键训练参数
batch_size = 32
learning_rate = 0.001
epochs = 50
# 数据加载
train_loader = DataLoader(dataset, batch_size=batch_size, shuffle=True)
# 初始化模型和优化器
model = CRNN(num_chars=68) # 31 个汉字 +10 数字 +24 字母 + 3 特殊字符
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
criterion = nn.CTCLoss()
# 训练循环
for epoch in range(epochs):
for images, labels, lengths in train_loader:
optimizer.zero_grad()
outputs = model(images)
loss = criterion(outputs, labels, input_lengths, label_lengths)
loss.backward()
optimizer.step()
避坑指南
常见误区
- 忽略车牌颜色信息:新能源车牌识别需要特殊处理
- 直接 resize 破坏宽高比:车牌有固定比例 (约 3.7:1)
- 过度增强导致字符变形:特别是对汉字识别的影响较大
优化建议
- 数据层面:
- 按省份划分训练 / 验证集(避免地域偏差)
- 对模糊样本单独增强
- 模型层面:
- 使用 Focal Loss 解决字符类别不平衡
- 添加注意力机制提升长序列识别效果
- 后处理:
- 结合车牌规则进行结果校验(如省份简称 + 发证机关代码)
- 使用语言模型修正易混淆字符(如 ’0’ 与 ’D’)
总结与展望
CCPD 数据集为中文车牌识别研究提供了高质量的基准。随着深度学习技术的发展,车牌识别正朝着以下方向演进:
- 轻量化:移动端实时识别(<50ms)
- 多任务统一:检测、识别、颜色分类一体化
- 无监督学习:减少对标注数据的依赖
建议读者从 CCPD 基础版开始,逐步尝试更复杂的变种(如 CCPD-FN 检测夜间车牌)。在实际项目中,可以结合具体场景对数据集进行适当扩充,例如添加特定场所的专属车牌样本。
正文完
