# XcOCR **Repository Path**: Vanishi/XcOCR ## Basic Information - **Project Name**: XcOCR - **Description**: 支持 OpenVINO / TensorRT / RKNN / CANN 多平台部署的车牌识别训练框架 - **Primary Language**: Python - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2025-12-18 - **Last Updated**: 2026-02-14 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # XcOCR - OCR车牌识别训练框架 * 作者:北小菜 * 官网:https://www.yuturuishi.com * 邮箱:bilibili_bxc@126.com * QQ:1402990689 * 微信:bilibili_bxc * 哔哩哔哩主页:https://space.bilibili.com/487906612 * gitee开源地址:https://gitee.com/Vanishi/XcOCR * github开源地址:https://github.com/beixiaocai/XcOCR 支持 OpenVINO / TensorRT / RKNN / CANN 多平台部署的车牌识别训练框架 ## 特点 - ✅ **端到端**:YOLO11n 检测 + XcPlateNet (RepVGG) 识别 - ✅ **多平台**:支持 Intel / NVIDIA / RK3588 / 昇腾 - ✅ **高性能**:CTC解码优化 + 融合预处理 - ✅ **高准确率**:训练多分支 + 推理单路,准确率91%+ - ✅ **轻量级**:15-19MB,纯CNN算子,无RNN依赖 ## 技术架构 **流程**:输入 → YOLO11n检测 → 裁剪 → XcPlateNet识别 (RepVGG + 时间卷积 + CTC) → 车牌文本 **XcPlateNet 核心**: - RepVGG主干:训练时 3分支(3x3+1x1+identity),推理时融合为单路3x3 - 增强时间卷积:4层512通道 + 空洞卷积 - 纯 CNN 算子,全平台兼容 ## 快速开始 ### 1. 安装依赖 ```bash # 安装 PyTorch (CUDA 12.1) pip install torch==2.1.0 torchvision==0.16.0 torchaudio==2.1.0 --index-url https://download.pytorch.org/whl/cu121 # 安装其他依赖 pip install -r requirements.txt ``` ### 2. 数据准备 下载 CCPD 数据集到 `datasets/` 目录,然后转换数据格式: ```bash # 转换检测数据 (YOLO) python tools/ccpd2019_converter.py --task detection --ccpd-dir datasets/CCPD2019 --output-dir datasets/yoloCCPD2019 # 转换识别数据 (OCR) python tools/ccpd2019_converter.py --task recognition --ccpd-dir datasets/CCPD2019 --output-dir datasets/ocrCCPD2019 # 也支持 CCPD2020 数据集 python tools/ccpd2020_converter.py --task recognition --ccpd-dir datasets/CCPD2020 --output-dir datasets/ocrCCPD2020 # 合并多个数据集 python tools/merge_datasets.py --input-dirs datasets/ocrCCPD2019 datasets/ocrCCPD2020 --output-dir datasets/ocrCCPD_merged ``` ### 3. 训练模型 ```bash # 训练检测模型 (YOLO11n) - 使用 ultralytics yolo detect train data=datasets/yoloCCPD2019/data.yaml model=yolo11n.pt epochs=100 imgsz=640 batch=16 # 训练识别模型 (XcPlateNet) python OCR/train.py --train-dir datasets/ocrCCPD2019/train --val-dir datasets/ocrCCPD2019/val --num-epochs 300 --batch-size 128 --save-dir checkpoints ``` **训练参数说明**: - `--train-dir`:训练数据目录 - `--val-dir`:验证数据目录 - `--num-epochs`:训练轮数(默认:300) - `--batch-size`:批次大小(默认:128) - `--save-dir`:模型保存目录(默认:`checkpoints`) - `--learning-rate`:学习率(默认:0.001) - `--img-height`:图像高度(默认:32) - `--img-width`:图像宽度(默认:128) - `--hidden-size`:隐藏层大小(默认:128) ### 4. 模型评估 ```bash # 评估识别模型 python OCR/evaluate.py --model-path checkpoints/ocr_best_model.pth --data-dir datasets/ocrCCPD2019/val --batch-size 64 ``` ## 模型导出与部署 ### 1. 导出 ONNX 模型 ```bash # 基础导出(固定batch,推荐) python tools/export_onnx.py --checkpoint checkpoints/ocr_best_model.pth --output checkpoints/xcplatenet.onnx # 动态batch导出(可选,性能略低) python tools/export_onnx.py --checkpoint checkpoints/ocr_best_model.pth --output checkpoints/xcplatenet.onnx --dynamic-batch ``` **参数说明**: - `--checkpoint`:PyTorch权重文件路径 - `--output`:输出ONNX文件路径(默认:`checkpoints/xcplatenet.onnx`) - `--hidden-size`:模型隐藏层大小(默认:128) - `--dynamic-batch`:启用动态batch(TensorRT不推荐) - `--test-inference`:测试ONNX推理并对比PyTorch(默认开启) ### 2. 转换推理引擎 #### OpenVINO (Intel CPU/GPU/VPU) ```bash # 转换为 OpenVINO IR 格式 mo --input_model checkpoints/xcplatenet.onnx --output_dir checkpoints/openvino --data_type FP16 # Python 推理示例 python -c " from openvino.runtime import Core core = Core() model = core.read_model('checkpoints/openvino/xcplatenet.xml') compiled = core.compile_model(model, 'CPU') print('OpenVINO 模型加载成功!') " ``` #### TensorRT (NVIDIA GPU) ```bash # 转换为 TensorRT 引擎 trtexec --onnx=checkpoints/xcplatenet.onnx --saveEngine=checkpoints/xcplatenet.fp16.engine --fp16 --verbose # 静态 shape 模型不需要 --minShapes/--optShapes/--maxShapes # FP16 精度在精度损失极小的情况下性能提升 2-3 倍 ``` **重要提示**: - TensorRT 引擎文件与生成版本**必须完全一致**,跨版本无法使用 - 转换后的引擎大小约 10MB(FP16) - 推荐使用与运行环境相同版本的 trtexec #### RKNN (RK3588 NPU) 使用专门的 ONNX 转 RKNN 工具: ```bash # 转换为 RKNN 模型(默认开启 INT8 量化) python tools/onnx2rknn_XcOCR.py --input checkpoints/xcplatenet.onnx --platform rk3588 # 不量化(FP16) python tools/onnx2rknn_XcOCR.py --input checkpoints/xcplatenet.onnx --platform rk3588 --no-quant # 指定输出目录 python tools/onnx2rknn_XcOCR.py --input checkpoints/xcplatenet.onnx --platform rk3588 --output checkpoints/rknn ``` **参数说明**: - `--input`:输入ONNX模型路径(必需) - `--output`:输出目录(可选,默认与输入模型同目录) - `--platform`:目标平台(默认:rk3588,可选:rk3566, rk3568等) - `--no-quant`:禁用量化,使用FP16(默认开启INT8量化) - `--dataset`:量化校准数据集文件(可选) - `--num-samples`:校准样本数量(默认:10) **输出文件命名规则**: - 文件名包含分辨率、量化状态和平台信息 - 示例:`xcplatenet-rk3588-32x128-i8.rknn`(INT8量化) - 示例:`xcplatenet-rk3588-32x128-fp16.rknn`(FP16浮点) #### CANN (昇腾 NPU) ```bash # 转换为昇腾模型 atc --model=checkpoints/xcplatenet.onnx \ --framework=5 \ --output=checkpoints/xcplatenet \ --input_shape="input:1,3,32,128" \ --soc_version=Ascend310 # 查看模型信息 atc --mode=1 --om=checkpoints/xcplatenet.om ``` ### 3. 性能参考 | 平台 | 硬件 | 精度 | 延迟 | FPS | 备注 | |------|------|------|------|-----|------| | OpenVINO | i7-12700 iGPU | FP16 | 5ms | 180+ | 优化后 | | TensorRT | RTX 3080Ti | FP16 | 2ms | 400+ | 优化后 | | RKNN | RK3588 NPU | INT8 | 12ms | 80 | 量化后 | | CANN | Atlas 300I | FP16 | 8ms | 120 | - | **模型信息**: - YOLO11n: 5.5MB, mAP@0.5: 98%+ - XcPlateNet: 15-19MB, 准确率 91%+ ## 常见问题 **Q: 训练准确率为 0** A: 检查序列长度匹配 (`input_lengths=32`),确保 CTC Loss 输入正确 **Q: 推理结果错误** A: 旧权重(CNN)与新结构(RepVGG)不兼容,必须重新训练 **Q: ONNX 转换失败** A: 尝试使用 `onnx-simplifier` 简化模型: ```bash pip install onnx-simplifier python -m onnxsim checkpoints/xcplatenet.onnx checkpoints/xcplatenet_sim.onnx ``` **Q: TensorRT 引擎加载失败 (magic number 不匹配)** A: 引擎文件与 TensorRT 版本不一致,使用相同版本 trtexec 重新转换: ```bash # 查看 TensorRT 版本 trtexec --version # 确保 trtexec 与运行环境版本一致 ``` **Q: RKNN 转换失败** A: XcOCR 使用纯 CNN 架构,理论上完美兼容 RKNN。检查: 1. ONNX 模型是否正确导出 2. RKNN Toolkit 版本是否支持目标平台 3. 查看详细错误日志 **Q: 如何提高准确率** A: 1. 增加训练数据(推荐 50k+ 样本) 2. 数据增强(旋转、噪声、亮度调整) 3. 延长训练(300-600 epochs) 4. 混合多个数据集(CCPD2019 + CCPD2020) ## 项目结构 ``` XcOCR/ ├── OCR/ # 训练和评估代码 │ ├── model/ │ │ └── model.py # XcPlateNet 模型定义 │ ├── train.py # 训练脚本 │ ├── evaluate.py # 评估脚本 │ └── utils.py # 工具函数 ├── tools/ # 数据处理和模型转换工具 │ ├── ccpd2019_converter.py # CCPD2019 数据转换 │ ├── ccpd2020_converter.py # CCPD2020 数据转换 │ ├── merge_datasets.py # 数据集合并 │ ├── export_onnx.py # ONNX 导出 │ └── onnx2rknn_XcOCR.py # ONNX 转 RKNN ├── datasets/ # 数据集目录(需自行下载) │ ├── CCPD2019/ # 原始 CCPD2019 数据 │ ├── CCPD2020/ # 原始 CCPD2020 数据 │ ├── ocrCCPD2019/ # 转换后的 OCR 数据 │ └── yoloCCPD2019/ # 转换后的 YOLO 数据 ├── checkpoints/ # 模型权重(训练后生成) │ ├── ocr_best_model.pth # PyTorch 权重 │ ├── xcplatenet.onnx # ONNX 模型 │ └── ... # 其他转换格式 ├── requirements.txt # Python 依赖 └── README.md # 项目文档 ``` **说明**: - `checkpoints/` 目录及模型文件需要通过训练和转换生成 - `datasets/` 需要自行下载 CCPD 数据集并运行转换脚本 ## 技术细节 ### RepVGG 融合机制 训练时使用多分支结构提升表征能力,推理时融合为单路 3x3 卷积: ```python # 训练阶段 output = conv3x3(x) + conv1x1(x) + identity(x) # 推理阶段(融合后) output = fused_conv3x3(x) # 等价于上式,但速度更快 ``` ### CTC 解码优化 ```python # 优化前:创建中间 logits 数组 logits = [[output[t, c] for c in range(C)] for t in range(T)] result = decode(logits) # 额外内存开销 # 优化后:直接在原始数据上操作 for t in range(T): max_idx = argmax(output[t, :]) # 直接查找 if max_idx != blank and max_idx != prev: result.append(charset[max_idx]) ``` ### 预处理融合 ```python # 优化前:多次中间转换 img = cv2.cvtColor(img, BGR2RGB) # 1. 颜色转换 img = img.astype(float32) / 255.0 # 2. 归一化 img = (img - mean) / std # 3. 标准化 img = img.transpose(2, 0, 1) # 4. HWC→CHW # 优化后:一次循环完成 for c in range(3): for i in range(H * W): output[c, i] = (input[i, 2-c] / 255.0 - mean[c]) / std[c] ``` --- **基于**:[CCPD](https://github.com/detectRecog/CCPD) 数据集 | [Ultralytics](https://github.com/ultralytics/ultralytics) YOLO11 | RepVGG 架构 **License**: MIT