Files
ddddocr-rs/README.md
CNWei 00e8ab5308 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 模型下载说明
2026-08-10 19:56:29 +08:00

136 lines
6.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# ddddocr-rs
[带带弟弟 OCRddddocr](https://github.com/sml2h3/ddddocr) 的 Rust 移植版:提供验证码 OCR 识别、目标检测与滑块匹配能力。核心库与推理引擎解耦,同一套 API 可切换 [Tract](https://github.com/sonos/tract) 或 [ONNX Runtime](https://onnxruntime.ai/) 后端。
## 架构
项目为 Cargo workspace包含三个 crate
| crate | 说明 |
|---|---|
| `ddddocr-core` | 引擎无关的核心库OCR / 目标检测 / 滑块匹配、模型元数据与图像预处理 |
| `ddddocr-ort` | ONNX Runtime 推理后端(可选 `cuda` feature 启用 GPU 加速) |
| `ddddocr-tract2` | Tract纯 Rust推理后端 |
`ddddocr-core` 通过 `traits::InferenceEngine` / `OcrEngine` / `DetEngine` 抽象推理能力,由 `ddddocr-ort` / `ddddocr-tract2` 实现,业务代码只依赖核心库接口即可。
## 快速开始
在 Cargo.toml 中添加:
```toml
[dependencies]
ddddocr-core = "0.2"
ddddocr-ort = "0.2" # 或 ddddocr-tract2 = "0.2"
```
核心库自带一个不依赖真实模型的演示示例(用假引擎演示完整调用链):
```bash
cargo run -p ddddocr-core --example quick_start
```
真实推理需要自行准备 ONNX 模型文件crate 包内不包含模型)。以 ORT 后端为例:
```rust
use ddddocr_core::traits::{Info, Loader};
use ddddocr_core::{ModelMetadata, Normalization, Ocr, Resize};
// 1. 构建会话等价写法ddddocr_tract2::loader::ModelLoader
let session = ddddocr_ort::loader::ModelLoader::default()
.build_for_path("models/common.onnx")?;
// 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);
```
目标检测与滑块匹配类似:`Detector::new(&engine).predict(&image)` 返回检测框列表;`Slider::new().slide_match(target, background, simple_target)` 返回匹配坐标与置信度。
## 模型下载
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`