Project Atlas 知识图谱 / 验证码识别服务 ← 返回图谱
🔢

验证码识别服务 invoice_verification

HTTP 服务:输入验证码图片 + 中文意图("请输入验证码文字 / 红色文字 / 蓝色文字"),返回识别字符。两步法——HSV 单色抠图 + PP-OCRv5 识别,可选 LLM 兜底。被 Chrome 采集插件调用,用于攻克税务发票查验平台的彩色验证码。

FastAPI PaddleOCR 3.4.1 PP-OCRv5 CPU-only LLM 兜底 :8000
本页导航
调用场景 识别流程 接口 意图路由 响应与错误码 标注反馈闭环 部署 离线模型 关联

# 一、调用场景:税务发票查验

本服务的主要调用方是 Chrome 采集插件。插件在采集全国增值税发票查验平台(inv-veri.chinatax.gov.cn)时,该平台要求输入一段彩色验证码(提示"请输入图片中红色/蓝色文字"),插件把验证码交给本服务识别。

Chrome 插件 (directDetail/chinataxV2.ts)
        │  ① 抓验证码图片 → 转 base64
        │  ② 读页面提示文字当 prompt(如"请输入红色文字")
        ▼
POST http://<验证码服务>/recognize_base64      ← 本服务
        │  ③ 返回识别文字 text
        ▼
插件填入 #yzm → 提交查验 (queryFpcyxx)
        │  ④ 以税务局接口响应判定验证码对错
        ▼
POST /label/feedback  上报对错 → 进入准确率统计与再训练闭环
插件侧支持 全部 / 红色 / 蓝色 / 黄色 四种颜色意图,与本服务 config.yaml 的 intent_rules 精确对应。验证码对错以税务局 queryFpcyxx 查验接口的响应为准,而非本服务自身置信度,判定结果回流形成准确率统计。
插件中的服务地址示例为 http://192.168.113.70:8123(端口按部署环境而定,非固定 8000)。旧版采集器 chinatax.ts 调 /recognize,新版 chinataxV2.ts 调 /recognize_base64 并带 /label/feedback 反馈。

# 二、识别流程(两步法)

验证码图片 + 中文意图 prompt
        │
        ▼
① 意图路由 (RED / BLUE / YELLOW / ALL)
        │
        ▼
② 单色抠图 (HSV 四色阈值 + 连通域去噪) —— RED/BLUE/YELLOW 时按颜色抠字
        │
        ▼
③ PP-OCRv5 识别 (在 1749 张人工样本上微调的 mobile rec head)
        │
        ├─ 高置信 → 直接返回 (source=ocr)
        └─ 低置信/含中文 → 可选 LLM 兜底 (source=llm)
识别头是微调过的 PP-OCRv5 mobile rec(data/finetune_output_v2/best_accuracy/inference/)。抠图保留原始墨色白底(不二值化),因为 PaddleOCR 对自然色文字识别更好。

# 三、接口

服务监听 8000,响应统一 RecognizeResponse 结构。

方法路径说明
GET/health健康检查,返回 {"status":"ok"}。启动即 200,但首次 OCR 需等模型加载 15–30 秒。
POST/recognizemultipart 上传:image(file) + prompt(string) + rec_only(可选)
POST/recognize_base64JSON:img_base64 + prompt + rec_only。允许 data:image/png;base64, 前缀

请求示例

# multipart
curl -F image=@captcha.png \
     -F 'prompt=识别全部' \
     -F 'rec_only=false' \
     http://127.0.0.1:8000/recognize

# base64 JSON
curl -X POST http://127.0.0.1:8000/recognize_base64 \
  -H 'Content-Type: application/json' \
  -d '{"img_base64":"iVBORw0K...","prompt":"识别全部","rec_only":false}'
rec_only 为 1/true/yes/on 时跳过检测,整图直接过 rec head。约束:图片 ≤ 2MB,仅 PNG/JPEG。

# 四、意图路由

config/config.yaml > intent_rules 命中规则(不区分大小写,子串匹配),未命中回退 default_intent(默认 ALL):

意图关键词
RED红色、红字、red
BLUE蓝色、蓝字、blue
YELLOW黄色、黄字、yellow
ALL全部、所有、验证码文字、all

颜色阈值在 config.yaml > color_filter 配置(HSV 范围、形态学核、单色抠图参数)。改阈值后需重跑 python -m tests.eval 校准准确率。

# 五、响应与错误码

{
  "code": 0,           // 0成功 / 1命中中文需复核 / 2识别失败
  "text": "TET7",
  "mode": "ALL",       // 实际走的意图分支 ALL/RED/BLUE
  "source": "ocr",     // ocr / ocr_lowconf / llm
  "confidence": 0.8949,
  "ocr_confidence": 0.8949,
  "elapsed_ms": 262,
  "message": null
}
调用方应优先看 code 而非 HTTP 状态码:识别失败/含中文都是 200 OK,只在参数错误时返 4xx。

参数错误码

codehttp含义
4001400image / prompt 缺失
4002400格式不支持 / 超 2MB / base64 解析失败
4003400prompt 太长或无法路由
5001500所有识别路径都失败
5003500服务端未知错误

# 六、标注反馈闭环(/label/*)

除识别接口外,服务还带一套在线标注 + 反馈 + 再训练闭环(app/api/label_routes.py,配合 app/static/label.html 页面)。插件采集时的对错反馈、以及人工打标,都汇入这里持续改进模型。

方法路径说明
POST/label/feedback上报一次识别的对错(插件以税务局查验结果为准调用),计入准确率统计
GET/label/next后端代理上游验证码接口(绕过 CORS),随机取发票号拉图,用本地模型识别一次返回
POST/label/save存人工确认/纠正后的样本到 data/raw_dump/打标-已标记/,每满 100 张提示可开训
GET/label/history标注历史
POST/label/train触发模型微调训练(?mode=full)
GET/label/train/status · /label/train/config训练状态与配置
样本命名 <毫秒>,<颜色>,<答案>.png 可被 scripts/prepare_finetune_dataset_v2.py 直接消费,形成"采集识别 → 反馈纠错 → 增量微调"的自我改进链路。

# 七、部署

本地开发

python3 -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
python -m app.main          # 首次启动下载 PP-OCRv5 权重到 ~/.paddleocr

Docker Compose(CPU-only 一键)

docker compose up -d --build
docker compose logs -f captcha    # 等到 "Application startup complete."
curl http://<host>:8000/health
镜像约 1.4GB(paddle 占大头)。前置要求:Docker 24+ / compose v2、≥2 CPU 2GB 内存(compose 已写死上限)、8000 端口、首次启动需外网下约 220MB 模型。依赖锁定 paddlepaddle 3.3.1 / paddleocr 3.4.1 / paddlex 3.4.3。

# 八、离线模型与运维

首次启动顺序拉取模型到容器内 /root/.paddlex/official_models/,缓存在 paddlex_cache named volume,重启不再下载:

# 内网离线:先在联网机预热 ~/.paddlex,再喂给容器 volume
docker compose up -d && docker compose stop captcha
docker run --rm -v $(pwd):/src -v invoice_verification_paddlex_cache:/dst \
  busybox sh -c "cp -r /src/paddlex/* /dst/"
docker compose start captcha

# 常用运维
docker compose ps
docker compose restart captcha
docker compose down        # 保留 volumes
docker compose down -v     # 连模型缓存一起删(会重新下载)
LLM 兜底默认关闭。开启需 config.yaml 设 llm.enabled: true,环境变量给 LLM_API_KEY,可调 model/base_url 用 OpenAI 兼容 API。

运行依赖

本服务自包含,不依赖任何数据库 / 消息队列 / 对象存储(是三系统中唯一不接共享基础设施的服务)。唯一外部依赖是可选的 LLM 兜底(默认关闭)。模型权重随镜像内置或首次启动下载,缓存在本地 volume。标注样本与反馈直接落本地磁盘(data/),无需外部存储。

# 九、关联

Project Atlas · 返回知识图谱 · 如何维护