
-
使用 Vision 框架读取文档
了解 Vision 框架的最新进展。我们将介绍 RecognizeDocumentsRequest,并介绍如何使用该工具读取文本行并将其分组为段落、读取表格等。此外,我们将深入探讨相机镜头污渍检测,以及如何在照片图库或你自己的相机拍摄管道中识别可能有污渍的图像。
章节
资源
- Classifying Images with Vision and Core ML
- Image Classification with Vision and CoreML
- Recognizing tables within a document
- Vision
相关视频
WWDC25
WWDC24
WWDC23
-
搜索此视频…
大家好 我叫 Megan Williams 是 Vision Framework 团队的工程师 Vision 提供的 API 可帮助你 轻松地将机器学习技术 集成到 App 中 适用于各种不同的用例 例如人物和物体检测、 身体和手势追踪 以及轨迹分析等
另外 所有 Vision API 都完全在设备端运行 让你能够以高效且安全的方式 在 App 中运行计算机视觉任务
我们的 API 可用于 iOS、macOS、 iPadOS、Apple tvOS 和 visionOS
Vision 提供 31 个 API 可用于不同类型的图像分析 现在 我们又增加了两个 API 在本视频中 我们将介绍的新 API 可用于读取文档 和执行相机镜头污渍检测 最后 我们将介绍手势检测的更新
我们来深入了解一下
Vision 目前支持 使用 RecognizeTextRequest 从图像中检测和提取文本行的功能 这项功能非常实用 但有些文档具有高度结构化的格式 我们可以需要从中提取更多信息
例如 这张传单中有标题、几个段落 列表、表格和条形码
如果我只读取文档中的文本行 就会遗漏重要的结构化信息 例如 如果只提取这份表格中的 文本行 就无法得知行和列的排列方式 我需要同时了解文本内容 以及文本格式 今年 Vision 将推出新的 API 来实现以上甚至更多功能
一起来了解 RecognizeDocumentsRequest 这个 API 能识别 26 种语言的文本 开发者可使用它从文档中 提取结构化元素 以及重要信息 这个 API 可检测表格和列表等结构
将文本行划分到段落中
检测二维码等机读代码 并识别如电子邮件地址、电话号码 或 URL 等重要信息 这些功能将帮助你更好地理解文档 通过更少的代码 更轻松地进行解析
假设我们经营着一家商店 希望来店顾客 能够注册我们的月度简报
因此 我们提供了一份注册表 供顾客填写自己的姓名、 电子邮件地址和电话号码
我想开发一个 App 来扫描表格 从而为每位顾客创建对应的联系方式
以前 我会使用 RecognizeTextRequest 来提取文本 这样每个表格单元格 都会作为一个独立的对象返回
如果我想为每位顾客创建联系方式 就必须使用 每个文本框的位置信息 这样才能确定 哪些单元格位于同一行
而现在 我可以使用 RecognizeDocumentsRequest 它将为你解析表格 单元格会自动按行分组 这大大简化了解析注册表的过程 让我们来看看如何利用这个 API
RecognizeDocumentsRequest 与 Vision 中的其他请求类似 要进一步了解如何使用 Vision 框架 请观看 WWDC24 讲座“探索 Vision 框架中的 Swift 增强功能” 别担心 我会带大家简要回顾一下
在 Vision 中 我们通过请求来处理图像 请求决定了我们要执行的 图像分析类型 我们可以对图像执行请求 这会生成 一个或多个观察结果 这些观察结果提供了有关图像的信息 例如 人脸在图像中的位置
RecognizeDocumentsRequest 将生成文档观察结果
文档观察结果可帮助你了解 文档内容和结构 当前 如果运行 RecognizeDocumentsRequest Vision 将针对每张图像 返回一个文档观察结果 文档观察结果具有层次结构 每个文档都是一个容器 可以容纳: 文本、表格、列表或条形码
表格由单元格组成 列表由项目组成 它们本身就是容器 并可容纳其他元素 例如文本 现在我们了解了什么是文档观察结果 我们可以用它来解析注册表
我们首先要从文档中提取表格结构
我将使用 iPad 拍摄一张文档照片
我的 App 正在使用 RecognizeDocumentsRequest 来检测并在屏幕上突出显示表格
我们来看一下代码
我刚拍摄了一张图像 需要从中提取表格 首先 我将创建 RecognizeDocumentsRequest 然后 对这张图像执行这个请求 我收到了一份文件观察结果 我可以访问 document 上的 tables 属性 以提取图像中的表格
在本例中 我希望我的文档 只包含一个表格 因此 我只需要返回检测到的 第一个表格
现在已经检测到一个表格 让我们看看它包含的内容
表格由 2D 单元格数组组成 这些单元格可以按行或列访问
我们还将表格的边界定义为 boundingRegion 为你提供图像中表格的具体坐标 每个表格单元格都有一个属性 用于指示它所属的行和列
由于单个单元格可跨越多行或多列 这个值表示为 Range
单元格的内容为 Container 可以容纳 文档中查找到的任何内容 例如文本、表格、列表或条形码
容器也有自己的 boundingRegion
将数据提取成表格后 我现在就可以逐行查看报名表了
我需要查看每个单元格的内容 来提取文本
下面 我们来更详细地看看文本 有多种方法可以查看容器中的文本
转录会将容器中的所有文本 整合成一个字符串 另一种查看文本的方法 是将文本以数组形式显示为行
行可以分组形成段落 从而呈现出更加自然的 文本阅读方式 如果某一行不在段落分组中 它会被视为一个独立的段落 我们还可以获取单个单词的列表 但某些语言不支持这个功能 如中文、日语、韩语和泰语等
最后 detectedData 是文本中检测到的特殊字符串 代表着文档中的关键信息 如电子邮件地址、日期或 URL Vision 将采用新的 DataDetection 框架 支持扫描重要数据的字符串
可检测电话号码、电子邮件地址 和邮政地址 支持各种格式
URL 会被检测为链接 时间和日期 会被检测为日历事件
测量值及相应单位会一起检测 美元金额及相应货币也会一起检测
还可以检测运单号 支付标识符和航班号
有了所有这些功能 我们就可以扩展示例 App 了 我们已经检测到表格 现在就可以提取表格中的文本 以生成联系方式列表 我们可以从第一列读取姓名 然后可以使用数据检测功能 识别其他列中的联系信息
我们来更新一下示例代码 我将解析 之前检测到的表格 并生成联系方式列表
我需要每个联系人的姓名、 电子邮件以及可选的电话号码
我将遍历表格中的所有行 然后针对每一行创建一个联系方式
大多数注册表的第一列都是姓名 所以 我们先提取每行的 第一个单元格
我可以查看这个单元格的文本 来获取联系人的姓名
我会使用转录功能 将单元格中的所有文本提取为字符串
现在 我会尝试查找每行中包含的 其他联系信息
首先 我会遍历剩余单元格
现在 我可以查找每个单元格中的 detectedData
让我们遍历数据 查看检测到的内容
我可以开启数据的详细信息 专门查找电子邮件和电话号码
如果检测到电子邮件 我可以根据 检测到的信息创建联系方式
现在 我可以轻松地从注册表中 提取联系方式列表
我会将这个列表传递到 联系方式视图中 以便在 App 中显示联系方式 我们来看看联系方式
非常好
我还添加了将表格导出为 以制表符分隔的字符串的功能
这样我就可以复制表格 并将它粘贴到兼容的 App 中 比如备忘录和 Numbers 表格
要查看这项功能背后的代码 可以从 Apple 开发者网站 下载示例 App 总而言之 RecognizeDocumentsRequest 让开发者能够轻松从文档中 提取重要信息
这个 API 提供了一个简洁的界面 供你了解文档结构 轻松解析表格等格式化文本 并识别重要信息 如电子邮件和电话号码
现在 我们来谈谈 Vision 今年推出的另一项新功能
相机镜头污渍检测功能
当我拿起设备扫描报名表时 我可能会不小心用手指弄脏了镜头
这可能会导致拍摄的照片质量差 无法进行处理
值得庆幸的是 Vision 今年推出了 一项新功能可解决这一问题 DetectLensSmudgeRequest 可以识别图像是否是通过 有污渍的镜头拍摄的 以便你提示用户清洁镜头 或提供其他照片 通过这项请求 你可以确保 只在 App 中处理高质量图像
DetectLensSmudgeRequest 与 Vision 框架中的其他请求类似 你可以对图像执行这项请求 以生成污渍观察结果
观察结果会提供置信度分数 帮助你了解图像被污渍污染的概率
置信度始终介于 0 和 1 之间
置信度接近 1 表示 图像很有可能被污渍污染
置信度为零表示图像很可能 未被污渍污染 让我们来看看如何 通过代码实现这项功能
我有一张图像 我想知道它有没有被污渍污染
首先 我会创建一个 DetectLensSmudgeRequest
然后 对这张图像执行这个请求
这会生成污渍观察结果
观察结果的置信度会提示我们 图像被污渍污染的概率
我们可以为置信度设定一个阈值 用于滤除质量较差的图像
这里我选择了 0.9
这样 如果图像分数高于这个阈值 就会被视为有污渍污染 从而不进行处理
你可以针对 App 选择一个最合适的阈值 这里显示了三个 具有不同污渍置信度的文档
阈值较高就能处理更多的图像 但这些图像的质量可能较低
阈值越低 无法处理的图像就越多 其中可能存在误报 这就可能导致 质量良好的图像被遗漏
有些不存在镜头污渍的图像 也可能具有较高的污渍分数
例如 这张图像因相机抖动 而导致模糊 这种情况与使用有污渍的镜头 拍摄的图像 非常相似 此外 对于长时间曝光拍摄的图像 或在云雾环境下 拍摄的图像也是如此 需要注意的是 照片的污渍分数较低 并不能保证它是一张高质量的照片 例如 这张通风口图像未被污渍污染 但它也不是一张我想与朋友们分享的 有趣或有吸引力的图像 Vision 还提供其他 API 可以与 DetectLensSmudgeRequest 搭配使用 以查找高质量照片
如果图像包含人脸 则可以使用 DetectFaceCaptureQualityRequest 来查找优质的人脸拍摄图像 这个请求会为每张人脸 生成一个拍摄质量分数
同样介于 0 和 1 之间 其中 1 表示拍摄质量较高
如果图像不包含人脸 则可以使用 CalculateImageAestheticScoresRequest 以获取图像的总分
这个请求还可识别实用图像 即拍摄质量良好 但内容缺乏视觉吸引力的照片 如文档或收据的图像 要进一步了解 CalculateImageAestheticScoresRequest 请观看 Vision 的 WWDC24 讲座
在结束前 我来简单介绍下 手势检测的更新
自 2020 年以来 开发者就能够使用 DetectHandPoseRequest 来识别手部 21 个关节的位置
关节位置将以手势观察结果返回
这项技术支持 ML 手势分类器 和手部动作分类器 以便你识别不同手势和手部动作
例如 你可以训练这些模型来识别 控制 App 功能的手势 要进一步了解如何训练手势分类器 请观看 WWDC21 讲座“使用 Create ML 将手势和动作分类”
今年 Vision 将手势检测模型更新为 更小、更现代化的模型
新模型仍能检测 21 个关节 但准确性有所提高 更省内存且延迟更低 虽然新模型的准确性有所提高 但检测的关节位置 与之前的模型并不相同 因此 如果你之前已经训练过 ML 手势分类器 或 ML 手部动作分类器 我们建议你使用新模型 重新训练分类器 以提高准确性
总结一下今年计划推出的新功能 我们将引入两项新的请求 RecognizeDocumentsRequest 可理解结构化文档 DetectCameraLensSmudgeRequest 可识别 带污渍镜头拍摄的照片 此外 我们还推出了更新的 手势检测模型
可以从 Apple 开发者网站 下载本视频中的示例 App 另外 要进一步了解 Vision 提供的更多 API 请记得观看 WWDC24 讲座 “探索 Vision 框架中的 Swift 增强功能” 感谢观看
-
-
6:39 - Detect tables
/// Process an image and return the first table detected func extractTable(from image: Data) async throws -> DocumentObservation.Container.Table { // The Vision request. let request = RecognizeDocumentsRequest() // Perform the request on the image data and return the results. let observations = try await request.perform(on: image) // Get the first observation from the array. guard let document = observations.first?.document else { throw AppError.noDocument } // Extract the first table detected. guard let table = document.tables.first else { throw AppError.noTable } return table }
-
10:50 - Parse contacts
/// Extract name, email addresses, and phone number from a table into a list of contacts. private func parseTable(_ table: DocumentObservation.Container.Table) -> [Contact] { var contacts = [Contact]() // Iterate over each row in the table. for row in table.rows { // The contact name will be taken from the first column. guard let firstCell = row.first else { continue } // Extract the text content from the transcript. let name = firstCell.content.text.transcript // Look for emails and phone numbers in the remaining cells. var detectedPhone: String? = nil var detectedEmail: String? = nil for cell in row.dropFirst() { // Get all detected data in the cell, then match emails and phone numbers. let allDetectedData = cell.content.text.detectedData for data in allDetectedData { switch data.match.details { case .emailAddress(let email): detectedEmail = email.emailAddress case .phoneNumber(let phoneNumber): detectedPhone = phoneNumber.phoneNumber default: break } } } // Create a contact if an email was detected. if let email = detectedEmail { let contact = Contact(name: name, email: email, phoneNumber: detectedPhone) contacts.append(contact) } } return contacts }
-
-
- 0:00 - 简介
Vision 框架提供了多种 API,用于将机器学习集成到各种 Apple 平台的 App 中。这些 API 支持人员和物体检测、位姿追踪以及轨迹分析等任务,所有这些任务均在设备端运行,可确保出色的性能和安全性。这一框架目前包含 31 个 API,其中有两个新增 API 分别用于实现文稿读取和相机镜头污迹检测,还有一个更新是针对手势检测。
- 1:22 - 读取文档
有一个名为“RecognizeDocumentsRequest”的新 API,它基于现有的“RecognizeTextRequest”功能构建,支持从文稿中提取结构化信息。 借助“RecognizeDocumentsRequest”,现在可以处理图像并获取文稿内容的层次结构。这个 API 可以检测各种元素,例如表格、列表、段落和二维码等机器可读代码。它不仅可以提取文本,还可以理解文本的格式,从而使解析和解释数据变得更加容易。 例如,现在有一张包含姓名、电子邮件地址和电话号码的注册表。以前,提取这些信息非常复杂,需要手动确定单元格关系。但使用“RecognizeDocumentsRequest”后,系统会自动解析表格并将单元格分组为行,从而简化基于扫描的工作表创建联系人的过程。
- 13:35 - 相机镜头污渍检测
Vision 中新增的相机镜头污迹检测功能“DetectLensSmudgeRequest”使用介于 0 到 1 之间的置信度分数来识别污迹图像。你可以设置阈值来过滤掉质量较差的图像,置信度越高表示越有可能是污迹图像。所设阈值较高,则处理的图像较多,但可能包括质量较低的图像;而所设阈值较低,则拒绝的图像较多,但可能包括质量较好的图像。 相机运动模糊、长时间曝光、云或雾等因素有时会导致误报。此外,Vision 还提供了其他 API 来评估图像质量,例如“DetectFaceCaptureQualityRequest”和“CalculateImageAestheticScoresRequest”。前者用于包含人脸的图像,后者用于不包含人脸的图像 (包括文稿或收据)。
- 17:59 - 手势更新
Vision 框架还包含一个经过更新的手势检测模型。原模型于 2020 年推出,可识别手部的 21 个关节,以便在 App 中进行手势识别。新模型更小、更快、更准确,但使用了不同的关节位置,因此需要重新训练现有的分类器。