大多数浏览器和
Developer App 均支持流媒体播放。
-
使用物体捕捉创建 3D 模型
物体捕捉提供了一种快速简便的方法,只需使用几张图片即可为真实世界对象创建逼真的 3D 模型。了解如何入门并使用 macOS 的摄影制图技术逼真地呈现资源。探究有关对象选择和图像捕捉的最佳实践,以帮助您获得最高质量的结果。
资源
- Capturing photographs for RealityKit Object Capture
- Creating 3D objects from photographs
- Creating a Photogrammetry Command-Line App
- Explore the RealityKit Developer Forums
- PhotogrammetrySample
- PhotogrammetrySession
- Taking Pictures for 3D Object Capture
相关视频
WWDC22
WWDC21
-
下载
♪低音音乐播放♪ ♪ 迈克尔帕特尔克约翰逊:嗨! 我是迈克尔帕特尔克约翰逊 我是物体捕捉团队的工程师 今天我和我同事戴夫麦金侬 要跟大家介绍如何在macOS上 用我们新的摄影测量法API 将实际存在的物体转换成3D模型 大家可能已经很熟悉 用我们的ARKit和RealityKit框架 来建立增强现实app 你可能也用过Reality Composer 和Reality Converter来制作 增强现实的3D模型 现在 大家可以很轻松地 用物体捕捉API 将实际存在物体的图像转换成 详细的3D模型 例如你面前有一些刚出炉的披萨 放在餐桌上 看起来很好吃 对吧? 假设我们想要捕捉前景的披萨 来做成3D模型 一般来说 你需要雇一位专家 花许多小时来建立形状和纹理的模型 不过等一下 现在你只要几分钟 就能自己做出来了! 通过物体捕捉 你先替你的物体 以各种角度拍照 接着 你把这些图像复制到 搭载支持物体捕捉API的Mac上 利用一种叫“摄影测量法”的 新计算机视觉技术 可以在几分钟内将一迭2D图像 转换成3D模型 输出的模型包含几何网格 和各式各样的材质贴图 而且可以直接把它拉到你的app中 或者从“AR快速查看”开启 现在让我们更仔细来看看 这每一个步骤 首先 从对象的每一侧拍摄照片 你可以用你的iPhone或iPad 数码单镜头反光相机 甚至是无人机来拍摄图像 只要能够从对象周围的每个角度 拍摄到清晰的照片就可以 我们待会会提供一些 拍摄照片的最佳实例 如果你是用iPhone或iPad来拍摄 我们可以从支持的装置中 利用立体深度数据 来还原真实的对象大小 以及重力矢量 所以会自动建立正面朝上的模型 一旦你拍下一系列的图像 你需要把它们复制到你的Mac 在Mac上你可以通过物体捕捉API 在几分钟内就把它们转换成3D模型 近期采用英特尔芯片的Mac机种 可以支持这个API 不过在所有搭载最新 Apple Silicon的Mac上运作得更快 因为我们使用了Apple神经网络引擎 来加速我们的计算机视觉算法 我们也提供HelloPhotogrammetry 一个范例命令行app来帮助大家开始 你也可以直接把它用到 你的图像文件夹上 在写入任何编码前 就帮自己建立模型 最后 你可以直接在你的Mac上 预览USDZ输出模型 我们针对不同的使用案例需求 提供四种精密度的模型 我们等一下会更详细地讨论这部分 压缩、中等和完整精密度都是安装后 能直接使用的 就像这里显示的披萨 原始图文件精密度用于自定义工作流程 通过选择中等精密度输出USDZ 你可以直接在iPhone或iPad上的 “AR快速查看”中 查看新的模型 要做出能用于增强现实中 优化的逼真对象 就是这样而已 喔 等等 还记得刚才的披萨吗? 我们应该要把话说清楚 那张图像并不真的是照片 而是在几个披萨上 利用物体捕捉建立出来的 接着在后制工具中 将这些样本 结合到场景里面 并且以有进阶材质贴图的 光线追踪进行渲染 大家可以看到 物体捕捉 支持各类的目标使用案例 从在iPhone或iPad上的增强现实app 到拍摄完成的生产资产上 在这一段剩下的时间里 我们会告诉大家怎么开始 使用物体捕捉API 接着会介绍能达到最佳质量结果的 最佳实例 在开始使用这部分 我们会讲到物体捕捉API的更多细节 以及介绍要建立一个app 最基本的编码概念 之后我们会讨论拍摄图像、对象选择 和精密度选择的最佳实例 让我们从在macOS上使用API的 基本步骤一步步开始进行 在这一段中 你们会学到 物体捕捉API的基本组件 和怎么把它们组合在一起 譬如说我们想把这双很酷的新球鞋 转换成3D模型 在增强现实中浏览 我们可以从这个图表中 看到我们在这段内容中 会探索的基本工作流程 这个过程有两个主要的步骤 设定 这里我们聚焦于 手上那组对象的图像 接着是处理过程 在这里我们会要求建构出 我们想要的模型 首先 我们先来看设定区块 它是由两个子步骤组成的 建立一个对话 然后连结到它相关的输出串流上 一旦我们有了有效的对话 就能用它来建立我们的模型 首先我们需要 建立一个PhotogrammetrySession 要建立一个对话 我们会假设你已经有一个 存放图像的文件夹 我们在API文档中有提供一些 拍摄的示例图像文件夹 让你可以快速地开始 PhotogrammetrySession是API中的 一个主要顶层类别 也是主要控制点 大家可以把对话想成一个容器 里面装着一组固定的图像 我们可以将摄影测量算法 套用在这组图像上来产出3D模型 这里我们有123张 用iPhone 12 Pro Max拍摄的 球鞋HEIC图像 目前有几种方法 可以指定要使用哪一组图像 最简单的方式是 通过图像目录的档案URL 对话会一个一个接收它们 并且在遇到问题时回报 如果在HEIC图像中有嵌入深度数据 就会自动被用来 回复物体的实际大小 尽管我们预期大多数人偏好 以文件夹输入 我们也有进阶的工作流程界面 来提供一连串的自定义样本 PhotogrammetrySample包含图像 和其他选择性数据 例如深度图 重力矢量 或其他自定义分割掩膜 一旦你从输入来源建立一个对话 你会从上面要求模型重建 对话会输出产生的模型 以及在输出信息串流上输出状态信息 现在我们知道对话是什么 让我们来看看如何用API 来建立一个对话 这里我们看到 从一个存放图像的文件夹 来执行对话的初始设定的编码 PhotogrammetrySession 是存放在RealityKit框架内 首先 我们将输入文件夹 指定为档案URL 这里 我们假设在本机磁盘中 已经有一个包含球鞋图像的文件夹 最后 我们通过传递URL 做为输入来源 来建立一个对话 万一路径不存在或无法读取 初始化程序就会丢出错误 你可以选择性提供 进阶组态参数 不过这里我们直接用预设值 这样就完成建立对话了! 既然我们成功建立了对话对象 我们需要连结到对话的输出串流 这样信息抵达时我们才能处理 在信息串流连结好之后 我们会看到如何请求 接下来会抵达串流的模型 我们会使用今年新的Swift性能 AsyncSequence 来提供输出的串流 输出信息包含请求的结果 还有状态信息 例如处理过程的更新 一旦我们调用第一个处理过程 信息就会开始流到输出信息串流上 当对话还活着 输出信息序列就不会终止 它会一直产生信息 直到对话被去初始化或者 出现致命错误 现在 让我们来看看 我们会收到的信息类型 送出请求后 我们预期会收到周期性的 requestProgress信息 以及针对每一个请求部分完成的评估 如果你在建立一个会调用 物体捕捉API的app 你可以靠这些驱动每个请求的进度条 来表示状态 一旦请求处理完成后 我们会收到一个 requestComplete信息 里面包含产生的负载 例如一个模型或是一个限界框 如果处理过程中出现什么问题 那个请求的输出 则会由requestError取代 方便起见 当所有队列请求 都处理完成后 就会输出 processingComplete信息 现在我们认识了 对话输出串流的概念 并且看过主要的输出信息 让我们来看一些处理信息串流的 范例编码 我们讲完后 大家就知道怎么请求模型了 这里是会建立异步任务 并在信息抵达时处理它们的编码 看起来这里有很多编码 不过大部分都只是信息分派 我们接下来会讲到 我们在session.outputs中 用“for try await”循环 在这些信息抵达时异步迭代它们 这一堆编码是信息分派器 它会将输出信息切换成开启 输出是一种带着不同信息类型 和负载的枚举 每个案例陈述会处理不同的信息 我们来解释一下这部分 首先 当我们得到一个处理过程信息 我们会直接印出那个值 注意到我们每个请求 都有处理过程信息 在我们的例子中 当请求完成时 我们预期结果负载为modelFile 以及模型储存位置的URL 我们等一下就会讲到怎么提出请求 如果请求因为摄影测量法错误而失败 我们则会收到关于它的错误信息 在来自处理过程调用的 整套请求都完成后 会产生一个 processingComplete信息 如果是命令行app 你可以在这里退出app 最后 在文档中还有其他状态信息 大家可以去看看 例如无法载入文件夹内 图像的警告 信息处理就讲到这里! 只要对话还活着 信息处理作业会一直 异步迭代和处理信息 好的 让我们来看一下现在我们在 工作流程的什么地方 我们已经讲完设定阶段 而且有一个已经可以使用的对话 现在我们准备好要提出 处理模型的请求了 在我们一头栽入编码前 我们先仔细看看 我们提出的各种请求类型 你可以从对话收到三种 不同的数据类型 ModelFile、ModelEntity 和BoundingBox 这些类型在请求枚举中 都有相关联的案例 modelFile、modelEntity和bounds 每个都带有不同的参数 modelFile请求是最常见的 也是我们要用在我们 基本工作流程中的请求 你只要指定一个有USDZ扩展 和精密度的档案URL 就可以建立modelFile请求 在使用互动式工作流程中 有一个选择性几何参数可以使用 不过我们在这里不会用到 对于更困难的后处理制作流程 你可能会需要用到USDA 或OBJ输出格式 你可以改成提供输出目录URL 还有精密度 接着 这个对话会将USDA和OBJ档案 和所有参考性资产 例如纹理和材质 写入那个文件夹中 GUI app也可以请求RealityKit ModelEntity和BoundingBox 来做互动式预览和精炼 modelEntity请求还会用到精密度 和选择性几何学 bounds请求会回传 估计的物体捕捉尺寸BoundingBox 这个框可以从用户界面调整 然后把几何论证传送给下一个请求 来调整重建体积 我们等一下会看到它是如何运作的 大部分的请求都需要精密度 预览精密度只是给 互动式工作流程使用 它是很低显示画质 但是建立的速度最快 将主要的精密度 按照画质和尺寸递增排列上去为 压缩、中等和完整 这些精密度都是可以直接使用的 此外 原始图档精密度 是提供个专业级使用 而且需要有后制工作流程 才能适当地使用它 我们在最佳实例那部分 会再说详细一点 好 现在大家已经看过 我们能做哪些请求 让我们来看看怎么从编码来做 我们现在会看到怎么在一个调用中 同时生成两个模型 各自以不同的文件名和精密度输出 这里是要在对话上处理的第一个调用 注意它是用请求的数组 这样我们可以一次请求两个模型 我们会以压缩精密度请求一个模型 以中等精密度请求另外一个 各自存到不同的USDZ档案中 在一个调用中 一次请求 物体捕捉想要使用的精密度 能让引擎分享计算 和依序请求它们比起来 同时请求能更快产出模型 你甚至可以一次要求所有的精密度 万一请求是无效的 像是无法读取输出位置 处理过程就会马上丢出一个错误 这个调用会立刻回传 而且信息会开始出现在输出串流上 基本工作流程到此为止! 你可以用自己的图像建立一个对话 连结到输出串流 然后要求模型 每个模型的处理时间会根据 图像数目和精密度有所不同 一旦处理完成 你会收到输出信息 模型已经做好了 你可以直接在你的Mac上 打开你建立的球鞋的USDZ档案 并且以3D方式、从各个角度检视它 包括底部 在后面的内容里 我们会讲到如何在一个捕捉对话中 覆盖到你的对象的所有面向 不必用好几个捕捉把它们结合在一起 它看起来很棒! 现在大家看过基本工作流程了 接着我们要来浏览 同样是物体捕捉API支持的 比较进阶的互动式工作流程 互动式工作流程的功能是 在最后重建前 先在预览模型上做一些调整 这样能减少在后制模型编辑上的需求 并且优化内存的使用 首先 注意看设定步骤 和处理过程步骤 在这个工作流程的两端都和之前一样 你还是要建立一个对话 然后连结到输出串流 跟之前一样 你也要请求最终模型 不过 注意看 我们在中间加上一个区块 里面有用来互动式编辑预览模型的 3D用户界面 这个步骤会重复到你满意预览为止 你可以跟之前一样 继续请求最终模型 你先在模型请求中指定为预览精密度 来请求预览模型 预览模型为低显示画质 并且会以最快的速度产出 你可以要求modelFile 再自己把它载入 或者直接请求RealityKit ModelEntity来显示 一般来说 也会同时提出bounds请求 来预览和编辑捕捉的体积 你可以调整捕捉的体积 来移除捕捉中任何不想要的几何 例如在捕捉过程用来 支撑对象直立的底座 你可以把根变换调整成缩放 平移和旋转模型 我们刚刚看到那个请求的几何属性 能在模型产生之前 先提供捕捉的体积和相对的根变换 这会输出一个已经可以使用的3D模型 让我们来看看这个过程 实际进行时的样子 这里我们看到一个互动式 物体捕捉app的范例 它是我们用API建立来示范 这个互动式工作流程的 首先 我们选择里面存有 这些装饰用石头图像的图像文件夹 以及一个输出文件夹 这是最终USDZ会写入的位置 接着我们点预览来要求预览模型 和预估的捕捉体积 经过一些时间后 石头的预览模型 和它的捕捉体积出现了 假设在输出中 我们只想要 石头的上半部 仿佛石头底部是在地下一样 你可以调整限界框 来避免重建模型的底部 一旦我们满意了 点下精炼模型 根据调整的捕捉体积来产生新的预览 同时也针对这部分来优化输出模型 一旦精炼的模型做好了 就会出现新的预览 你可以看到新模型的几何 是经过剪辑并且留在框内的 这对于移除捕捉中不想要的项目 很有用 例如支撑对象的底座 一旦我们满意裁切过的预览 我们可以选择完整精密度做最终渲染 开始建立模型的步骤 经过一些时间后 完整精密度模型完成了 并且取代预览模型 现在我们可以看到 实际模型的完整细节 这看起来很棒 模型会存在输出目录 而且不需要其他额外的后处理 就可以使用了 这些就是开始使用 新的物体捕捉API的内容 我们看到如何从输入来源 建立一个对话 例如存放图像的文件夹 我们看到如何连接异步的输出串流 来分派信息 接着我们看到如何同时请求 两种不同精密度的模型 最后 我们用ObjectCapture的 RealityKit GUI app范例 来介绍互动式工作流程 现在我要把时间交给我的同事 戴夫麦金侬 他会跟大家说物体捕捉的最佳实例 戴夫麦金侬:谢谢你 迈克尔 嗨 我是戴夫麦金侬 我是物体捕捉团队的工程师 在下一段内容中 我会介绍一些最佳实例 来帮大家取得最佳质量的结果 首先 我们会深入来看 选择具有适当特征的对象的技巧 和秘诀 然后会讨论如何控制 环境条件和相机 来得到最佳的结果 接着 我们会一步一步介绍 如何使用CaptureSample app 这个app能让你捕捉图像 还有深度数据和重力信息 来回复你的对象的真实大小和方向 我们会示范如何用这个app 进行手握捕捉 以及转盘捕捉 最后 我们会讲如何就你使用案例 选择适合的输出精密度 并且提供一些连结让大家可以 了解更多内容 在扫描对象时 首先要考虑的是 选择具有适当特征的对象 要得到最佳的结果 挑选具有足够纹理细节的对象 如果对象具有纹理不明显 或透明的区域 得到的扫描可能会缺少细节 除此之外 试着避开 具有高度反光区域的对象 如果对象会反光 用漫射光扫描 能让你得到最佳结果 如果你打算在捕捉过程中翻转对象 确保它够坚硬 形状才不会改变 最后 如果你想要扫描 表面细节很精细的对象 你必须使用高分辨率相机 并且拍摄许多表面的特写照片 来回复这些细节 我们现在要示范典型的扫描过程 要得到最佳的结果 首先 将你的对象放到干净的背景下 这样对象才能从背景凸显出来 基本步骤包含在对象周围缓慢地移动 确认你有均匀地捕捉到对象的每一面 如果你想要重建对象的底部 把它翻过来并且继续捕捉图像 在拍摄图像的时候 尽量以最大的视野 来捕捉对象 这样能帮助API回复更多的细节 其中一个方法是 根据对象的维度和方向 来使用人像或风景模式 还有 在图像之间 尽可能保留高度的重复 根据对象的状况 可能需要 20到200张特写来得到够好的结果 要帮各位开始在iOS上 捕捉具有深度和重力的高画质相片 我们提供了CaptureSample app 这可以当成你自己的app的起始点 它是用SwiftUI写的 而且它是开发者文档的一部分 这个app示范了如何拍摄 能在物体捕捉中使用的高画质照片 它有手动和定时快门模式 你也可以修改app来和你的转盘同步 它示范如何使用有双镜头的 iPhone和iPad 来捕捉深度数据 并且直接将它嵌入输出的HEIC档案中 这个app也告诉你怎么储存重力数据 你可以在你的图库中快速地确认 你取得所有高画质的照片 以及深度和重力 并且删除没拍好的照片 捕捉文件夹是存在app的 文档文件夹中 你可以利用iCloud和隔空投送 轻易地把那里的档案复制到你的Mac 也有求助屏幕 上面概括了 一些我们这段讨论过的 最佳实例的指导方针 让你能有好的物体捕捉 你也可以在开发者文档中 找到这些信息 我们会建议使用转盘捕捉 尽可能取得最好的结果 要开始使用转盘捕捉 你需要像我们这里这样设置安排 包含一台用来捕捉的iOS装置 不过你也可以使用 数码单镜头反光相机 一台机械式转盘来旋转对象 一个摄影棚 还要一些打光板 目的是要有均匀的光线 避免产生任何硬阴影 很适合使用摄影棚来做这件事 在这个案例中 CaptureSample app 利用和转盘运动同步的定时快门模式 来捕捉图像 我们也可以翻转对象 以及让转盘转很多圈 来捕捉物体的所有面向 这里是在macOS的预览中显示 从转盘捕捉得到的USDZ档案 既然我们已经讲完捕捉图像的 技巧和秘诀 让我们进入最后一部分 如何选择适当的输出 有很多种不同的精密度设定 可以用在扫描上 让我们来看看 这张表上面显示了精密度 支持的精密度显示在左手边 压缩和中等精密度适合 基于网页的和移动的体验 例如在“增强现实快速查看”中 浏览3D内容 它们有比较少的三角形序列 和材质通道 所以消耗比较少的内存 完整和原始图档精密度 是用于高端互动性使用 例如电脑游戏或后制工作流程 它们具有较高的几何细节 并且让你能灵活地在 烘焙和未烘焙材质间做选择 压缩和中等精密度适合用在 想要在网页或移动设备上呈现的内容 在这个例子中 物体捕捉会将 原始图文件结果中的几何和材质信息 压缩成适合在增强现实app中 或是在“增强现实快速查看”上 呈现的程度 在压缩和中等精密度中 都有漫反射、正常和环境光遮蔽的 物理基础渲染的材质通道 如果你想要以高度细节呈现单一扫描 中等精密度会针对档案大小 将画质最大化 来给你更多几何和材质细节 不过 如果你想在同一个场景中 呈现很多张扫描 你应该要设定为压缩精密度 如果你想更了解如何使用物体捕捉 来建立移动和网页增强现实体验 请去看《增强现实快速查看 遇见物体捕捉》的课程 以完整精密度来输出 是很适合专业工作流程的选择 在这个例子中 你会得到 扫描的最高精密度 完整精密度会优化扫描的几何 并且将细节烘焙成物理基础渲染材质 包含漫反射、正常、环境光遮蔽 粗糙度和位移信息 我们认为这个输出的精密度能提供你 最困难的渲染所需要的全部内容 最后 如果你不需要材质烘焙 或者你有自己的管道可以取得 原始图档精密度会回传 最大多边形面数 以及最大漫反射材质细节 来做更进一步的处理 如果你想更了解如何在macOS上 操作用于专业工作流程的物体捕捉 请看课程《以USD建立3D工作流程》 最后 也是最重要的 如果你打算在iOS和macOS上 都使用你的扫描 你可以选择多个精密度 确保不论在目前和未来使用案例中 你都有合适的输出 我们讲完了 让我们回顾一下我们学到了什么 首先 我们用范例来介绍 物体捕捉API背后的概念 我们示范了如何建立物体捕捉对话 以及如何用这个对话 处理一整组图像 来建立一个3D模型 我们介绍了一个API 如何支持交互式预览应用程序 让你可以调整捕捉体积 和模型变换的例子 接下来 我们介绍了扫描的最佳实例 我们讨论了该使用哪一种对象 以及什么样的环境、光线和相机设定 才能取得最佳的结果 最后 我们讨论了如何选择 适合你应用程序的输出精密度设定 如果你想知道如何将物体捕捉 带到你自己的app中 请先去看看iOS捕捉 和macOS命令行界面处理app 以开始使用 这些app中包含各种范例数据 里面有最佳实例 当你打算捕捉自己的扫描时 这些都很有用 除此之外 请大家去看 在developer.apple.com上 关于最佳实例的详细文档 含有这些相关的WWDC内容 接下来你唯一要做的事 就是开始使用物体捕捉进行扫描了 我们很期待看到大家会 扫描和分享什么对象 ♪
-
-
6:56 - Creating a PhotogrammetrySession with a folder of images
import RealityKit let inputFolderUrl = URL(fileURLWithPath: "/tmp/Sneakers/", isDirectory: true) let session = try! PhotogrammetrySession(input: inputFolderUrl, configuration: PhotogrammetrySession.Configuration())
-
9:26 - Creating the async message stream dispatcher
// Create an async message stream dispatcher task Task { do { for try await output in session.outputs { switch output { case .requestProgress(let request, let fraction): print("Request progress: \(fraction)") case .requestComplete(let request, let result): if case .modelFile(let url) = result { print("Request result output at \(url).") } case .requestError(let request, let error): print("Error: \(request) error=\(error)") case .processingComplete: print("Completed!") handleComplete() default: // Or handle other messages... break } } } catch { print("Fatal session error! \(error)") } }
-
13:44 - Calling process on two models simultaneously
try! session.process(requests: [ .modelFile("/tmp/Outputs/model-reduced.usdz", detail: .reduced), .modelFile("/tmp/Outputs/model-medium.usdz", detail: .medium) ])
-
-
正在查找特定内容?在上方输入一个主题,就能直接跳转到相应的精彩内容。
提交你查询的内容时出现错误。请检查互联网连接,然后再试一次。