space ocr
文章文档
developer

一个返回可验证边界框的 OCR API

大多数 OCR API 都会返回边界框——但坐标系各不相同,而一个框只告诉你在哪,不告诉你有多确定。这是一份面向开发者的指南:如何获得带源坐标的 OCR,外加一个匹配比例,告诉你每个值有多少真的在页面上被找到了。

8 分钟阅读· 2026-06-25

边界框是你验证 OCR 的依据。一个光秃秃的字符串只告诉你模型自以为读到了什么;而一个框告诉你它是在页面的什么位置读到的,于是你(或你的审核者、或你的代码)可以拿这个值跟原件核对,而不是盲目相信。如果你要把 OCR 接入任何会被审计的场景——发票、报销、KYC、档案管理——“模型返回了 total: 2,045”是不够的;你得能指出 2,045 究竟是从哪些像素上来的。

好消息是:大多数主流 OCR API 确实会返回边界框。问题在于,一旦你真动手开发,它们会在三个要紧的地方各不相同——坐标系、是否同时给你结构化字段(而不只是原始文本),以及那个逐值置信度到底度量的是什么。本文会把这三点逐一讲透,并展示一个带源坐标、外加一个字符覆盖匹配比例的 OCR API 在实践中是什么样子。

先看证据:可以悬停的框

这是一次真实的提取,其中每一个值都能指回它被读取出来的确切区域。把鼠标悬停在任意字段上——票据上的那个框就是这个值的来源,而每个值都带着一个匹配比例,告诉你这个值的文本有多少真的在页面上被定位到了。

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

Every value carries a verified on-page location — bbox + 4-point vertices + 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.

Demo每个字段都返回一个边界框和一个 <b>匹配比例</b>——正是这些坐标,让一次提取从“看起来可信”变成“可以核对”。
每个字段都返回一个边界框和一个 匹配比例——正是这些坐标,让一次提取从“看起来可信”变成“可以核对”。

大多数 OCR API 都返回框——区别在这里

Google Cloud Vision、Tesseract、Amazon Textract 和 Azure AI Document Intelligence 都会随文本一起返回几何信息。它们的分歧在于坐标系、在于你拿到的是结构化字段还是只有原始文本加版式,以及那个置信度数字意味着什么。这些是经过核实的事实,而非营销话术——用它们来估算这套集成在你的技术栈里要花多少工。

API坐标系结构化字段逐值置信度
Google Cloud VisionboundingPoly 顶点,单位为源图像的像素仅文本 + 几何信息(结构化键值对属于 Google Document AI,是单独的产品)每个词/符号的识别置信度(0–1)
TesseracthOCR / TSV 框,单位为像素(自托管,无 API)无——仅原始文本 + 版式每个词的识别置信度(0–100)
Amazon TextractBoundingBox,按页面宽高归一化到 0–1(外加 Polygon表单/表格用 AnalyzeDocument;票据用 AnalyzeExpense每个 block 的识别置信度(%)
Azure Document Intelligence边界多边形,单位为像素(图像)或英寸(PDF)预构建/自定义模型每个词的识别置信度
space-ocrbbox 归一化到 0–1000(外加带方向的 vertices内置模板 + 自定义字段,支持明细行match_ratio——该值的字符在页面上被找到的比例——外加 bbox_source

有两点值得留意。第一,坐标单位不可移植——Vision/Tesseract/Azure 的像素框绑定在你发送的那张确切图像上,而归一化的框(Textract、space-ocr)在缩放后依然有效。第二,置信度这一列含义不同:大多数 API 报告的是识别置信度(模型有多确定),这与“度量一个返回值有多少真的在页面上被定位到”并不是一回事。

✓ Verified

框是怎么推导出来的,和它的格式同样要紧。 在 space-ocr 中,语言模型会返回每个字段的文本——以及它用到了哪些词元(word token)的提示——但从不返回框本身。引擎随后把这段文本与视觉 OCR 在页面上实际检测到的符号逐字符匹配,于是框落在这些字符被找到的真实像素上,每个值也据此得到一个 match_ratio,表示它有多大比例被定位到了。这些词元提示可能有噪声(它们有时会在重复出现的行之间张冠李戴),所以系统用列一致性和行一致性检查来验证它们,而不是盲目相信。这正是“模型断言的坐标”和“回过头来与页面核对过的坐标”之间的区别。

space-ocr 为每个值返回什么

在每个提取出的值旁边,你会拿到四样东西,所以一个坐标绝不只是一个你不得不信的数字:

  • bbox——一个轴对齐矩形 { xmin, ymin, xmax, ymax },由整数构成,位于一个 0–1000 归一化网格上(0,0 = 左上角,1000,1000 = 右下角),与图像的像素尺寸无关。
  • vertices——正好四个有序顶点(左上、右上、右下、左下),构成一个带方向的框,会跟随单据的倾斜角度,所以一张拍歪的手机照片也能干净地框住。
  • match_ratio——该值的字符中,实际在页面上被定位到的比例(0–1)。当达到 ≥ 0.85 时,该字段被视为可信匹配;1.0 表示每一个字符都被找到了。
  • bbox_source——一个标签,说明坐标是怎么推导出来的(例如逐字符匹配路径对应 vision_symbol_match,当匹配比例低于阈值时则为 low_confidence)。
一个返回值
1
2
3
4
5
6
7
8
9
10
11
12
{
  "total": {
    "value": "2,045",
    "bbox": { "xmin": 381, "ymin": 803, "xmax": 500, "ymax": 825 },
    "vertices": [
      { "x": 380, "y": 804 }, { "x": 500, "y": 801 },
      { "x": 500, "y": 823 }, { "x": 381, "y": 826 }
    ],
    "match_ratio": 1.0,
    "bbox_source": "vision_symbol_match"
  }
}

像素还是归一化?换算一次,缩放就不再出问题

OCR 集成里有一类反复出现的 bug:像素坐标绑定在你上传的那张确切图像上——一旦为了存储而缩放或重新压缩,或者漏掉一个 EXIF 旋转标志,叠加上去的框就会漂移、被裁切,或者落到错误的文字上。归一化坐标避开了一整类这样的 bug:一个 0–1000 的框可以映射到同一页面的任意一种渲染上。

要在显示的图像上画一个框,只需换算一次:

  • SVG 叠加层——给 SVG 设 viewBox="0 0 1000 1000",然后原样画出 bboxvertices
  • 绝对定位的 div——leftPct = xmin / 1000 * 100topPct = ymin / 1000 * 100widthPct = (xmax - xmin) / 1000 * 100heightPct = (ymax - ymin) / 1000 * 100
  • 换回像素——pixel_x = bbox_x / 1000 * image_widthpixel_y = bbox_y / 1000 * image_height

引擎在加载时还会应用 EXIF 方向,所以它返回的坐标已经与显示出来的图像对齐——一张旋转过的手机照片(方向 6/8)不需要你这边再做一遍纠正处理。

请求字段并拿回坐标
1
2
3
4
5
6
7
8
9
10
11
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/receipt.jpg",
    "imageType": "url",
    "fields": [
      { "name": "vendor", "type": "string" },
      { "name": "total",  "type": "string" }
    ]
  }'

置信度分数和匹配比例不是一回事

这是个值得内化的区别。大多数 OCR API 都记录了一个识别置信度——一个反映引擎对自己读取结果有多确定的数字,依据的是字体清晰度、图像质量之类的因素。它有用,但那是模型在给自己的作业打分。而匹配比例度量的是某种外部的东西:在模型返回的那个值的字符里,有多少真的能在页面级 OCR 检测到的符号中被找到。一个值可以带着识别置信度被返回,却依然跟页面上的任何东西都对不上;一个低的 match_ratio 恰好能逮住这种情况。把它当作一道闸门——对 match_ratio < 0.85 排序或筛选,把那少数几个值得人工瞥一眼的值挑出来,而不必把所有东西都重新核对一遍。

先验证,再查询——无需重跑 OCR

坐标在数据留存下来时最有用。用 POST /upload 把图像推入一张表,然后用 GET /view 在服务端查询它——wheresortselectlimitoffset——比如拉出所有 match_ratio 偏低或 total >= 40000 的行,既不重跑 OCR,也不再付一次费。每个返回值都保留它的 bboxvertices(或用 boxes=0 把它们去掉,得到更轻量的响应体)。关于验证工作流的深入讲解,参见 用边界框验证 OCROCR 审计记录

Demo点击任意一个值,它的源区域就会在原件上高亮——正是 API 返回的那些坐标,做成了可交互的样子。
点击任意一个值,它的源区域就会在原件上高亮——正是 API 返回的那些坐标,做成了可交互的样子。

如何从 API 拿到可验证的边界框

  1. 请求字段
    把图像 POST 到 /ocr/fields,imageType 设为 'url' 或 'base64',并附上一个 templateId 或你自己的 fields 数组。引擎接收栅格图像(JPEG、PNG、GIF、BMP、TIFF、WebP)。
  2. 读取坐标
    每个值返回一个位于 0–1000 网格上的 bbox { xmin, ymin, xmax, ymax }、四个带方向的顶点、一个 match_ratio,以及一个 bbox_source。
  3. 叠加或换算
    用 viewBox 为 '0 0 1000 1000' 的 SVG 画框,或用 pixel_x = bbox_x / 1000 * image_width 换算成像素。EXIF 旋转已经应用过,所以框与显示出来的图像对齐。
  4. 对匹配比例设闸门
    把 match_ratio 在 0.85 及以上当作可信匹配;把任何低于它的挑出来供人工瞥一眼,而不必把每个值都重新核对一遍。
  5. 存储并查询
    用 /upload 把图像推入一张表,再用 GET /view(where、sort、select)查询它——坐标会被保留,既不重跑 OCR,也不再付一次费。
哪些 OCR API 会返回边界框?
Google Cloud Vision、Tesseract、Amazon Textract 和 Azure AI Document Intelligence 都会随文本一起返回几何信息,space-ocr 也是如此。它们的区别在于坐标系(Vision、Tesseract 和 Azure 用像素;Textract 用 0–1 归一化;space-ocr 用 0–1000 归一化)、在于返回的是结构化字段还是只有原始文本加版式,以及那个逐值置信度度量的是什么。
边界框坐标是像素还是归一化的?
space-ocr 返回的 bbox 归一化到一个 0–1000 网格上,与图像的像素尺寸无关,外加四个带方向的顶点。用 pixel_x = bbox_x / 1000 * image_width(y 同理)换算成像素,或者直接用 viewBox 为 '0 0 1000 1000' 的 SVG 叠加。归一化坐标在图像被缩放后依然有效,而某些其他引擎的像素坐标做不到这一点。
OCR 置信度分数和匹配比例有什么区别?
识别置信度反映的是引擎对自己读取结果有多确定。而 match_ratio 度量的是:返回值的文本有多少真的能在页面级 OCR 检测到的符号中被找到——这是一种外部核对,而非自我报告。space-ocr 把 match_ratio 在 0.85 及以上的值视为可信匹配,所以你可以对偏低的那些设闸门。
对于拍歪或旋转的照片,我能拿到带方向的边界框吗?
可以。每个值都返回四个有序顶点(左上、右上、右下、左下),构成一个跟随单据倾斜角度的带方向的框。引擎在加载时还会应用 EXIF 方向,所以坐标已经与显示出来的图像对齐——一张方向为 6 或 8 的手机照片,不需要你这边再做一遍纠正处理。
这种带边界框的 OCR 支持日文、韩文和中文吗?
支持。同一个引擎处理中日韩文字和拉丁文字,自动检测语言——无需设置任何语言参数——并为每个值返回同样的 bbox、vertices 和 match_ratio,无论是哪种文字,也包括全角字符和竖排汉字。

为每个值拿到源坐标

免费额度——每月 100 次扫描,无需信用卡。每个字段都返回一个边界框、带方向的顶点,以及一个匹配比例。

相关文章