大多数浏览器和
Developer App 均支持流媒体播放。
-
探索 Vision 框架中的 Swift 增强功能
Vision Framework API 经过重新设计,旨在利用并发等现代 Swift 功能,更轻松快速地将各种 Vision 算法整合到你的 App 中。我们将一起了解更新后的 API,并分享示例代码以及推荐做法,帮你在精简编程工作的同时仍能充分发挥该框架的优势。我们还将展示两项新功能:图像美学和整体身体姿势。
章节
- 0:00 - Introduction
- 1:07 - New Vision API
- 1:47 - Get started with Vision
- 8:59 - Optimize with Swift Concurrency
- 11:05 - Update an existing Vision app
- 13:46 - What’s new in Vision?
资源
相关视频
WWDC23
-
下载
大家好 我叫 Megan Williams 来自 Vision 框架团队 Vision 是一个提供 计算机视觉 API 的框架 开发者可使用这些 API 来打造出色的 App 和体验 下面我将介绍可通过 Vision 框架实现的部分功能 Vision 可检测人脸和人脸特征点 例如眼睛、鼻子和嘴巴
Vision 框架可识别 18 种不同语言的文字 其中包括韩语、瑞典语和中文
对于健康和健身应用程序 Vision 可追踪身体 位姿和运动轨迹
Vision 还有一个手势追踪功能 可实现一种无需触摸屏幕 即可与 Apple 设备 进行交互的全新方式 这些只是众多功能当中的少数几例 全球数以千计的开发者 已使用 Vision 构建出优秀的 App 今年 你可以更轻松地 将计算机视觉技术引入你的 App 我们很高兴宣布推出一个 与以往一样强大的新 API 它现在已针对 Swift 简化了语法 同时 我们还将全面支持 Swift 并发和 Swift 6 从而帮助你编写出 性能极佳的 App 在这个视频的余下部分 我们将 介绍如何开始使用新的 Swift API 然后 我们会演示如何利用 Swift 并发来优化你的 App 接着 我们会讲解如何更新 现有的 Vision 应用程序 以使用新的 API 最后 我们会介绍今年 为 Vision 推出的部分新功能 让我们开始吧 在 Vision 中 一切从请求开始 你可将 Vision 请求想象为 我们针对图像询问的问题 比如“这张图像中的 人脸位于何处?” “这张收据上的总额是多少?” 或“这张图像的主题是什么?” 我们可使用 DetectFaceRectangleRequest 询问这些问题来查找人脸 用 RecognizeTextRequest 来理解文本 以及用 GenerateObjectnessBasedSaliencyImageRequest 来查找图像中的显著物体
询问一些问题后 我们还想得到一些答案 Vision 能以观察结果的形式 为这些问题提供答案 这些观察结果是通过执行请求生成的
DetectFaceRectanglesRequest 可生成 FaceObservations 从而告知我们人脸的位置 RecognizedTextObservation 可帮助理解文本 SaliencyImageObservation 可帮助突出显示 图像中的重要元素
这些只是众多功能当中的少数几个 Vision 提供了 31 个不同的请求 每个请求都代表一种图像分析类型 本视频无法一一介绍这么多请求 我想着重介绍几个我最喜欢的 Vision 提供了针对 常见计算机视觉任务的请求 这类任务包括图像分类 和文本识别等 Vision 可检测并识别 图像中的各种物体 比如条形码 人物 和动物 此外还有针对 2D 或 3D 身体位姿估计的 API Vision 还可检测移动物体 并分多帧对它们进行追踪
了解了什么是请求后 我们来看看它们在代码中 所呈现的示例 我想构建一个杂货店应用程序 为了在杂货店内浏览各种产品 我希望能扫描它们的条形码 为此我可使用 DetectBarcodesRequest
现在 我们来扫描 这张图像中的条形码 首先 我会创建请求 然后 对这张图像执行这个请求
这项操作会生成 barcodeObservations 在这张图像中检测到的每个 条形码都会对应一项“观察结果”
这个请求可能会失败 于是我需要添加 try 语句
这里还有一项重要说明 新的 API 为异步 API 因此 App 必须等待它们完成运行 这样就可以了 只需 3 行代码 我们就能检测到条形码 我们刚刚只举了一个例子 实际上所有 Vision 请求 都遵循同一通用结构
检测到某一条形码后 我便可从条形码的有效负载中 获取产品信息 我可使用这行代码来扫描条形码 此外 我还想知道这个条形码 在图像中的位置 这样我就能为用户突出显示它 通过 .boundingBox 属性 我可获取这个条形码的位置 需要注意的是 Vision 观察结果具有 归一化到图像的坐标
在 Vision 系统中 坐标 会归一化为介于 0 到 1 的值 且原点位于左下角 这可能与你熟悉的 其他框架有所不同 比如 SwiftUI 这个框架会将原点置于左上角 但不用担心 今年我们会 提供一个新 API 用于帮助执行不同坐标系 之间的转换 要从 Vision 的 归一化坐标转换回 原始图像的坐标 我可以调用 toImageCoordinates() 并传入图像的大小 此外 我还可指定坐标原点应位于 图像的左上角还是左下角 我将使用 upperLeft
这将为我们提供 原始坐标空间中的边界框 以作为原点位于左上角时的图像 现在 我们已经知道条形码 在原始图像中的位置 并为用户突出显示它们
现在我有了一个 可扫描是否存在条形码的 App 我可以进行一些优化 来进一步完善这个 App 很多请求都附带可配置的属性 对它们进行微调就能提升性能 DetectBarcodesRequest() 可默认扫描是否存在 多种不同类型的条形码 由于我要构建一个杂货店应用程序 我可改为仅扫描是否存在 杂货店中常见的条形码
我会设置这个请求的 symbologies 属性以便仅扫描是否存在 .ean13 这比扫描是否存在所有条形码类型 更为高效 同时还可 提升 App 的性能
介绍完 API 的基本用法后 我们再重点介绍一些 针对杂货店应用程序的 高级用例 我们可扫描图像是否存在条形码 但商品没有条形码时该怎么办? 这种情况下 我会通过 标签上的文字来识别商品 为此 我需要执行第二个请求 在本例中 我会使用 RecognizeTextRequest()
我会像之前一样创建请求
我可以逐个执行请求 但为了获得最佳性能 Vision 建议同时执行所有请求 为此 我需要使用 ImageRequestHandler
你可将 ImageRequestHandler 想象为图像的容器 我会使用这个处理程序来执行请求 这个处理程序会 为每个请求返回一个结果
现在 我可扫描图像 是否存在条形码 同时识别所有文字标签
需要注意的是 这个 perform 调用 会使用参数包语法 这种语法允许执行任意数量的请求 使用这种方法时还有一件事需要注意 那就是 我们必须等待所有请求都完成 才能使用它们的结果
这对某些应用程序来说或许还好 但在我们的杂货店应用程序中 如果 DetectBarcodesRequest 检测到条形码 我们不想等到 RecognizeTextRequest 完成后才扫描这个条形码 Vision 提供了一个名为 performAll 的备用 API 它可用于同时执行多个请求 并在每个请求完成后 立即处理相应的结果 performAll 会以 流的形式返回结果 也就是说当某一请求完成时 它的结果会立即返回 而其他请求则仍在运行
要访问观察结果 我需要等待来自流中的结果
这样我就能在 条形码观察结果可用时 立即使用它们 而无需等待 RecognizeTextRequest 完成
介绍完这些基础知识后 我们聊聊如何使用 Swift 并发 来优化 Vision API 很多时候 应用程序 可能需要处理多个图像 这些图像可在 for 循环中 逐个处理 但为了实现最佳性能 我们可使用并发功能
这样我们就能批量获取图像 并同时处理它们
假设有一个照片图库 里面有很多图像 我想在网格视图中显示这些图像 但它们的大小各不相同 首先 我需要将图像裁剪为正方形 这样做是为了裁剪为 图像的主要拍摄对象 我会使用 GenerateObjectnessBasedSaliencyImageRequest 来识别图像中主要拍摄对象的位置 并在它的周围进行裁剪
我会编写一个函数 generateThumbnail 它会在图像的显著部分 周围进行裁剪 然后 我会使用 for 循环 来迭代照片图库中的图像 并为每个图像生成缩略图 我一次只能处理一个图像 因此速度可能会较慢 为此 我可使用并发功能来提速
我会改用 TaskGroup 借助 TaskGroup 我可创建多个任务 来并行执行请求 我需要对这段代码再进行一次调整
Vision 请求可能会 占用大量内存 因此 建议你限制同时执行的 Vision 请求的数量 以减少 App 占用的内存 在本例中 我将任务数量 限制为 5 个
当某一任务完成时 我会添加另一个任务来 开始处理下一个图像 这样便可保证一次 处理的请求不超过 5 个 我已选择为我的应用程序 将任务数限制为 5 个 但你可能会发现其他限值 对你的应用程序更有效
现在 我会演示如何将 应用程序更新到新的 API 旧版 Swift API 并未停用 但为充分利用 Swift 6 和 Swift 并发 强烈建议在应用程序中 采用新的 API 在开始之前 还有一点需要注意 为减少内存占用 对于配备神经网络引擎的设备 Vision 将不再对某些请求 提供 CPU 与 GPU 支持
在这类设备上 神经网络引擎 是性能最高的一个选项
通过使用 supportedComputeDevices() API 你可随时检查某一请求 支持哪些计算设备
现在 我们来深入了解一下如何 更新现有的 Vision 应用程序 以使用新的 API 更新过程只需三步即可完成
首先 我们需要采用新的 请求类型与观察结果类型 旧 API 中的大多数请求 在新 API 中都有直接的对等项
要获取新的请求类型 或观察结果类型 需要从 Vision 类型名称中 移除 VN 前缀
接下来 Vision 已去除 面向请求的完成处理程序 并将它替换为 async/await 语法
最后 由请求生成的观察结果 会直接从 perform() 调用返回 现在 我们来更新部分代码 这段代码使用旧版 Vision API 来检测图像中的条形码
通过移除 VN 前缀 我会更新 VNDetectBarcodesRequest 来使用新的请求
在旧 API 中 我们已在 完成处理程序中处理相关结果 现在 结果会直接从 perform() 返回 于是我会移除完成处理程序
此时 我会为 perform() 调用 采用 async/await 语法
为了使用这个异步 API 我还需要将函数设为异步
我们不会从完成处理程序 获取条形码观察结果 观察结果现在会直接从 perform() 调用返回 此外 你可能还发现 我已无须再解包可选值 最后 由于我只是执行一个请求 因此实际上并不需要 imageRequestHandler 于是 我会将它移除以简化代码
这样就可以了
通过采用新 API 代码行数已从 10 行减少为只有 6 行 简化后的语法也非常好用 最后 Vision 今年提供了两项新功能 Vision 还将推出一个新请求 名为 CalculateImageAestheticsScoresRequest 这个请求可用于评估图像质量 和查找令人难忘的照片
我们可通过分析多种因素 来确定图像质量 比如模糊和曝光 这个质量将以赋给图像的 总分来表示
此外 这个请求还可识别实用图像 这类图像可能会有用 但并不怎么令人难忘 比如收据的截屏或照片 我们来看几个示例
这张美丽的风景图像 具有较高的分数 它不但拍摄精良 曝光恰到好处 场景也令人记忆深刻
这张图像的对焦不太清晰 它似乎是无意间拍摄的 因此分数较低
从技术角度来看 这张木箱图像拍得很好 但它未必是你想与朋友 分享的一张令人难忘的照片 这就是所谓的“实用图像” 要使用新的 API 只需使用 CalculateImageAestheticsScoresRequest 这个请求会生成 ImageAestheticsScoresObservation 它的总分范围介于 -1 到 1 表示图像拍摄的精良程度 这个观察结果还有另一个属性 即 isUtility 对于拍摄精良但内容 并不令人印象深刻的照片 这个属性的值为 true
此外 今年 Vision 还有 一个新增功能 即整体身体位姿
先前在 Vision 中 身体姿势和手部姿势检测 对应不同的请求
借助整体身体位姿 你可同时检测手部和身体
要使用整体身体位姿 需创建 DetectHumanBodyPoseRequest
将请求的 detectsHands 设为 true
这个请求会生成一个 HumanBodyPoseObservation 它现在多了两个属性 一个用于右手观察结果 另一个用于左手观察结果 刚才介绍了很多新功能 现在我来总结一下 通过支持并发和 Swift 6 我们的新 Swift API 在 Swift 生态系统中运行良好 这使得在 Swift 应用 程序中采用 Vision
会变得轻松很多 因此 Vision 后续只会在 Swift 中引入新功能 现有的 API 不会停用 但我们强烈建议采用新的 API 新的图像美学和整体身体位姿 API 可用于为你的应用程序添加新功能
谢谢观看! 我已迫不及待地想看到你用 Vision 创建的所有出色 App
-
-
正在查找特定内容?在上方输入一个主题,就能直接跳转到相应的精彩内容。
提交你查询的内容时出现错误。请检查互联网连接,然后再试一次。