space ocr
指南文章价格文档

最好用的票据与发票 OCR 识别软件

票据与发票 OCR 软件选购指南:可验证的准确度、明细提取、导出、API 与 webhook、审计追踪,以及透明的定价——并用实时演示逐一印证。

凡是要跟纸打交道的企业,都绕不开票据和发票——而这两样东西手动录入起来都让人头疼。OCR 的卖点很直白:把单据拍下来,得到结构化数据,然后继续干别的。问题在于,大多数 OCR 工具只做到了看起来像那么回事。它们给你一个供应商名称和一个合计金额,剩下的就要你自己去信。记一笔个人开销,这没问题。但放到应付账款、费用对账,或者任何会被审计的场景里,“模型说是这样”可不是你敢拍胸脯担保的答案。

本文就是一份选购清单。它会带你梳理:到底是什么把真正好用的票据与发票 OCR 软件和一个华而不实的演示区分开来——可验证的准确度、明细行提取、干净的导出、带 Webhook 的真正 API、审计记录,以及你能预估的定价——然后展示 space-ocr 如何逐一做到,用一个实时、可核对的演示,而不是一张截图。

先看证据:一次你可以亲自核对的真实提取

在罗列任何功能之前,先看一样多数厂商不会给你看的东西:一次提取里,每一个数值都能指回它在页面上原本所在的确切位置。把鼠标悬停在下方任意字段上——票据上高亮的那个框,就是这个数值被读取的地方。

Receipts with extracted-field bounding boxes
Verified fields
KINSHO · 合計 2,045
ライフ · 合計 4,286

Each value with a box carries a verified on-page location — in data.cells[path], that is box + 4-point quad + evidence.match_ratio — on a 0–1000 normalized grid (0,0 top-left → 1000,1000 bottom-right), the same shape the live API returns. Hover a field to trace it back to the pixels it came from.

票据与发票 OCR 该看哪些点

票据和发票是最难啃的“简单”单据。版式因供应商而异,合计金额藏在小计和税额之间,明细行会换行折行,而一张手机拍的照片往往是歪的、还带着反光。一个能搞定干净 PDF 的工具,下一张皱巴巴的热敏小票就可能崩盘。用下面这些标准,帮你穿过营销话术看清本质。

关键点为什么重要弱工具强工具
可验证的准确度一个无法追溯的数字,反正你还得重新录入一遍给出一个值,也许再加个置信度分数给出每个值连同它的来源坐标——轴对齐的框,加上跟随页面倾斜的四点
给的是待查清单,不是分数先查哪一条,总得有人决定把阈值设计丢给你自己返回需要复核的路径,附上机器可读的原因码;声明过的数值与日期还带确定性解析值
明细行发票和票据是表格,不是一组扁平字段抓到合计,丢掉行提取可重复的明细行,每个单元格都带位置
导出数据得能离开工具才有用复制粘贴或锁死在查看器里通过 API 提供 CSV(Excel/中日韩文本安全)和 JSON
API + Webhook真有量就意味着自动化,而不是点鼠标只有界面,或一个单薄的同步接口带异步任务和签名 Webhook 的 REST API
审计记录审核者需要看到改了什么悄悄覆盖 OCR 输出把原始值保留在人工修改旁边
透明定价做预算最怕意外凡事“请联系我们”公开的单图价格加免费额度

本文余下部分会逐行展开。

可验证的准确度,胜过一个置信度分数

置信度分数告诉你模型自我感觉很有把握。它并不告诉你 total: 2,045 到底是不是票据上实际印着的那个数字。space-ocr 回答的是一个更严苛的问题。业务数据放在 data.values 里,而通往它的每一条路径(total、line_items[0].unit_price)都对应 data.cells 中的一项:

  • box——一个轴对齐矩形 { xmin, ymin, xmax, ymax },位于 0–1000 归一化网格上(0,0 = 左上角,1000,1000 = 右下角)。换算成像素要用 data.image,它给出实际读取时的页面宽高。
  • quad——四个有序顶点,跟随单据的倾斜角度,且始终与 box 一起返回。系统不做倾斜校正,所以哪怕手机拍歪了,框也会按页面本来的样子贴上去。
  • verified——这是一个判定:单元格带有复核原因时为 false,比对跑过且没有任何标记时为 true,没有可比对的对象时(例如明细行的合并框)为 null。
  • review——要么是 null,要么是 { reasons },说明这个单元格为什么值得再看一眼。
  • evidence——判定背后的佐证:text_match 是逐字符比对本身的结果,match_ratio 表示该值有多少字符在页面上被定位到,printed_text 是这些坐标处 OCR 读到的原始字符。

待办清单是 data.review.flagged——一个 { path, reasons } 数组,其中 path 与 cells 的键用同一套写法,可以直接取到对应单元格。因为位置是跟着值一起走的,你可以渲染出这个框、引用这些坐标,或者重新核对一个被标记的字段,而无需重跑 OCR。这正是 OCR 审计记录 的基础——也是上面那个演示不是摆拍的原因。

✓ Verified

这些坐标并不是听模型一面之词得来的。 语言模型会返回每个字段的文本——以及它用到了哪些词元(word token)的提示——但从不返回框本身。引擎随后把这段文本与视觉 OCR 在页面上实际检测到的符号逐字符匹配,于是框落在这些字符被找到的真实像素上,每个值也据此得到一个 match_ratio,表示它有多大比例被定位到了。模型给的词元提示可能有噪声(在重复出现的行之间它有时会张冠李戴),所以系统用列一致性和行一致性检查来验证这些提示,而不是盲目相信它们。重点不在于 AI 不会出错——而在于每个值都会回过头来与票据本身核对,并附上一个分数说明它匹配得有多好。

要的是明细行,不只是合计

廉价票据 OCR 最大的缺口就在表格。谁都能抓到一个总计;真正的价值在行里——每一项商品、数量、单价和折扣。space-ocr 把这些提取为可重复的行,而且每个单元格都保留自己的位置,所以一条换行或合并的明细行依然可追溯。

你通过一个 type: "array" 的字段来请求它们,其 children 描述一行的结构。关于行模型更深入的讲解,参见 从发票中提取明细行。

明细行字段定义
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
  "fields": [
    { "name": "vendor", "type": "string" },
    { "name": "invoice_date", "type": "string" },
    { "name": "total", "type": "string" },
    {
      "name": "line_items",
      "type": "array",
      "children": [
        { "name": "description", "type": "string" },
        { "name": "quantity", "type": "number" },
        { "name": "unit_price", "type": "number" }
      ]
    }
  ]
}

只声明你需要的字段——不确定就交给 autoFields

抽取模式通过 fields 数组传入:把真正要落库的项按名称和类型列出来,明细行则声明成 type: "array" 字段,用 children 描述其中一行。如果还不清楚单据上有哪些项,改传 autoFields: true,由模型提出一份模式——把它返回的字段名固化成显式声明,就是你的生产调用。

声明并不是一个调节准确度的旋钮。required、pattern、min/max、enum、near、not_near 都不会传给模型,所以声不声明,抽出来的值都一样。多出来的是两样东西:违反规则的值会连同原因(missing、pattern_mismatch、out_of_range、near_mismatch、near_conflict)进入 data.review.flagged;而声明 number、integer、date 会在 values 旁边多出 data.normalized 这一层——同一份读数的确定性解析结果,同一张页面每次跑都得到同一个数。near 和 not_near 并不能让模型在印着两个公司名的单据上挑对那一个,它们的作用是让挑错这件事显形。

整个调用就是一次 HTTP 请求——不用 SDK,也不用对 PDF 做预处理(引擎读的是栅格图像,也就是照片和扫描件)。

字段声明与 autoFields
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# A. 生产——只声明你真正要落库的项
curl -s https://api.space-ocr.com/ocr/fields \
  -H "Authorization: Bearer $SPACE_OCR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "image": "https://example.com/invoice.jpg",
    "imageType": "url",
    "fields": [
      { "name": "issuer",         "type": "string", "near": ["纳税人识别号", "电话"] },
      { "name": "recipient",      "type": "string", "not_near": ["纳税人识别号", "电话"] },
      { "name": "invoice_no",     "type": "string", "required": true,
        "pattern": "^[A-Z0-9-]{4,}$" },
      { "name": "invoice_date",   "type": "date" },
      { "name": "payment_method", "type": "string", "enum": ["现金", "转账", "信用卡"] },
      { "name": "total",          "type": "number", "required": true, "min": 0 },
      {
        "name": "line_items",
        "type": "array",
        "children": [
          { "name": "description", "type": "string" },
          { "name": "quantity",    "type": "number" },
          { "name": "unit_price",  "type": "number" }
        ]
      }
    ]
  }'

# B. 探索——还没有模式,让接口提一份
curl -s https://api.space-ocr.com/ocr/fields \
  -H "Authorization: Bearer $SPACE_OCR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "image": "https://example.com/invoice.jpg",
    "imageType": "url",
    "autoFields": true
  }'

导出与 API:数据去往何处

如果数据被困在工具里,提取就毫无价值。space-ocr 给你两条干净的出口:

  • CSV——表格导出时带 UTF-8 BOM,这样 Excel 才能正确打开日文、韩文和中文文本。数组(明细行)会展开成子行,而任何人工修正都会在输出中覆盖 OCR 原值。
  • 基于 REST 的 JSON——POST /ocr/fields 处理单份单据,POST /upload 把图片直接推入一张表,GET /view 在服务端查询已存储的表(where、sort、select、limit),无需重跑 OCR,也不必再付一次费。

面向大批量的自动化,/upload 默认是异步的:它为每个文件返回一个任务,并在完成时通过 Webhook 通知你——每个空间一个签名(HMAC-SHA256)端点,事件如 ocr.completed 和 ocr.failed。这就是“你点鼠标的工具”和“自己跑起来的流水线”之间的区别。完整的接口面收录在 发票数据提取 API 指南 和 API 文档 里。

丢进一张票据或发票,结构化字段就回来了——每一个都定位在源图像上。

审计记录:机器读到了什么 vs. 人改了什么

最好的票据与发票 OCR,不只是记录它自己的输出——它还会记录修正。当你在 space-ocr 里编辑一个单元格时,你的值会与 OCR 原值分开存储,而一个 Original(原值)提示框始终显示引擎最初读到的内容。审核者可以并排看到机器值和人工覆盖值——这恰恰是审计所要的。

点击任意单元格,对应区域就会在原图上亮起——这是抽查一整批的最快方式。

透明、可预估的定价

可验证的准确度和一个实诚的价格,往往出自同一种态度。space-ocr 为每张图 $0.05。有每月 100 点数的免费额度,无需信用卡;Pro 套餐 $39/月,含 1,100 点数、不限表格数量和 100 GB 存储。没有按字段计费,没有按页加价,针对已存储表的查询(GET /view)也是免费的。

如何提取一张票据或发票

  1. 发送图像
    把票据或发票 POST 到 /ocr/fields,imageType 取 'url' 或 'base64'。引擎读的是栅格图像——手机照片或扫描件。
  2. 声明字段
    用 fields 数组声明你要落库的项,明细行用带 children 的 array 字段描述其中一行。如果模式还没定下来,就改传 autoFields 让模型提一份。
  3. 读取结构化结果
    业务数据在 data.values;每个值的 box、quad、verified、review 和 evidence 在 data.cells[path];坐标所依据的页面尺寸在 data.image。
  4. 核对与修正
    逐条处理 data.review.flagged:每一项给出路径和原因(text_mismatch、missing、out_of_range 等)。点击单元格即可高亮它被读取的确切区域;修改会保存在原值旁边。
  5. 导出或查询
    下载 CSV(UTF-8 BOM,明细行已展开),或用 GET /view 配合 where、sort 和 select 查询已存储的表——无需重跑 OCR,也不额外收费。
票据和发票 OCR,哪款软件最好用?
最好的工具不止是识别文字——它们会提取明细行、导出干净的 CSV 和 JSON、提供带 Webhook 的 REST API、保留修正的审计记录,并透明定价。space-ocr 还加上了可验证的准确度:每个值都带着来源坐标放在 data.cells[path] 里,data.review.flagged 会把需要复核的路径连同原因一起给你,所以你能把任何数字追溯回它来自的像素。你可以自己声明需要的字段,还没想好就用 autoFields 让接口提一份,并且每月有 100 点数的免费起步额度。
OCR 能从票据或发票里提取明细行吗,而不只是合计?
可以。在 space-ocr 里,你把明细行作为一个 'array' 类型的字段来请求,其 children 描述一行的结构(描述、数量、单价等等)。每个单元格都以 line_items[0].unit_price 这样的带下标路径出现在 data.cells 中,所以一条换行或合并的明细行依然能追溯到它在页面上的位置。
票据和发票 OCR 对手机拍的照片管用吗?
管用。引擎在加载时会应用 EXIF 旋转,使返回的坐标与实际读取的页面一致;除了轴对齐的框,它还返回跟随单据倾斜角度的四个有序顶点(quad)。系统不做倾斜校正,所以歪斜、旋转的手机照片依然按页面本来的样子框住。输入是栅格图像——照片和扫描件。
票据和发票 OCR 多少钱?
space-ocr 为每张图 $0.05。有每月 100 点数的免费额度,无需信用卡;还有 $39/月 的 Pro 套餐,含 1,100 点数、不限表格数量和 100 GB 存储。用 GET /view 查询已存储的数据是免费的,也没有按字段或按页的附加费。
我能把票据和发票处理做成大批量自动化吗?
可以。POST /upload 把图片直接推入一张表,默认异步运行,为每个文件返回一个任务,并在完成时通过签名(HMAC-SHA256)的 Webhook 通知你,例如 ocr.completed 和 ocr.failed。你也可以轮询 GET /jobs/{jobId} 作为 Webhook 的替代方案。

拿你自己的票据和发票,试试最好用的 OCR

免费额度——每月 100 点数,无需信用卡。每个值返回时都带着它在页面上的位置。

相关