中国车牌检测识别系统。两阶段流水线:YOLO11n-pose 检测车牌(区分单层/双层)→ 透视矫正裁剪 → CNN+CTC 识别字符 + 颜色分类。
支持单图、文件夹批量、视频。模型权重已随包分发,装完依赖即可使用。
一张图看完:输入怎么进来、三个阶段各做了什么、图片和视频在哪里分道扬镳、结果怎么落盘。 每个方块都标了对应的源码位置。
| 检测 | 识别 | ||
|---|---|---|---|
| precision | 0.97972 | 整牌准确率 | 0.97071 |
| recall | 0.95812 | 字符准确率 | 0.99050 |
| mAP50 | 0.98813 | 颜色准确率 | 0.98908 |
| mAP50-95 | 0.85786 | ||
| 关键点 mAP50-95 | 0.98614 |
覆盖蓝/绿/黄/白/黑五色,单层与双层,以及警车牌、教练车牌、使领馆牌、港澳牌。
四角点用来做透视矫正,对倾斜车牌收益很大 —— 20° 以上倾斜的整牌准确率从 23.70% 提升到 76.61%。
需要 Python 3.9 或更高版本。
双击 install.bat 就装完了 —— 它依次升级 pip、装依赖、把本项目注册成命令。
想自己敲命令的话,在本项目目录下右键:在终端中打开,依次执行这三条:
python -m pip install --upgrade pip
python -m pip install -r requirements.txt
python -m pip install -e .第一条别跳过。 Python 3.9 自带的 pip 是 21.x,太老,会以两种方式失败: 一是按系统编码(中文 Windows 为 GBK)去解 UTF-8 的 requirements 文件,报
UnicodeDecodeError;二是不认 PEP 660,装不了只有
pyproject.toml的项目,报File "setup.py" or "setup.cfg" not found。升完 pip 两个问题都没了。第三条也别跳过,末尾那个点表示「当前目录」。它做两件事:注册
plate-infer/plate-gui两个命令; 别挪动或改名本文件夹,真要挪,挪完重跑一次python -m pip install -e .。
想确认装对了没有,跑一遍自带的回归测试:
python scripts/bench.py它会识别 assets/samples/ 下的 11 张样图,并与 docs/baseline_current.json 里的标准答案逐字段比对。
输出「✅ 完全一致」就说明环境没问题。
项目自带了一组测试样本,装完不用自己找图就能直接试 —— testimg 文件夹下有 7 张 1920×1080 的实拍车牌图(每张 2~3 块牌)和一段 45 秒的行车视频。
双击 start_gui.vbs 启动图形界面。
.vbs被安全策略拦截的话用start_gui.bat,效果一样,只是会闪一下控制台窗口。第一次启动需要加载模型,会慢一点,后面就很快了
界面起不来时在终端里跑
python scripts/gui.py,能看到完整报错。
界面里可以选单张图片、整个文件夹或视频,也可以直接把文件拖进去 —— 比如把 testimg/demo.mp4 拖进窗口,就能看到视频识别的效果。识别过程中:
- 左侧实时显示当前处理的画面,右侧结果表逐条出结果
- 点结果表里的任意一行,左侧就回显那一条对应的标注图;视频的行会跳到该车识别得最准的那一帧
- 随时可以点「停止」,已经跑完的部分照常保存
装完(含上面第三条 pip install -e .)后,在任意目录下都能用以下命令。打开存放图片的文件夹,然后右键在终端中打开,执行:
plate-infer --source . --output .就能识别当前目录下的所有图片和视频,结果就存在当前目录。
末尾那两个点别漏了 —— 它们表示「当前目录」, 前一个点表示从「当前目录」读图片,后一个点表示在「当前目录」写结果。
省掉 --output . 的话结果会存进项目的 results 文件夹。
常用参数:
| 参数 | 说明 |
|---|---|
--source |
图片、视频或目录;不给则跑 assets/samples |
--output |
输出根目录;不给则写进项目的 results/ |
--conf |
检测置信度阈值,默认 0.3。漏检多就调低,误检多就调高 |
--device |
auto / cpu / cuda,默认 auto(有显卡就用) |
--show |
每张图弹窗显示结果,按任意键看下一张 |
每跑一次生成一个以时间戳命名的目录:
results/20260805_143022/
├── 车牌图1.jpg 标注图(画了框和车牌号)
├── 某视频.mp4 标注视频
└── results.csv 全部结果汇总
results.csv 用 Excel 直接打开即可(已带 BOM,中文不乱码)。字段:
| 列 | 说明 |
|---|---|
file |
来源文件名 |
plate_no |
车牌号 |
plate_color |
车牌颜色 |
plate_type |
单层 / 双层 |
detect_conf |
检测置信度(0~1) |
color_conf |
颜色判定置信度(0~1) |
x1 y1 x2 y2 |
车牌在原图中的位置(左上、右下角坐标,单位像素) |
frames |
这辆车在视频里出现了多少帧(仅视频,图片留空) |
first_frame last_frame |
首次 / 末次出现的帧号(仅视频) |
视频不是「逐帧各算各的」,而是做了跨帧跟踪:用检测框的重叠度把相邻帧的同一块车牌关联成一条轨迹,一辆车只出一行结果、一个车牌号。
这样处理有三个直接好处:
- 视频里的标签不会每帧乱跳 —— 只有出现更可信的读数时才更新
- CSV 一辆车一行,而不是「每帧每块牌一行」(十几秒的视频就上千行)
- 只闪现一两帧的误检会被自动滤掉
被前车挡一下、或中间几帧没检出,跟踪会断开成两条轨迹;跑完后会按车牌号把它们合并回一辆车。
├── configs/ 配置:路径、推理超参
├── weights/release/ 模型权重(随包分发,开箱即用)
├── src/plate/ 主代码包
│ ├── common/ 字符表、预处理、双层拼接、中文路径 IO
│ ├── detect/ 检测:加载、推理
│ ├── recognize/ 识别:模型、推理
│ ├── pipeline/ 检测 → 识别 串联、跨帧跟踪、结果绘制
│ └── gui/ 图形界面(PySide6 + QSS)
├── scripts/ 可执行入口(gui / infer / bench)
├── assets/
│ ├── fonts/ NotoSansSC.ttf —— 绘制中文车牌号必需,不可删
│ └── samples/ 回归测试样图(覆盖蓝/绿/黄/双层/警/学/使领馆/港牌)
├── testimg/ 自带测试样本:7 张实拍图 + 一段行车视频
├── results/ 识别结果输出
└── docs/ 回归基线、README 配图
权重已经训练好并随包分发,直接用即可;模型的训练代码与数据集不在本仓库范围内。

