大多数浏览器和
Developer App 均支持流媒体播放。
-
在 Vision 中探索 3D 人体位姿和人像分隔
了解如何使用 Vision 构建以人像为中心的的功能。了解如何检测人体位姿并测量 3D 空间中的各个关节位置。我们还将向你展示如何利用人像分隔 API 来区分和分隔图片上的人像,最多可处理四个人。 要了解有关 Vision 最新功能的更多信息,请观看 WWDC23 课程“在 Vision 中检测动物位姿”。
资源
相关视频
WWDC23
WWDC22
WWDC20
-
下载
♪ ♪
Andrew:大家好 我是 Andrew Rauh 是 Vision framework 的软件工程师 今天 我将介绍人体位姿、 Vision 框架中的景深应用 以及如何使用 instance Mask 将人像从图片中提取出来
检测并理解人一直都是 Vision 关注的重点 Vision 框架也在几年前 提供了 2D 人体位姿 简单回顾一下 2D 人体位姿 会回传一个 observation 使用标准化像素坐标标出标志点 定义出一个 与输入与图片对应的骨架 若要了解更多具体信息 并且还没有观看过讲座 “检测身体和手部姿势” 可前往观看 Vision 将从环境中捕捉人像的支持 拓展至 3D 层面 使用的是一个新请求 名为 VNDetectHumanBodyPose3DRequest 这个请求会生成一个 observation 返回一个有 17 个关节的 3D 骨架 可以使用关节名称 或关节组合名称 来访问单个或一组关节 Vision 返回的其他识别点 统一以左下角为坐标原点 但 3D 关节返回的 位置不同 返回的是 拍下来的真实世界所对应的尺寸 以根关节为原点 最初版本只返回一个骨架 对应画面中检测到的最显眼的人像 如果你在开发的是一款健身 App 对这张在健身房拍摄的健身课照片 执行这个请求时 observation 的对象 即为中间的女性 她距离摄像头最近 为了更好地展示 3D 骨架的结构及其使用场景 来详细了解一下这个瑜伽姿势 毫无疑问 3D 人体骨架 从头部组合开始 包含头部中心和顶部的坐标点 接下来是躯干组合 包括左右肩膀关节、脊柱、根关节 也就是髋部正中的点 以及髋关节 请注意 部分关节 可能会分为多个组返回 比如手臂 分为左臂组和右臂组 各包含一个腕关节、 肩关节和肘关节 左右是指人的左右 而不是图片的左右 最后 骨架中还有左腿组和右腿组 各对应一个的髋关节、 膝关节和踝关节 使用这一请求的工作流 与其他请求一致 因此开发者如果在代码中使用过 Vision 那应该对这个请求的流程很熟悉 首先 需要创建一个实例 使用新的 DetectHumanBodyPose3DRequest 然后 初始化图片请求处理程序 使用你想要执行检测的资源 要执行你的请求 需要把请求实例 传递给 perform 请求成功的话 会返回一个没有错误消息的 VNHumanBodyPose3DObservation 照片是 3D 世界里 人的 2D 载体 Vision 现在可以让你 从照片中提取出 3D 位置 并且无需使用 ARKit 或 ARSession 这一轻量级选项功能强大 可帮助了解 3D 空间内的主体 并且为 App 开启一系列全新的功能 我做了一个 App 示例 以便更直观地帮助大家理解 打开 App 后 可以从图库里任选一张
我和我的同事们先前 从瑜伽教练身上的平静获得了灵感 所以我们休息了一下 出门自己尝试了几个姿势 我虽然不像教练那么灵活 但我这个姿势做得很好 做成 3D 后效果应该也很不错
我们来执行一下这个请求 将我重新变回三维
请求成功 生成的 3D 骨架 与我在所输入图片中的位置一致 当我旋转场景时 我的手臂伸长 根据我的站立姿势 双腿和髋部的相对位置也是正确的 这个金字塔形状代表的是 照下这张照片时的摄像头位置 轻点 Switch Perspective 按钮后 当前视图就是摄像头位置的正视图 我会给大家讲解 需要了解的代码和概念 从而让大家能使用 3D 人体位姿 为 App 打造美妙的用户体验
开发 App 的第一步是 使用 observation 返回的点 用来获取点位的 API 主要有两个: recognizedPoint 用来访问特定关节的位置 recognizedPoints 用来 访问特定组合名下的关节集合 除核心方法外 observation 还会提供 一些额外的有用信息 首先是 bodyHeight 以米为单位 估算主体高度 根据可用的景深元数据 这一高度 可能是测量后更精确的值 也可能是 1.8 米的参考高度 稍后我将介绍 关于景深和 Vision 的更多内容 开发者可以使用 heightEstimation 属性 来确定用于计算处理高度的技术 其次 可以通过 cameraOriginMatrix 得出摄像头位置 由于在现实生活中 摄像头可能不是正对着拍摄主体的 这一 API 就可以用来获取当时 镜头相对于 拍摄画面上的人物的位置 observation 还提供了一条 可将关节坐标点投射回 2D 的 API 如果你要用输入图片覆盖返回的点 或与之对齐 这条 API 会很有帮助 最后 为了解人物在两张相似照片 之间的动作变化 可以使用这一 API 来获取已知关节 相对于摄像头的位置
在展示 3D 人体点位的应用方法前 我想先介绍 Vision 继承的 新的几何分类 VNPoint3D 是定义 simd_float 4 x 4 矩阵的基类 用以存储 3D 位置 这种呈现与 ARKit 等 其他 Apple 框架一致 也包含全部可用的旋转和平移信息 接下来是 VNRecognizedPoint3D 在继承这一位置的同时 额外添加了一个标识符 用来存储关节名称等对应信息 最后是今天的重点 VNHumanBodyRecognizedPoint3D 它新增了 localPosition 和 parentJoint 两项 我们来深入了解一下 利用点位属性的一些细节 使用 recognizedPoint API 后 我得到了左腕的位置 关节的模板位置或一个点的位置属性 始终是相对于骨架的根关节 即髋部中心点来说的 如果我们重点关注 位置矩阵中的第三列 可以看到这些是平移值 左腕在 y 轴上的值是 人像髋部上方 0.9 米 对于这个姿势来说 应该是正确的 接下来是返回点的 localPosition 属性 也就是相对于父关节的位置 在这种情况下 左手肘就是左腕的父关节 最后一列显示 x 轴数值为 -0.1 米 看上去也是正确的 数值的正负是由参考点位置决定的 在这个姿势里 手腕在手肘左侧 若 App 只处理身体的一个部位 localPosition 会十分有帮助 它也可以更简单地确定出 子关节和父关节之间的角度 我现在就来展示怎样 用代码计算这一角度 处理返回的 3D 点时 有几条概念可能会 对开发 App 有所帮助 第一 开发者可能经常需要确定 子关节和父关节之间的角度 使用 calculateLocalAngleToParent 可以通过与父关节的 相对位置找到这一角度 节点的旋转是围绕 x、y 和 z 三轴的旋转 或者说是倾斜、偏航和旋转 先说倾斜 90° 旋转是用来定位 SceneKit 节点几何 从朝正下方的默认位置 变为更适合骨架的位置 而对于偏航 我们用的是 z 坐标的反余弦 除以向量长度 得出适宜的角度 对于旋转 通过 y 和 x 坐标的反正切 测量出角度 接下来 你的 App 需要 将返回的 3D 位置 与原图关联起来 正如我的示例 App 一样 在我的可视化中 我用了 pointInImage API 达成对我的图片平面的两方面变换 即比例和平移 首先 我需要按返回点的比例 缩放图片平面 取两个已知关节间的距离 比如肩关节中心和脊柱 3D 和 2D 距离都获取到后 将它们按比例关联起来 并据此缩放图片 对于平移组件 我用了 pointInImage API 来获取 2D 图片中的根关节位置 这一方法是用根关节位置来确定 图片平面 在 x 轴和 y 轴上的位移 同时完成坐标原点 在左下角 VNPoint 坐标 和图片中心的 渲染环境原点间的切换 最后 你可能想要 从摄像头视角查看图片 或根据摄像头点位渲染图像 可使用 cameraOriginMatrix 来获取该结果 正确的方向取决于你的渲染环境 不过 这是我定位节点的方法 利用 PivotTransform 获取转换信息 将节点在本地坐标系中的位置 和其余场景关联起来 我还使用了 cameraOriginMatrix 里的旋转信息 以便正确将我的图片平面 旋转至面向摄像头的方向 此处的代码使用了逆变换
这里只需要旋转信息 所以 最后一列的平移信息可忽略 把所有部分组合起来后 就完成了我示例 App 中所展示的场景 现在 我想花些时间来介绍几个 精彩的附加项 包括 Vision 中的景深 Vision 框架现在将景深作为一个 与图片或帧缓存一起的输入项 VNImageRequestHandler 添加了初始化 API 启动能够为 AVDepthData 接收新参数的 cvPixelBuffer 和 cmSampleBuffer 此外 若你的文件中已包含景深数据 那可以直接使用现有 API 无需修改 Vision 会帮你 自动从文件中获取景深 在 Apple SDK 中使用景深时 AVDepthData 将作为连接 所有景深元数据的容器类 摄像头传感器拍摄到的景深元数据 包含用视差 或深度格式表示的深度图 这些格式可以互换 可以使用 AVFoundation 相互转换 景深元数据还包括摄像头校准数据 如内参、外参和镜头畸变等 重新构筑 3D 场景所需的数据 如需进一步了解详细信息 请观看 2022 年的讲座 “发现 iOS 摄像头捕捉的改进” 摄像头捕捉会话可以获取景深 先前捕捉的文件中也可能包含景深 使用相机 App 拍下的图片 如照片中的人像 始终将景深存储为 带有摄像头校准元数据的视差图 在实时捕捉会话中捕捉景深时 如果设备支持的话 可以使用附加功能 指定会话使用激光雷达 激光雷达的功能很强大 因为它 对场景的比例和测量十分精确 Vision 还引入了 可与一张图片内的多人 进行交互的 API
目前 Vision 可以 将人和周围场景分隔开 使用的请求是 GeneratePersonSegmentation 这个请求会返回一个 包含画面上所有人的蒙版 而现在 Vision 增加了更多选择 可使用新的 PersonInstanceMaskRequest 这个新的 API 最多可输出 四个独立人像蒙版 每个对应单独的置信度 这样 你就能从图片中 分别选择并提取出朋友们了 如果你想选择提取非人的其他主体 可以使用 VisionKit 中的 主体提取 API 或使用 Vision 框架中的 ForegroundInstanceMask 请求 请观看讲座 “在 App 内提取图片上的主体” 获取更多信息 这里的示例代码展示了如何 从图片中选取 你想要的特定人像实例 目前的设置是要返回所有实例 但你可以自主选择 实例 1 或实例 2 这取决于你想要关注的 是图片上的哪个朋友 也可以选择实例 0 来获取背景 这一新请求最多可分隔四人 所以 若图片含四个人以上 在代码里就需要处理一些附加条件 在多人场景下 返回的 observation 可能会遗漏或合并人像 通常 只有在背景有人的时候 才会发生这种情况 如果你的 App 必须处理 多人场景的话 可以使用一些策略来 尽可能保证最佳体验 使用 Vision 中的面部识别 API 可算出图片上的人脸数量 也可以选择跳过四人以上的图片 或使用现有的人像分隔请求 将所有人放进一个蒙版里
来总结一下 Vision 目前 提供了功能强大的新方法 用于了解人及所处环境 这得益于景深、 3D 人体位姿 和人像实例蒙版的支持 但这些并不是今年 Vision 推出的全部功能 你可以创造出更美妙的体验 不止局限于人像 也可以通过“在 Vision 中检测动物姿态” 会话来处理毛绒朋友们的图片 感谢你的观看 希望能尽快看到 你打造的更多不可思议的功能 ♪ ♪
-
-
正在查找特定内容?在上方输入一个主题,就能直接跳转到相应的精彩内容。
提交你查询的内容时出现错误。请检查互联网连接,然后再试一次。