feat: ddddocr-rs 完成 core/ort/tract2 规范整改与发布
准备 - core:内置官方字符集(OLD/BETA)与 ModelMetadata::from_builtin_* 构造器 - ort:导出 Session、实现 Info、修正 cuda feature 接线、共享推理工具 - tract2:包名更名(原 ddddocr-tract 已被占用)并完成规范整改 - 集成测试按领域拆分(ocr / det / slide / common / api_surface) - 发布准备:Cargo.toml 元数据、workspace 版本 0.2.4、LICENSE/ NOTICE、README 模型下载说明
This commit is contained in:
144
README.md
144
README.md
@@ -1,45 +1,135 @@
|
||||
# ddddocr-rs
|
||||
|
||||
带带弟弟 OCR (ddddocr) 的 Rust 移植版。高性能、低占用,支持多种验证码识别与检测。
|
||||
[带带弟弟 OCR(ddddocr)](https://github.com/sml2h3/ddddocr) 的 Rust 移植版:提供验证码 OCR 识别、目标检测与滑块匹配能力。核心库与推理引擎解耦,同一套 API 可切换 [Tract](https://github.com/sonos/tract) 或 [ONNX Runtime](https://onnxruntime.ai/) 后端。
|
||||
|
||||
🧩 滑块识别算法核心知识点总结
|
||||
本项目实现了两种核心匹配模式,其底层逻辑与 OpenCV 的对齐情况如下:
|
||||
## 架构
|
||||
|
||||
1. 匹配模式对比 (Match Modes)
|
||||
|**模式**|**算法原理**|**适用场景**|**备注**|
|
||||
|---|---|---|---|
|
||||
|**边缘模式** (Edge-based)|基于 **Canny 边缘检测** 提取轮廓后再进行匹配。|**推荐方案**
|
||||
。适用于绝大多数拼图滑块。|天然免疫拼图周边的透明/黑色留白干扰,坐标最精准。|
|
||||
|**简单模式** (Simple/Gray)|直接基于 **灰度像素值** 进行归一化互相关计算。|适用于无明显边缘、靠颜色差异识别的场景。|对背景和透明边框敏感,可能存在重心偏移。|
|
||||
项目为 Cargo workspace,包含三个 crate:
|
||||
|
||||
2. 数学公式差异 (NCC vs. CCOEFF)
|
||||
在简单模式下,本项目采用的是 归一化互相关 (NCC),对应 OpenCV 中的 TM_CCORR_NORMED。
|
||||
| crate | 说明 |
|
||||
|---|---|
|
||||
| `ddddocr-core` | 引擎无关的核心库:OCR / 目标检测 / 滑块匹配、模型元数据与图像预处理 |
|
||||
| `ddddocr-ort` | ONNX Runtime 推理后端(可选 `cuda` feature 启用 GPU 加速) |
|
||||
| `ddddocr-tract2` | Tract(纯 Rust)推理后端 |
|
||||
|
||||
逻辑对齐:Rust 的 match_template 结果与 Python cv2.TM_CCORR_NORMED 完全一致。
|
||||
`ddddocr-core` 通过 `traits::InferenceEngine` / `OcrEngine` / `DetEngine` 抽象推理能力,由 `ddddocr-ort` / `ddddocr-tract2` 实现,业务代码只依赖核心库接口即可。
|
||||
|
||||
关于偏移:若拼图原始图片(Target)四周包含大量的透明留白:
|
||||
## 快速开始
|
||||
|
||||
CCORR (本项目):会将留白视为图像的一部分,计算出的是整张图片框的中心。
|
||||
在 Cargo.toml 中添加:
|
||||
|
||||
CCOEFF (OpenCV 默认):会自动进行“均值中心化”,在一定程度上能削弱留白的影响。
|
||||
```toml
|
||||
[dependencies]
|
||||
ddddocr-core = "0.2"
|
||||
ddddocr-ort = "0.2" # 或 ddddocr-tract2 = "0.2"
|
||||
```
|
||||
|
||||
最佳实践:若发现坐标有固定位移,建议优先切换至 边缘模式,或对滑块图进行 Bounding Box 裁剪 后再匹配。
|
||||
核心库自带一个不依赖真实模型的演示示例(用假引擎演示完整调用链):
|
||||
|
||||
3. 图像预处理一致性
|
||||
```bash
|
||||
cargo run -p ddddocr-core --example quick_start
|
||||
```
|
||||
|
||||
为确保识别精度,本项目在 Rust 中完美复刻了 Python OpenCV 的预处理链路:
|
||||
真实推理需要自行准备 ONNX 模型文件(crate 包内不包含模型)。以 ORT 后端为例:
|
||||
|
||||
- **灰度化权重**:采用 OpenCV 标准感光公式 $0.299R + 0.587G + 0.114B$。
|
||||
```rust
|
||||
use ddddocr_core::traits::{Info, Loader};
|
||||
use ddddocr_core::{ModelMetadata, Normalization, Ocr, Resize};
|
||||
|
||||
- **Alpha 处理**:在将 PNG 转为 RGB 时,自动将透明区域填充为黑色,确保与 PIL (Python Imaging Library) 行为一致。
|
||||
// 1. 构建会话(等价写法:ddddocr_tract2::loader::ModelLoader)
|
||||
let session = ddddocr_ort::loader::ModelLoader::default()
|
||||
.build_for_path("models/common.onnx")?;
|
||||
|
||||
- **坐标定义**:所有返回坐标均为匹配区域的 **几何中心点** $(x + w/2, y + h/2)$。
|
||||
// 2. 组装 OCR 运行时
|
||||
let metadata = ModelMetadata::from_static_slice(
|
||||
&["a", "b"], // 字符集
|
||||
false, // 非单字模型
|
||||
Resize::DynamicWidth(64), // 高度固定 64、宽度等比缩放
|
||||
1, // 灰度单通道
|
||||
Normalization::MinusOneToOne,
|
||||
);
|
||||
let ocr = ddddocr_ort::OcrRuntime::new(session, metadata);
|
||||
|
||||
💡 开发者建议:
|
||||
// 3. 识别图片
|
||||
let result = Ocr::builder().build_with(&ocr).predict(&image)?;
|
||||
println!("识别结果: {}", result);
|
||||
```
|
||||
|
||||
如果识别结果在 $X$ 轴上有大约 $10px$ 左右的固定误差,通常是因为滑块原图自带了透明边距(留白)。此时请确保
|
||||
simple_target=false。该模式会通过 Canny 边缘检测 提取轮廓特征,能自动锁定拼图实体并忽略背景留白的像素干扰。
|
||||
鸣谢 (Credits)
|
||||
目标检测与滑块匹配类似:`Detector::new(&engine).predict(&image)` 返回检测框列表;`Slider::new().slide_match(target, background, simple_target)` 返回匹配坐标与置信度。
|
||||
|
||||
- 本项目是 [ddddocr](https://github.com/sml2h3/ddddocr) 的 Rust 移植版本,原作者为 sml2h3。衷心感谢原作者对 OCR 社区做出的杰出贡献。
|
||||
- 推理引擎基于 [tract (Sonos)](https://github.com/sonos/tract)。感谢其为 Rust 生态提供的轻量级推理方案。
|
||||
## 模型下载
|
||||
|
||||
OCR / 目标检测需要 ONNX 模型文件。官方模型位于 [ddddocr 仓库 `ddddocr/` 目录](https://github.com/sml2h3/ddddocr/blob/master/ddddocr/),下载后放入仓库根目录的 `models/` 文件夹:
|
||||
|
||||
| 文件 | 大小 | 用途 | 直链 |
|
||||
|---|---|---|---|
|
||||
| `common.onnx` | 约 51.6 MB | 新版 OCR 模型(默认) | [下载](https://raw.githubusercontent.com/sml2h3/ddddocr/master/ddddocr/common.onnx) |
|
||||
| `common_det.onnx` | 约 19.2 MB | 目标检测模型 | [下载](https://raw.githubusercontent.com/sml2h3/ddddocr/master/ddddocr/common_det.onnx) |
|
||||
| `common_old.onnx` | 约 13 MB | 旧版 OCR 模型 | [下载](https://raw.githubusercontent.com/sml2h3/ddddocr/master/ddddocr/common_old.onnx) |
|
||||
|
||||
> 注意:`ddddocr-tract2` 不支持旧版模型 `common_old.onnx`,请使用 `common.onnx`。
|
||||
>
|
||||
> 字符集配对:`common.onnx` 对应内置 Beta 字符集(`Charset` / `ModelMetadata::from_builtin_beta`,归一化 `MinusOneToOne`);`common_old.onnx` 对应旧版字符集(`from_builtin_old`,归一化 `ZeroToOne`)。
|
||||
>
|
||||
> 仓库测试使用的 `common_sml2h3_f32.onnx`、`common_huashi666_i64.onnx` 为社区转换的 f32 / i64 变体模型(与 `common.onnx` 同源),不在上述官方目录中,需自行获取。
|
||||
|
||||
## 字符集与内置默认值
|
||||
|
||||
OCR 模型的字符集(token 列表)是模型的一部分:字符 `i` 对应模型输出 logits 的第 `i` 列,必须与模型训练时一致,否则识别结果会错位。
|
||||
|
||||
字符集有两种提供方式:
|
||||
|
||||
- 通过模型元数据 JSON 的 `charset` 字段(`Metadata::from_json_str` / `from_json_bytes` 自动解析);
|
||||
- 代码内显式指定:`ModelMetadata::from_static_slice(&["", "a", "b"], ...)` 或 `Charset::new(...)`。
|
||||
|
||||
`ddddocr-core` 内置官方模型的默认字符集(旧版 `CHARSET_OLD` 与 Beta `CHARSET_BETA`),作为免配置的快速通道。字符集数据独立存放在 `ddddocr-core/src/ocr/builtin.rs` 私有模块中(与业务逻辑分离),通过 `ModelMetadata` 的公开构造方法使用:
|
||||
|
||||
```rust
|
||||
use ddddocr_core::{ModelMetadata, Normalization, Resize};
|
||||
|
||||
// 官方旧版模型配套
|
||||
let meta = ModelMetadata::from_builtin_old(
|
||||
false,
|
||||
Resize::DynamicWidth(64),
|
||||
1,
|
||||
Normalization::ZeroToOne,
|
||||
);
|
||||
|
||||
// 官方 Beta 模型配套
|
||||
let meta = ModelMetadata::from_builtin_beta(
|
||||
false,
|
||||
Resize::DynamicWidth(64),
|
||||
1,
|
||||
Normalization::MinusOneToOne,
|
||||
);
|
||||
```
|
||||
|
||||
数据内置于代码,不依赖外部文件。若使用自有模型,请仍以元数据 JSON 或 `from_static_slice` 指定匹配的字符集。
|
||||
|
||||
## 滑块匹配核心知识点
|
||||
|
||||
项目实现两种匹配模式,底层逻辑与 OpenCV 对齐:
|
||||
|
||||
| 模式 | 算法原理 | 适用场景 | 备注 |
|
||||
|---|---|---|---|
|
||||
| 边缘模式(Edge-based) | 基于 Canny 边缘检测提取轮廓后匹配 | **推荐方案**,适用于绝大多数拼图滑块 | 天然免疫拼图周边透明/黑色留白干扰,坐标最精准 |
|
||||
| 简单模式(Simple/Gray) | 基于灰度像素值做归一化互相关(NCC) | 无明显边缘、靠颜色差异识别的场景 | 对背景和透明边框敏感,可能存在重心偏移 |
|
||||
|
||||
关键点:
|
||||
|
||||
- 简单模式采用归一化互相关(NCC),与 OpenCV 的 `TM_CCORR_NORMED` 完全一致。
|
||||
- 若拼图原图四周带透明留白,本项目会将留白计入整张图片框中心;OpenCV 默认的 CCOEFF 会做均值中心化削弱留白影响。
|
||||
- 图像预处理与 Python 链路保持一致:灰度权重采用 OpenCV 标准感光公式 `0.299R + 0.587G + 0.114B`;PNG 转 RGB 时透明区域填充为黑色;返回坐标为匹配区域的几何中心 `(x + w/2, y + h/2)`。
|
||||
|
||||
> 若识别结果在 X 轴上有约 10px 固定误差,通常是滑块原图自带透明边距所致。此时请确保 `simple_target = false`,边缘模式会自动锁定拼图实体并忽略留白干扰。
|
||||
|
||||
## 致谢
|
||||
|
||||
- [sml2h3 (ddddocr)](https://github.com/sml2h3/ddddocr) - 模型权重与原始逻辑。
|
||||
- [Sonos (tract)](https://github.com/sonos/tract) - 纯 Rust ONNX 推理引擎。
|
||||
- [pyke.io (ort)](https://github.com/pykeio/ort) - ONNX Runtime 的 Rust 绑定。
|
||||
- [Microsoft (ONNX Runtime)](https://onnxruntime.ai/) - ONNX 推理引擎。
|
||||
|
||||
## License
|
||||
|
||||
`MIT OR Apache-2.0`,许可证文本见仓库根目录的 `LICENSE-MIT` 与 `LICENSE-APACHE`。
|
||||
|
||||
Reference in New Issue
Block a user