This commit is contained in:
Yaojia Wang
2026-02-11 23:40:38 +01:00
parent f1a7bfe6b7
commit ad5ed46b4c
117 changed files with 5741 additions and 7669 deletions

View File

@@ -1,14 +1,14 @@
# Invoice Master POC v2
自动发票字段提取系统 - 使用 YOLOv11 + PaddleOCR 从瑞典 PDF 发票中提取结构化数据。
自动发票字段提取系统 - 使用 YOLO26 + PaddleOCR 从瑞典 PDF 发票中提取结构化数据。
## 项目概述
本项目实现了一个完整的发票字段自动提取流程:
1. **自动标注**: 利用已有 CSV 结构化数据 + OCR 自动生成 YOLO 训练标注
2. **模型训练**: 使用 YOLOv11 训练字段检测模型,支持数据增强
3. **推理提取**: 检测字段区域 -> OCR 提取文本 -> 字段规范化
1. **自动标注**: 利用已有 CSV 结构化数据 + OCR 自动生成 YOLO 训练标注(统一 15px 填充)
2. **模型训练**: 使用 YOLO26 训练字段检测模型,支持数据增强
3. **推理提取**: 检测字段区域 -> OCR 提取文本 -> ValueSelector 过滤标签 -> 字段规范化
4. **Web 管理**: React 前端 + FastAPI 后端,支持文档管理、数据集构建、模型训练和版本管理
### 架构
@@ -37,8 +37,8 @@ frontend/ # React 前端 (Vite + TypeScript + TailwindCSS)
|------|------|
| **已标注文档** | 9,738 (9,709 成功) |
| **总体字段匹配率** | 94.8% (82,604/87,121) |
| **测试** | 2,058 passed |
| **测试覆盖率** | 60% |
| **测试** | 2,047 passed |
| **测试覆盖率** | 72% |
| **模型 mAP@0.5** | 93.5% |
**各字段匹配率:**
@@ -204,7 +204,7 @@ invoice-master-poc-v2/
│ ├── run_server.py # Web 服务器入口
│ └── backend/
│ ├── cli/ # infer, serve
│ ├── pipeline/ # YOLO 检测, 字段提取, 解析器
│ ├── pipeline/ # YOLO 检测, 字段提取, ValueSelector, 解析器
│ ├── web/ # FastAPI 应用
│ │ ├── api/v1/ # REST API (admin, public, batch)
│ │ ├── schemas/ # Pydantic 数据模型
@@ -278,7 +278,7 @@ python -m training.cli.autolabel --workers 4
```bash
# 从预训练模型开始训练
python -m training.cli.train \
--model yolo11n.pt \
--model yolo26s.pt \
--epochs 100 \
--batch 16 \
--name invoice_fields \
@@ -286,7 +286,7 @@ python -m training.cli.train \
# 低内存模式
python -m training.cli.train \
--model yolo11n.pt \
--model yolo26s.pt \
--epochs 100 \
--name invoice_fields \
--low-memory
@@ -443,6 +443,30 @@ result = parser.parse("Said, Shakar Umj 436-R Billo")
print(f"Customer Number: {result}") # "UMJ 436-R"
```
## 推理流水线 (Two-Stage Detection)
```
YOLO bbox -> crop -> PaddleOCR -> [all tokens] -> ValueSelector -> normalizer
| |
individual selected
text lines value token(s)
```
**BBox 扩展**: 所有字段统一使用 15px 填充150 DPI 下约 2.5mm),不做方向性扩展,不依赖布局假设。
**ValueSelector**: 在 OCR 和 normalizer 之间按字段类型过滤标签文本,只保留值 token
| 字段 | 选择策略 | 示例输入 -> 输出 |
|------|---------|-----------------|
| InvoiceDate / DueDate | 日期模式匹配 | "Fakturadatum 2024-01-15" -> "2024-01-15" |
| Amount | 金额模式匹配 | "Belopp 1 234,56 kr" -> "1 234,56" |
| Bankgiro / Plusgiro | Giro 号码模式 | "BG: 123-4567" -> "123-4567" |
| OCR | 最长数字序列 (>=5位) | "OCR 94228110015950070" -> "94228110015950070" |
| InvoiceNumber | 排除瑞典语标签 | "Fakturanr INV-2024-001" -> "INV-2024-001" |
| payment_line | 保留全部 | 不过滤 |
如果没有匹配到任何模式,回退返回全部 token永远不会比之前更差
## DPI 配置
系统所有组件统一使用 **150 DPI**。DPI 必须在训练和推理时保持一致。
@@ -506,9 +530,9 @@ DB_PASSWORD=xxx pytest tests/ --cov=packages --cov-report=term-missing
| 指标 | 数值 |
|------|------|
| **测试总数** | 2,058 |
| **测试总数** | 2,047 |
| **通过率** | 100% |
| **覆盖率** | 60% |
| **覆盖率** | 72% |
## 存储抽象层
@@ -619,7 +643,7 @@ npm run dev
| 组件 | 技术 |
|------|------|
| **目标检测** | YOLOv11 (Ultralytics) |
| **目标检测** | YOLO26 (Ultralytics >= 8.4.0) |
| **OCR 引擎** | PaddleOCR v5 (PP-OCRv5) |
| **PDF 处理** | PyMuPDF (fitz) |
| **数据库** | PostgreSQL + SQLModel |