# 用大白话说 ddddocr

> 这个仓库做什么、最简单的类比、以及你需要记住的几件事。

- Repository: sml2h3/ddddocr
- GitHub: https://github.com/sml2h3/ddddocr
- Human wiki: https://grok-wiki.com/public/wiki/sml2h3-ddddocr-a34dd45d9f63
- Complete Markdown: https://grok-wiki.com/public/wiki/sml2h3-ddddocr-a34dd45d9f63/llms-full.txt

## Source Files

- `README.md`
- `pyproject.toml`
- `ddddocr/__init__.py`
- `ddddocr/compat/v1.py`

---

<details>
<summary>相关源文件</summary>
以下文件用于生成此维基页面：
- [README.md](README.md)
- [pyproject.toml](pyproject.toml)
- [ddddocr/__init__.py](ddddocr/__init__.py)
- [ddddocr/compat/v1.py](ddddocr/compat/v1.py)
- [ddddocr/core/ocr_engine.py](ddddocr/core/ocr_engine.py)
- [ddddocr/core/detection_engine.py](ddddocr/core/detection_engine.py)
- [ddddocr/core/slide_engine.py](ddddocr/core/slide_engine.py)
- [ddddocr/core/base.py](ddddocr/core/base.py)
- [ddddocr/models/model_loader.py](ddddocr/models/model_loader.py)
- [ddddocr/models/charset_manager.py](ddddocr/models/charset_manager.py)
- [ddddocr/utils/validators.py](ddddocr/utils/validators.py)
- [ddddocr/__main__.py](ddddocr/__main__.py)
</details>

# 用大白话说 ddddocr

ddddocr 是一个**离线验证码识别 Python 库**。它的核心卖点是：把训练好的神经网络模型打包进库本身，用户只需 `pip install ddddocr`，不需要自己下载模型文件、配置深度学习框架，就能直接识别验证码图片里的文字。

本页用最直白的方式解释这个仓库做什么、怎么工作的、以及你需要记住的几件事。

---

## 一句话类比

把 ddddocr 想象成一台**自动售货机**：你把验证码图片塞进去（`bytes`），它把识别出的文字吐出来（`str`）。你不需要知道里面的齿轮怎么转——模型文件、推理引擎、字符集映射全都封装好了。

---

## 它能做什么

ddddocr 提供三种核心能力，通过一个统一的入口类 `DdddOcr` 暴露：

| 能力 | 用法 | 背后原理 |
|------|------|----------|
| **文字识别（OCR）** | `ocr.classification(image)` | 神经网络模型 + 字符集解码 |
| **目标检测** | `det.detection(image)` | 神经网络模型，返回边界框坐标 |
| **滑块验证码匹配** | `slide.slide_match(target, bg)` | 纯 OpenCV 模板匹配，**不需要模型** |

Sources: [ddddocr/compat/v1.py:72-93]()、[ddddocr/core/slide_engine.py:23-29]()

---

## 最简使用示例

```python
import ddddocr

ocr = ddddocr.DdddOcr()                    # 初始化一次，加载模型
with open("captcha.jpg", "rb") as f:
    image = f.read()

result = ocr.classification(image)          # 识别图片文字
print(result)                               # 输出类似 "a3K9"
```

关键点：**`DdddOcr()` 只需要创建一次**，之后可以反复调用 `classification()`。每次重新创建会重新加载模型，白白浪费时间。

Sources: [README.md:214-227]()、[ddddocr/compat/v1.py:26-42]()

---

## 内部架构：三层结构

ddddocr 的代码分为三层，每层职责清晰：

```
用户代码
  │
  ▼
┌─────────────────────────────────┐
│  DdddOcr（兼容门面层）           │  ← ddddocr/compat/v1.py
│  统一入口，根据参数选择引擎       │
└──────────┬──────────────────────┘
           │
     ┌─────┼─────────┐
     ▼     ▼         ▼
┌────────┐┌────────┐┌────────┐
│OCR 引擎││检测引擎││滑块引擎│  ← ddddocr/core/
│(ONNX) ││(ONNX) ││(OpenCV)│
└───┬────┘└───┬────┘└────────┘
    ▼         ▼
┌─────────────────┐
│  模型加载器      │  ← ddddocr/models/model_loader.py
│  字符集管理器    │  ← ddddocr/models/charset_manager.py
└─────────────────┘
```

**要点**：OCR 引擎和检测引擎依赖 ONNX 模型文件；滑块引擎**不使用任何模型**，纯粹靠 OpenCV 的图像处理算法工作。

Sources: [ddddocr/compat/v1.py:72-93]()、[ddddocr/core/slide_engine.py:23-29]()

---

## 模型文件说明

ddddocr 随库附带了三个 ONNX 模型文件，打包在 `ddddocr/` 目录下：

| 文件名 | 用途 | 触发方式 |
|--------|------|----------|
| `common_old.onnx` | 默认 OCR 模型 | 默认使用 |
| `common.onnx` | Beta OCR 模型 | `beta=True` |
| `common_det.onnx` | 目标检测模型 | `det=True` |

模型选择逻辑在 `ModelLoader.load_ocr_model()` 中实现：当 `beta=True` 时加载 `common.onnx`，否则加载 `common_old.onnx`。

Sources: [ddddocr/models/model_loader.py:119-145]()

---

## 三种工作模式

通过初始化参数组合，`DdddOcr` 会进入不同模式：

```python
# 模式1：文字识别（默认）
ocr = ddddocr.DdddOcr(ocr=True, det=False)

# 模式2：目标检测
det = ddddocr.DdddOcr(det=True, ocr=False)

# 模式3：滑块匹配（两个都关）
slide = ddddocr.DdddOcr(ocr=False, det=False)
```

模式选择的优先级规则（在 `compat/v1.py` 的 `__init__` 中实现）：

1. `det=True` → 目标检测模式（**最高优先级**，即使同时设 `ocr=True`）
2. `ocr=True` 或提供了 `import_onnx_path` → OCR 模式
3. 都不设 → 滑块模式（`SlideEngine` 始终会创建）

Sources: [ddddocr/compat/v1.py:72-93]()

---

## 推理流程：图片进去，文字出来

以 OCR 识别为例，一次 `classification()` 调用的完整流程：

1. **输入校验** — `validate_image_input()` 检查类型是否为 `bytes`、`str`、`PIL.Image` 等
2. **图片加载** — 统一转为 numpy 数组
3. **预处理** — 缩放到 64×64、转灰度（单通道）、可选的 PNG 透明修复或颜色过滤
4. **ONNX 推理** — `onnxruntime.InferenceSession.run()` 得到输出矩阵
5. **后处理** — 对输出矩阵取 argmax，通过 `CharsetManager.index_to_char()` 映射为文字

如果调用 `classification(image, probability=True)`，则跳过第 5 步，直接返回每个字符位置的概率分布字典。

Sources: [ddddocr/core/ocr_engine.py:39-54]()、[ddddocr/models/charset_manager.py:168]()

---

## 你需要记住的几件事

### 1. 只初始化一次

模型加载是最慢的步骤。创建 `DdddOcr()` 后，应该复用同一个实例处理所有图片。在循环中反复创建实例会严重拖慢速度。

### 2. 线程安全：每个线程一个实例

如果在多线程环境中使用，**每个线程应创建独立的 `DdddOcr` 实例**。共享实例可能导致识别结果错乱。

### 3. 滑块引擎不需要模型

`SlideEngine` 不加载任何 ONNX 文件，它直接用 OpenCV 做模板匹配。这意味着滑块匹配的初始化速度远快于 OCR/检测。

Sources: [ddddocr/core/slide_engine.py:23-29]()

### 4. 字符集可以缩小

通过 `set_ranges()` 方法可以限定识别范围，减少误识别：

```python
ocr.set_ranges(0)                    # 只识别数字 0-9
ocr.set_ranges("0123456789+-x/=")   # 自定义字符集
```

预设值 `0`-`7` 分别对应数字、小写英文、大写英文等组合。

Sources: [README.md:303-335]()

### 5. GPU 加速可选

默认用 CPU 推理。设置 `use_gpu=True` 会尝试加载 `CUDAExecutionProvider`，需要预装 CUDA 和 `onnxruntime-gpu`。如果 GPU 不可用，会自动回退到 CPU。

Sources: [ddddocr/models/model_loader.py:31-53]()

### 6. 还能跑 HTTP API

除了作为库使用，ddddocr 还内置了一个 FastAPI 服务：

```bash
python -m ddddocr api --host 0.0.0.0 --port 8000
```

这会启动一个 REST API，提供 `/ocr`、`/det`、`/slide_match` 等端点，适合需要网络调用的场景。API 依赖（`fastapi`、`uvicorn` 等）是可选的，需要额外安装：`pip install ddddocr[api]`。

Sources: [ddddocr/__main__.py:8-75]()、[pyproject.toml:34-39]()

---

## 依赖关系

ddddocr 的设计哲学是"最简依赖"。核心依赖只有：

- **onnxruntime** — ONNX 模型推理引擎
- **Pillow** — 图片读取
- **opencv-python** — 图像处理（滑块匹配、预处理）
- **numpy** — 数组运算

不需要 PyTorch、TensorFlow 等重量级框架。训练模型用的是 PyTorch（通过 [dddd_trainer](https://github.com/sml2h3/dddd_trainer)），但推理阶段只依赖 ONNX Runtime。

Sources: [pyproject.toml:22-28]()

---

## 总结

ddddocr 本质上是一个**预训练模型的便捷封装**：把用 PyTorch 训练好的验证码识别模型转成 ONNX 格式，打包进 Python 库，再用 `onnxruntime` 做推理。用户不需要了解深度学习的任何细节，三行代码就能识别验证码。它的三种引擎（OCR、检测、滑块）通过一个统一的 `DdddOcr` 类对外暴露，根据初始化参数自动切换工作模式。
