大多数浏览器和
Developer App 均支持流媒体播放。
-
使用 Vision 检测人物、面孔和姿势
了解 Vision 框架的最新更新,帮助您的 app 检测人物、面孔和姿势。了解 Person Segmentation API,它可以帮助您的 app 将图像中的人与周围环境区分开来,并探索用于跟踪俯仰、哈欠和头部转动的最新连续指标。还会了解如何将这些功能与 Core Image 等其他 API 结合使用,以在图像编辑 app 中提供从简单的虚拟背景到丰富的离线合成等各种内容。为了能充分了解本节内容,我们建议观看 WWDC20 中的“使用 Vision 检测身体和手部姿势”和 WWDC19 中的“理解 Vision 框架中的图像”。要了解有关人物分析的更多信息,请参阅 WWDC20 中的“使用 Vision 检测身体和手部姿势”和 WWDC19 中的“理解 Vision 框架中的图像”。
资源
相关视频
WWDC22
WWDC21
WWDC20
WWDC19
-
下载
♪重低音音乐声♪ ♪ 谢尔盖卡曼斯基:大家好 欢迎来到WWDC 我是谢尔盖卡曼斯基 我是Vision框架团队的 软件工程师 今天这场专题讲座的主题是 展示Vision框架 如何协助进行人像分析 今天的议程包含两大项目 首先我们会综述 Vision框架中的人像分析技术 在此同时 我们会特别聚焦于新添加的部分 第二 我们会深入评论 新的人像分割功能 我们先来谈谈人像分析技术 Vision中人像分析的基石 是人脸分析 自从Vision框架成形后 我们一直在添加和加强 人脸分析功能 我们目前提供人脸检测 人脸特征点检测和人脸拍摄质量检测 Vision框架中的人脸检测功能 通过DetectFaceRectanglesRequest 公开 我们的人脸检测器提供高精准度 和召回指标 它能找到不同方向 不同大小 还有部分遮蔽的人脸 目前我们支持的遮蔽 包含眼镜和帽子 现在我们让人脸检测器升级到 修订版本三 在这版本中 除了改进所有既有的极好特性外 现在也能检测被口罩挡住的脸 我们的人脸检测器的主要功能 当然是找到人脸的边界框 但它也可检测人脸姿态指标 之前我们只提供翻滚角和偏航角指标 大部分指标都用弧度报告 它们的值以离散的箱返回 推出新的修订版本后 我们也添加了俯仰角指标 让它变得完整 但我们不只做到这样 我们也让三个指标 全都在连续空间中报告 所有人脸姿态指标 都作为FaceObservation对象的属性 返回 那是执行 DetectFaceRectanglesRequest的结果 我们来看这个演示应用程序 它专为展示 人脸姿态检测功能设计 这个应用程序通过运行 Vision人脸检测器 处理摄像头画面 并在将结果从弧度转换成角度后 向用户呈现人脸姿态指标 为了更好地跟踪指标变化 应用程序用红色渐变显示 往正向增加的人脸姿态指标 蓝色渐变表示 往负向增加的指标 两者都是颜色越浅 指标越接近零的位置 每个指标零的位置就是所谓 人头的中立位置 当一个人直直往前看 像这样 如同前面提过的 我们有三个人脸姿态指标 翻滚角 偏航角 俯仰角 这些词汇来自飞行动力学 用来形容飞行器的主轴 和飞行器重心的关系 同样的词汇被用来形容 人头姿势 当应用于头部姿势 或者我们也会称为人脸姿态 它们跟踪的人头运动如下 翻滚角跟踪这个方向的头部运动 当我从翻滚角的最负值 移动到最正值 可以看到背景颜色 从深蓝变成浅蓝 中立 然后浅红 最后变深红 类似的颜色变化也出现在偏航角指标 它跟踪的角度是 头往右或往左转时 最后 俯仰角指标跟踪我的头部 上下点头的动作 这里可以再次看到类似的颜色变化 当我从最负值 移到范围中的最正值 人脸特征点检测 是另一个人脸分析套件的 重要功能 人脸特征点检测的提供是通过 DetectFaceLandmarksRequest 最新的修订是修订版本三 此修订版本提供76特征点群 能更好地代表主要脸部区域 也提供准确的瞳孔检测 人脸分析套件 也包含人脸拍摄质量检测 这个整体的测量考虑到 各种特性 像是表情、光线 遮蔽、模糊、聚焦等 它通过DetectFaceCaptureQuality Request API公开 这个请求的最新修订版本 是修订版本二 有一点很重要 人脸拍摄质量 是对于同样的对象的比较测量 这个功能很适合像是 选出连拍中的最佳照片 或是选出照片库中 最能代表一个人的照片 这项功能并不是设计来比较 不同人的脸 Vision框架提供的人像分析技术 另一大区块是人体分析 Vision在这个领域中提供多个功能 包含人体检测 人体姿势检测 还有同等重要的 人手姿势检测 我们先看人体检测 这个功能的提供是通过 DetectHumanRectanglesRequest 它目前只能检测人体上身 我们将添加新功能到这个请求 因此将此修订版本升级成修订版本二 新的修订版本中 除了上身检测 我们也提供全身检测 选择上身检测 或是全身检测 是由 DetectHumanRectanglesRequest的 新的upperBodyOnly属性控制 这个属性的默认值设置为true 以维持向下兼容性 Vision框架中的人体姿势检测 通过DetectHumanBodyPoseRequest 提供 处理这个请求能提供 一系列人体关节位置 修订版本一是这个请求最新的 也是唯一一个可用的修订版本 Vision框架也提供人手姿势检测 DetectHumanHandPoseRequest 类似人体姿势检测 处理手部姿势请求 会返回一系列人手关节位置 我们会升级这个请求的功能 通过添加一个重要属性到观测结果 手部手性属性 HumanHandPoseObservation的 新的手性属性 会包含关于 检测的手是左手还是右手的信息 若想了解更多 手部姿势检测的细节 建议观看 《使用Create ML 分类手势及手部动作》专题讲座 以上就是人像分析技术套件 新升级的综述 现在要进入专题讲座的第二个主题 就是人像分割 什么是人像分割? 以大白话来说 它是将人从场景分离出来的能力 现今人像分割技术用于 无数个应用 例如大家都熟悉的 视频会议应用程序的虚拟背景功能 它也用于运动直播分析 自动车 和更多地方 人像分割也驱动我们著名的人像模式 Vision框架中的人像分割 这个功能设计用于单一帧 你可以把它用在串流管道 它也适合用在脱机处理 这个功能在多个平台上都支持 像是MacOS、iOS、iPadOS和tvOS Vision框架实现语义人像分割 意思是它会为帧中的所有人 返回单一的蒙板
人像分割的Vision API 是通过 GeneratePersonSegmentation Request实现 这是一个有状态的请求 与Vision框架中的传统请求相反 有状态的请求对象 会在帧的整个序列中 重复使用 以我们的案例来说 使用请求对象 可以帮忙缓和快速质量水平模型中 帧与帧之间的暂时变化 我们来看Vision框架提供的 人像分割API 这个API遵循大家熟悉 且已确立的模式 创建一个请求 创建一个请求处理程序 用请求处理程序处理你的请求 最后 检查结果 GeneratePersonSegmentation Request对象的 默认初始化 等同将修订版本、质量水平 和输出像素格式属性设为默认值 我们来一个个检视所有属性 第一个是修订版本属性 这里我们将修订版本设置为 修订版本一 这是默认且唯一可用的修订版本 因为我们要处理新的请求类型 虽然技术上来说今天也没得选 我们总是建议明确地设定 以保证在未来有确定性行为 这是因为如果之后推出新的修订版本 默认值也会改变 以反映最新可用的修订版本 第二个是质量水平属性 Vision API提供三个不同水平: 准确 也就是默认水平 平衡 以及快速 以不同用例来说 我们建议 计算摄影用准确水平 在这种用例中 你想要达到 最高可能质量 而且通常没有时间的限制 类似的逻辑 平衡水平建议用于 视频的逐帧分割 快速水平则用于串流处理 第三个属性是输出蒙板格式 我们会详细解说产生的蒙板 但我想先在这提 作为客户 你可以指定 产生的蒙板会以什么格式返回 你有三个选择:无符号8位整数蒙板 典型的0到255范围 还有两种浮点蒙板格式 一个是32位全精度 另一个是16位半精度 16位半精度目的是提供你一种 减少内存的浮点格式 可以直接插入 Metal的进一步的基于GPU的处理 目前我们学了如何创建 配置 和执行我们的人像分割请求 现在是时候来看结果 处理人像分割请求的结果 以PixelBufferObservation对象的 形式呈现 PixelBufferObservation来自观测 它添加一个重要的像素缓冲属性 存储在这个属性中的 实际那个CVPixelBuffer对象 和我们的人像分割请求配置 有同样的像素格式 处理人像分割请求 会产生一个分割蒙板 我们看看原始图像 还有通过执行人像分割请求 三个不同质量水平的蒙板 快速 平衡 以及准确 我们放大检视每个蒙板的细节 跟预期一样 当我们从快速换成平衡 最后换成准确 蒙板的质量上升 我们开始看到越来越多细节 现在让我们检视不同的蒙板水平 质量和表现之间的关系 当我们从快速换到平衡 最终换成准确 蒙板的质量上升 但资源用量也上升 当蒙板质量上升 动态范围、蒙板分辨率 内存消耗、处理时间都会增加 这代表分割蒙板的质量 和运算蒙板所消耗的资源 两者会相互影响 你已经知道蒙板的生成 和它的属性的一切 蒙板究竟可以拿来做什么? 我们先从三个图像开始 输入图像 通过处理输入图像获得的 分割蒙板 和背景图像 我们想做的是取代原始图像中的背景 范围是蒙板区域外面 要用不同图像的背景取代 当你执行这种混合操作 结果是原始图像中的年轻人 从海边漫步被传送到森林中 这个混合序列的代码长什么样子? 我们先推定已经完成所有相关处理 已经有三个图像 输入图像 蒙板 背景 现在我们需要调整蒙板和背景的大小 以符合原始图像的大小 然后我们会创建并初始化 Core Image混合筛选器 你可能注意到我用红色蒙板 创建我的混合筛选器 这是因为当CIImage 用一组件的PixelBuffer初始化… 我们所有蒙板都是… 默认情况下它会用红色通道创建对象 最后 我们执行混合操作以获得结果 我们看看可以如何用Vision框架中的 人像分割功能 第二个演示应用程序 你可以下载它 它结合人脸姿态指标检测 和新的人像分割功能 这个应用程序通过运行人脸检测 和人像分割 处理摄像头画面 然后用分割蒙板 将蒙板像素以外区域的背景 取代成不同颜色 要用什么背景颜色 取决于翻滚角、偏航角和俯仰角 在任何时点的 综合值 目前我人在有一张桌子 和几张椅子的房间 而演示应用程序显示我的分割轮廓 配上新背景 新背景是 和我的头部位置相对应的颜色 来看看它是否跟踪翻滚角 偏航角 和俯仰角的变化 我这样转头时 翻滚角是 决定背景颜色的主要因素 我的头向左向右转时 偏航角变成主要因素 最后 上下点头 让俯仰角成为主要因素 不只Vision框架 提供人像分割API 还有几个其他框架也提供 由同样技术驱动的类似功能 我们简单看一下每一个 首先是AVFoundation AVFoundation在较新一代的设备中 拍摄照片时 可以返回一个人像分割蒙板 分割蒙板通过 AVCapturePhoto的 PortraitEffectsMatte属性返回 为了取得它 你必须先检查 是否支持 如果支持 记得要启用交付 第二个提供人像分割API的框架 是ARKit A12 Bionic之后的设备 都支持这个功能 而且是在处理摄像头画面时生成 分割蒙板通过 ARFrame的segmentationBuffer 属性返回 在试图取回它之前 你必须先检查是否支持 方式是检视ARWorldTracking Configuration类的 supportsFrameSemantics属性 第三个框架是Core Image Core Image提供一个薄包装 包在Vision人像分割API上面 所以你可以在Core Image的域里面 执行整个用例 我们现在看看人像分割 如何用Core Image API实现 我们会先登录一个图像 以对它执行分割 然后我们会创建 一个人像分割CIFilter 分配一个输入图像给它 并执行筛选器以取得分割蒙板 我们刚刚检视了多个版本的 人像分割API和Apple SDK 让我们做个总结 看看每一个可以用在哪里 AVFoundation可用AVCaptureSession 用于某些iOS设备 如果你有个捕获会话在运行 你应该选择这个 如果你要开发ARKit应用程序 你应该已经有个AR会话 你可以从那里取得分割蒙板 此例中 ARKit API是建议使用的方式 Vision API在多个平台上可用 可用于联机和脱机单帧处理 最后 Core Image提供 包围Vision API的薄包装 如果你想待在Core Image的域中 这是很方便的选项 跟任何算法一样 人像分割 有它的最佳实践 换句话说 有它效果最好的一组条件 如果你计划使用人像分割功能 若能尽量遵守以下规则 你的应用程序表现会更好 首先 最多应只分割场景中的四个人 所有人的身体都应大部分可见 虽然可能有一些自然遮蔽 第二 每个人的身高 至少应该是图像高度的一半 且最好和背景有良好对比 第三 我们也建议你避免多义性 像是雕像 人像照片 距离远的人 以上就是本专题讲座内容 我们快速回顾一下今天学了什么 首先 我们综述了 Vision框架中的人像分析技术 同时聚焦于升级功能 像是戴口罩的人脸检测 添加人脸俯仰角指标 和让所有的人脸姿态指标 在连续空间中报告 我们也在人类手部姿势检测中 推出了新的手部手性指标 在第二部分 我们深入探讨 新添加到Vision框架的人像分割API 我们也看了其他提供类似功能的API 并指导每一个可以用在哪里 我很希望你在观看这场专题讲座后 学到了开发应用程序的新工具 并且很想要马上试用它们 在结束今天的讲座前 我想感谢你的收看 祝你好运 并有美好的WWDC ♪
-
-
8:13 - Get segmentation mask from an image
// Create request let request = VNGeneratePersonSegmentationRequest() // Create request handler let requestHandler = VNImageRequestHandler(url: imageURL, options: options) // Process request try requestHandler.perform([request]) // Review results let mask = request.results!.first! let maskBuffer = mask.pixelBuffer
-
8:33 - Configuring the segmentation request
let request = VNGeneratePersonSegmentationRequest() request.revision = VNGeneratePersonSegmentationRequestRevision1 request.qualityLevel = VNGeneratePersonSegmentationRequest.QualityLevel.accurate request.outputPixelFormat = kCVPixelFormatType_OneComponent8
-
12:24 - Applying a segmentation mask
let input = CIImage?(contentsOf: imageUrl)! let mask = CIImage(cvPixelBuffer: maskBuffer) let background = CIImage?(contentsOf: backgroundImageUrl)! let maskScaleX = input.extent.width / mask.extent.width let maskScaleY = input.extent.height / mask.extent.height let maskScaled = mask.transformed(by: __CGAffineTransformMake( maskScaleX, 0, 0, maskScaleY, 0, 0)) let backgroundScaleX = input.extent.width / background.extent.width let backgroundScaleY = input.extent.height / background.extent.height let backgroundScaled = background.transformed(by: __CGAffineTransformMake( backgroundScaleX, 0, 0, backgroundScaleY, 0, 0)) let blendFilter = CIFilter.blendWithRedMask() blendFilter.inputImage = input blendFilter.backgroundImage = backgroundScaled blendFilter.maskImage = maskScaled let blendedImage = blendFilter.outputImage
-
14:37 - Segmentation from AVCapture
private let photoOutput = AVCapturePhotoOutput() … if self.photoOutput.isPortraitEffectsMatteDeliverySupported { self.photoOutput.isPortraitEffectsMatteDeliveryEnabled = true } open class AVCapturePhoto { … var portraitEffectsMatte: AVPortraitEffectsMatte? { get } // nil if no people in the scene … }
-
14:58 - Segmentation in ARKit
if ARWorldTrackingConfiguration.supportsFrameSemantics(.personSegmentationWithDepth) { // Proceed with getting Person Segmentation Mask … } open class ARFrame { … var segmentationBuffer: CVPixelBuffer? { get } … }
-
15:31 - Segmentation in CoreImage
let input = CIImage?(contentsOf: imageUrl)! let segmentationFilter = CIFilter.personSegmentation() segmentationFilter.inputImage = input let mask = segmentationFilter.outputImage
-
-
正在查找特定内容?在上方输入一个主题,就能直接跳转到相应的精彩内容。
提交你查询的内容时出现错误。请检查互联网连接,然后再试一次。