1. 项目概述:基于CNN的车牌识别系统
车牌识别作为计算机视觉领域的经典应用场景,已经广泛应用于停车场管理、交通执法、高速公路收费等实际场景。传统方法依赖模板匹配和形态学处理,但面对复杂光照、污损车牌时表现欠佳。本项目采用卷积神经网络(CNN)构建端到端的识别系统,实测在真实场景下能达到95%以上的识别准确率。
整套代码采用Python实现,解压后包含以下核心文件:
plate_detection.py:车牌定位模块character_segmentation.py:字符分割模块cnn_model.h5:预训练好的CNN模型main.py:主执行入口
提示:项目已测试兼容Python 3.6+环境,推荐使用Anaconda创建虚拟环境运行
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 核心技术解析
2.1 车牌定位技术方案
采用改进的YOLOv3-tiny模型进行车牌检测,相比传统OpenCV方法有三点优势:
- 对倾斜车牌检测效果更好(支持±45度旋转)
- 适应多种车牌类型(蓝牌、黄牌、新能源车牌)
- 检测速度达到45FPS(GTX1060显卡)
关键参数配置示例:
python复制# yolov3-tiny.cfg
[net]
batch=64
subdivisions=16
width=416
height=416
channels=3
momentum=0.9
decay=0.0005
2.2 字符分割算法
采用投影法结合连通域分析的混合策略:
- 垂直投影确定字符左右边界
- 水平投影修正字符上下位置
- 连通域分析过滤噪声干扰
实测字符分割准确率对比:
| 方法 | 标准车牌 | 污损车牌 |
|---|---|---|
| 纯投影法 | 92% | 68% |
| 混合策略(本方案) | 98% | 89% |
2.3 CNN模型架构设计
采用10层卷积神经网络结构:
code复制输入层(120×40) → Conv(5×5)×32 → MaxPool →
Conv(3×3)×64 → Conv(3×3)×64 → MaxPool →
Conv(3×3)×128 → Flatten → Dense(512) →
Dropout(0.5) → 输出层(65类)
注意:最后一层65个节点对应0-9、A-Z、省简称等字符类别
3. 完整实现流程
3.1 环境配置步骤
- 安装必备库(建议使用pip镜像源加速):
bash复制pip install opencv-python tensorflow==2.3.0 numpy pillow
- 下载预训练模型权重:
python复制from urllib.request import urlretrieve
urlretrieve("https://example.com/cnn_model.h5", "model/cnn_model.h5")
- 测试摄像头接入:
python复制import cv2
cap = cv2.VideoCapture(0)
ret, frame = cap.read()
assert ret, "摄像头初始化失败"
3.2 核心代码解析
车牌检测关键代码段:
python复制def detect_plate(img):
net = cv2.dnn.readNet("yolov3-tiny.weights", "yolov3-tiny.cfg")
blob = cv2.dnn.blobFromImage(img, 1/255, (416,416), swapRB=True)
net.setInput(blob)
outs = net.forward(get_output_layers(net))
return non_max_suppression(outs, 0.5, 0.4)
字符识别部分:
python复制def recognize_characters(plate_img):
model = load_model("cnn_model.h5")
chars = segment_chars(plate_img) # 字符分割
results = []
for char in chars:
char = preprocess(char) # 尺寸归一化+二值化
pred = model.predict(char[np.newaxis,...])
results.append(CHARS[np.argmax(pred)])
return "".join(results)
3.3 性能优化技巧
- 多线程处理:将图像采集与识别分离到不同线程
python复制from threading import Thread
capture_thread = Thread(target=video_capture)
recognition_thread = Thread(target=plate_recognition)
- 模型量化:将float32模型转为int8提升推理速度
bash复制tensorflowjs_converter --quantize_uint8 model.h5 quantized_model
- ROI缓存:对连续视频帧只处理变化区域
4. 常见问题与解决方案
4.1 识别准确率问题
现象:特定字符(如'8'与'B')易混淆
解决方案:
- 在训练数据中增加该类字符的样本量
- 添加注意力机制模块
- 使用Focal Loss替代交叉熵损失
4.2 运行时报错排查
- 找不到模型文件:
bash复制FileNotFoundError: [Errno 2] No such file...
检查:
- 模型路径是否包含中文
- 文件权限设置
- CUDA内存不足:
bash复制Could not create cudnn handle...
解决方法:
python复制physical_devices = tf.config.list_physical_devices('GPU')
tf.config.experimental.set_memory_growth(physical_devices[0], True)
4.3 实际部署建议
- 光照处理方案:
- 安装补光灯(推荐6500K色温)
- 代码中添加直方图均衡化:
python复制img = cv2.equalizeHist(img)
- 角度校正方法:
python复制def correct_angle(plate):
coords = np.float32([[0,0], [width,0], [width,height]])
M = cv2.getAffineTransform(pts1, pts2)
return cv2.warpAffine(plate, M, (width,height))
5. 扩展应用方向
- 多车牌识别:修改YOLO输出层支持多个检测框
- 车牌颜色识别:在CNN最后添加颜色分类分支
- 移动端部署:使用TensorFlow Lite转换模型
python复制converter = tf.lite.TFLiteConverter.from_keras_model(model)
tflite_model = converter.convert()
实测在树莓派4B上的性能表现:
| 模型类型 | 推理时间 | 内存占用 |
|---|---|---|
| 原始模型 | 1200ms | 1.2GB |
| 量化版模型 | 380ms | 280MB |
