vision-handwriting-form-extraction · ZH · 2026-10-08

用手写表单与票据做字段抽取:视觉模型该怎么问

针对低质量、倾斜或手写扫描件,本文介绍图像预处理方法、字段抽取的提示框架,以及校验返回 JSON 的实用策略,帮助你更稳定地从表单与票据中提取结构化信息。

为什么直接问视觉模型容易失败

手写表单和票据的扫描件往往存在光照不均、倾斜、透视变形、字迹潦草、印章遮挡等问题。如果直接把原始图像丢给视觉模型并要求抽取字段,模型可能因为看不清或误读而返回错误结果,甚至生成不存在的字段。

因此,一个稳健的流程通常包含三个环节:图像预处理、提示设计、JSON 校验。

图像预处理:让模型看得更清楚

预处理的目标是减少干扰,突出文字区域。常见操作包括:

  • 去噪与二值化:对灰度图使用自适应阈值,将文字与背景分离。
  • 倾斜校正:通过霍夫变换或最小外接矩形检测文本行角度,旋转至水平。
  • 透视矫正:检测票据四角,做透视变换,得到正视图像。
  • 对比度增强:使用 CLAHE 等方法提升局部对比度,尤其适合褪色或阴影区域。
  • 裁剪与缩放:裁掉无关边缘,将图像缩放到模型推荐的输入尺寸附近。

注意:预处理不是越复杂越好。过度二值化可能丢失手写笔画的细节,反而降低识别率。建议保留一份原始图像作为备选。

提示框架:明确任务与约束

视觉模型对提示的格式敏感,尤其是需要结构化输出时。一个有效的提示应包含以下部分:

1. 角色与任务

你是一个表单信息抽取助手。请从给定的票据图像中提取以下字段:日期、金额、收款方、备注。

2. 字段定义与格式

为每个字段提供名称、类型和示例,避免歧义:

  • date: 字符串,格式 YYYY-MM-DD,若无法识别则填 null
  • amount: 数字,仅保留数值,不含货币符号
  • payee: 字符串,保留原始大小写
  • note: 字符串,可为空

3. 处理不确定性的规则

如果某个字段被遮挡、模糊或无法确认,请将该字段值设为 null,不要猜测。
如果图像中不存在该字段,也设为 null。

4. 输出格式

只返回一个 JSON 对象,不要包含任何额外文字或 Markdown 代码块。

对于多张图像或复杂表单,可以要求模型返回数组,每个元素对应一个区域或一张图。

校验返回的 JSON:从解析到业务规则

模型返回的 JSON 可能包含语法错误、多余文本或不符合预期的值。建议按以下层级校验:

第一层:语法解析

使用 JSON 解析器尝试解析。如果失败,可以尝试提取第一个 { 到最后一个 } 之间的内容,或要求模型重新输出。

第二层:模式校验

定义 JSON Schema,检查:

  • 字段是否存在
  • 类型是否正确(字符串、数字、null)
  • 日期格式是否符合 YYYY-MM-DD
  • 金额是否为非负数

第三层:业务规则

根据具体场景增加规则,例如:

  • 金额与明细行求和是否一致
  • 日期是否在合理范围内
  • 收款方名称是否与已知列表匹配

第四层:人工复核

对于高价值或低置信度的字段,保留裁剪后的局部图像,供人工快速核对。可以在返回结果中增加 confidence 字段(如果模型支持),或根据字段是否被遮挡来标记。

实践建议

  • 先预处理再识别:倾斜和光照问题在预处理阶段解决,比让模型“硬看”更可靠。
  • 提示要具体:字段名、类型、格式、空值规则都写清楚。
  • 校验要分层:从语法到业务规则,逐步过滤错误。
  • 保留原始图像:便于人工复核和调试。
  • 测试不同模型:手写识别对模型能力敏感,可以在同一提示下对比多个视觉模型的表现。

通过聚合 API 调用多个模型时,可以先用一个模型做快速抽取,再用另一个模型对不确定字段进行复核,平衡成本与准确率。