RapidOCR 发票票据识别技能
概述
使用 RapidOCR (rapidocr-onnxruntime) 引擎对发票/票据图片进行 OCR 识别,提取关键字段:价税合计金额、发票号码、开票日期、销售方/购买方名称等。支持电子发票(数电票 PNG)和纸质增值税专用/普通发票扫描件(JPEG/PNG),纯 CPU 运行,无需 GPU。
核心能力
- 批量 OCR 识别:支持单张或目录批量处理发票图片
- 智能金额提取:自动定位"价税合计(小写)"行,提取金额并交叉验证
- 文档图片提取:从 docx 文档中提取嵌入的发票图片,按段落上下文建立客户-发票对应关系
- 重复引用检测:检测同一图片在文档中被多次引用的情况,按实际引用次数累计金额
- 交叉验证机制:通过"金额 + 税额 = 价税合计"和大写金额双重校验,自动发现 OCR 丢字问题
- Excel 报表生成:一键生成包含汇总表和明细表的标准 Excel 报表
技术特性
| 特性 | 说明 |
|---|---|
| OCR 引擎 | RapidOCR (ONNX Runtime),中文识别准确率高 |
| 运行环境 | 纯 CPU,无需 GPU,普通 2 核服务器即可运行 |
| 模型体积 | 约 15MB,首次加载后毫秒级响应 |
| 支持发票类型 | 电子发票(数电票)、增值税专用发票、增值税普通发票 |
| 提取字段 | 价税合计金额、发票号码、开票日期、销售方/购买方、税额等 |
| 输出格式 | JSON 结构化数据、Excel 汇总报表 |
适用场景
- 企业财务:从合同文档中批量提取发票金额,按客户/供应商汇总统计
- 记账软件:发票图片自动识别并录入金额、发票号等字段,替代手工录入
- 报销审核:批量扫描报销发票,自动提取金额并校验合理性
- 税务合规:发票信息数字化归档,便于查询和审计
- 数据分析:将纸质票据转化为结构化数据,支持后续财务分析
环境安装
前置条件
- Python 3.10+
- 操作系统:Windows / Linux / macOS
创建独立 OCR 虚拟环境
建议在独立 venv 中安装,避免依赖冲突:
# 创建 venv
python -m venv ocr_env
# 激活(Windows)
ocr_env\Scripts\activate
# 激活(Linux/macOS)
source ocr_env/bin/activate
# 安装依赖
pip install rapidocr-onnxruntime Pillow openpyxl
验证安装:
python -c "from rapidocr_onnxruntime import RapidOCR; engine = RapidOCR(); print('OCR engine ready')"
使用流程
第一步:从 docx 文档提取发票图片(可选)
当发票图片嵌入在 Word 文档中时,使用 scripts/extract_docx_images.py 提取图片并建立上下文对应关系:
python scripts/extract_docx_images.py <docx文件路径> [--output <输出目录>]
该脚本会:
1. 解压 docx(本质为 ZIP),提取 word/media/ 下所有图片
2. 解析 word/document.xml 和 word/_rels/document.xml.rels
3. 按文档段落顺序建立图片与上下文文字(如客户名称)的对应关系
4. 自动区分 JPEG(通常为合同/证明材料)和 PNG(通常为电子发票)
5. 检测同一图片在文档中被多次引用的情况(同一 rId 出现多次 blip 引用),不去重
第二步:OCR 识别并提取金额
使用 scripts/ocr_invoices.py 进行批量 OCR 识别和金额提取:
python scripts/ocr_invoices.py <图片目录或文件> [--output <结果JSON路径>] [--scale 1.5] [--contrast 1.5]
参数说明:
- --scale:图片放大倍数(默认 1.5,提高小字识别率)
- --contrast:对比度增强系数(默认 1.5)
- --output:结果输出 JSON 文件路径
输出 JSON 格式:
[
{
"image": "image5.png",
"amount": 131741.27,
"invoice_number": "25442000000012345678",
"date": "2024-03-15",
"raw_text": "..."
}
]
第三步:金额交叉验证(可选)
使用 scripts/verify_amounts.py 验证 OCR 结果准确性:
python scripts/verify_amounts.py <OCR结果JSON路径> [--output <验证报告路径>]
验证逻辑:
- 金额(不含税)+ 税额 = 价税合计 → 等式成立则通过
- 大写金额反推数字金额 → 与 OCR 识别金额比对
- 标记验证失败的记录,提示人工复核
金额提取规则
中国发票的"价税合计(小写)"金额提取遵循以下优先级规则:
- 首选规则:查找包含"价税合计"且包含"小写"的行,在其后 3 行范围内匹配
(小写)¥XXX,XXX.XX格式 - 备选规则 1:匹配
¥后跟数字(含千分位逗号)的金额 - 备选规则 2:取文本中所有 ¥ 金额的最大值(适用于发票总额最大的场景)
- 交叉验证:当金额 + 税额可计算时,验证等式
金额(不含税) + 税额 = 价税合计,用于发现 OCR 丢字问题
常见问题与处理
OCR 识别金额丢失首位数字
电子发票中"(小写)"后的金额可能因字体渲染问题导致首位数字丢失(如 66854.00 识别为 6854.00)。
解决方案:
- 交叉验证:金额(不含税) + 税额 = 价税合计,若等式不成立则 OCR 结果可能有误
- 大写金额验证:OCR 同时识别"价税合计(大写)"行,通过大写金额反推数字金额
- 图片放大:使用 --scale 2.0 放大图片后重新 OCR
文档中同一图片被多次引用
Word 文档中同一张图片可能被插入多次(document.xml 中同一 rId 出现多次 blip 引用)。处理时需注意:
- 解析 XML 时不要去重 blip 引用,按实际出现次数计数
- 同一图片文件出现 N 次,金额应累计 N 次
电子发票 vs 纸质发票金额行位置不同
- 电子发票(PNG,如数电票):"价税合计"行通常在图片高度的 52%-66% 区域
- 纸质发票扫描件(JPEG/PNG):"价税合计"行通常在图片高度的 70%-82% 区域
批量处理时可采用双区域裁剪策略,同时截取两个候选区域拼接后 OCR。
参考文档
references/invoice_formats.md:中国发票格式说明、OCR 金额提取正则表达式、常见字段定位参考references/integration_guide.md:将 RapidOCR 嵌入到应用(小程序后端、桌面工具、Web 服务)的集成方案
脚本清单
| 脚本 | 功能 |
|---|---|
scripts/extract_docx_images.py |
从 docx 文档提取图片并建立客户-发票映射 |
scripts/ocr_invoices.py |
批量 OCR 识别发票图片,提取金额等关键字段 |
scripts/verify_amounts.py |
金额交叉验证(金额+税额=价税合计) |