鸿蒙开发-AR画面数据怎么流转?ARFrame数据详解
AR 帧数据怎么获取和使用AREngine_ARFrame 详解上一篇文章聊了 ARSession 在空间建模中的角色这篇文章来看看更具体的东西——ARFrame也就是 AR Engine 每一帧采集到的数据。AREngine_ARFrame 是什么AREngine_ARFrame是 AR Engine 中存储单帧 AR 数据的结构体。和 ARSession 一样它也是一个不透明句柄你不能直接访问它的内部字段。typedefstructAREngine_ARFrameAREngine_ARFrame;文档里对它的描述是“定义一个结构体用于存储 AR Engine 中捕获的单帧 AR 图像数据包含特定时间戳下的相机图像、追踪状态、锚点及 AR 相关信息。”拆开来看一帧 AR 数据包含了这些信息相机图像当前帧的画面就是摄像头看到的内容追踪状态AR Engine 对相机位置的追踪是否正常锚点在物理空间中固定的参考点用来稳定虚拟内容时间戳这一帧被采集的时间其他 AR 信息比如检测到的平面、特征点等从 ARSession 获取 ARFrame下面是 ARFrame 数据的完整流转过程AR 自身用途空间建模AR Engine 采集摄像头图像图像预处理去畸变、色彩校正特征提取检测角点和边缘姿态估计计算相机位置和旋转地图更新加入新特征点封装为 ARFrame 数据数据去向渲染虚拟物体、检测平面调用 PushARFrame 推入建模系统空间建模提取图像和姿态构建 3D 模型ARFrame 不是你自己创建的而是从 ARSession 里获取的。AR Engine 每一帧都会更新 ARSession 的内部状态你通过 AR Engine 的 API 来获取当前帧的 ARFrame。获取到 ARFrame 之后你可以做两件事用 AR Engine 自己的 API 来处理比如渲染虚拟物体、检测平面等通过 PushARFrame 把它推给空间建模系统对于空间建模场景你需要在每一帧的更新循环中获取 ARFrame然后推入空间建模会话。PushARFrame 的完整流程把 ARFrame 推入空间建模的流程是这样的HMS_SpatialReconStatusHMS_SpatialRecon_PushARFrame(HMS_SpatialRecon_Session*spatialReconSession,AREngine_ARSession*arSession,AREngine_ARFrame*arFrame);三个参数之间的关系spatialReconSession告诉空间建模系统我要给你送数据了arSession告诉空间建模系统这些数据来自哪个 AR 会话arFrame具体的一帧数据你可以把 arSession 理解为信封上的寄件人地址arFrame 理解为信封里的信。空间建模系统需要同时知道寄件人和信的内容才能正确处理。ARFrame 里对空间建模最有用的信息虽然 ARFrame 是个不透明句柄你不能直接读它的字段但空间建模系统在内部会使用这些信息相机图像这是最核心的数据——空间建模需要原始的图像像素来构建 3D 模型。AR Engine 获取的图像已经经过了预处理去畸变、色彩校正等质量比自己直接从摄像头获取的要好。相机姿态AR Engine 的 SLAM 追踪会给出每一帧相机在 3D 空间中的精确位置和旋转。空间建模系统需要这些信息来确定每张图像是从哪个角度拍摄的这样才能正确地把多张图像拼成一个 3D 模型。如果你用 PushFrame 手动推帧这些姿态数据需要你自己提供。用 PushARFrame 的话AR Engine 已经帮你算好了。特征点AR Engine 在追踪过程中会检测图像中的特征点比如角点、纹理丰富的区域。这些特征点不仅帮助 AR Engine 自己做追踪也能帮助空间建模系统理解场景的几何结构。时间戳每帧都有精确的时间戳空间建模系统用它来排序帧和计算帧间运动。ARFrame 的质量对建模的影响ARFrame 的质量直接决定了空间建模的效果。以下是几个影响质量的因素追踪状态如果 AR Engine 的追踪丢失了Lost说明它无法确定相机的位置。这种情况下推入的 ARFrame 缺少可靠的姿态数据会严重影响建模质量。建议的做法是在推帧之前检查追踪状态如果追踪丢失就跳过这一帧。宁可少推几帧质量好的数据也不要推一堆姿态不准的垃圾数据。运动模糊如果用户移动手机太快图像会出现运动模糊。模糊的图像对空间建模来说几乎没用——特征点检测不出来纹理信息也丢失了。你可以在 UI 上提示用户请缓慢移动手机或者通过分析连续帧之间的图像质量来自动过滤掉模糊帧。光线条件太暗或者太亮的环境都会影响图像质量。AR Engine 在低光环境下的追踪精度也会下降。如果用户的扫描环境光线不好可以在 UI 上给出提示。扫描角度空间建模需要从多个角度拍摄同一个物体/场景。如果用户只从一个方向扫建出来的模型会有很多盲区。你可以在 UI 上引导用户从不同角度扫描比如请从左侧扫一下、“请从上方扫一下”。什么时候停止推帧推帧的质量控制和停止判断流程丢失正常运动模糊光线太暗/太亮质量良好扫描时间足够达到最大帧数覆盖率足够否获取当前帧 ARFrame检查追踪状态追踪正常?跳过本帧图像质量如何?跳过本帧跳过本帧调用 PushARFrame 推帧是否达到停止条件?停止推帧继续下一帧调用 StartSession 启动重建推帧不是越多越好。有几个停止的时机扫描时间够了一般来说扫描一个中等大小的房间需要 30 秒到 2 分钟。扫描一个小型物体可能只需要 10-20 秒帧数达到上限系统有最大帧数限制推够了就不能再推了PushARFrame 会返回SPATIAL_RECON_STATUS_EXCEEDS_MAXIMUM覆盖足够了如果你实现了覆盖率检测当场景的各个角度都被扫描到之后就可以停止停止推帧后调用 StartSession 启动重建就行。ARFrame 和 DataFrame 的关系你可能注意到了ARFrame 和前面讲的 DataFrame 有很多相似之处——都有图像数据、相机参数、时间戳。其实它们本质上是同一类东西只是来源不同DataFrame你自己构造的需要手动填充所有字段ARFrameAR Engine 自动生成的你只需要获取和传递空间建模系统内部会把 ARFrame 转换成统一的格式来处理。所以不管你是用 PushFrame 还是 PushARFrame最终的效果是一样的——只是数据来源和便利程度不同。ARFrame 内部的数据流虽然 ARFrame 是个不透明句柄你不能直接读它的字段但了解一下它内部的数据流转过程对你理解空间建模的工作原理很有帮助。当 AR Engine 采集到一帧图像后会依次做这些处理图像预处理对原始摄像头数据做去畸变、色彩校正等操作得到干净的图像特征提取在图像中检测特征点角点、边缘等这些特征点是追踪的基础姿态估计通过匹配当前帧和上一帧的特征点计算相机的运动得出新的位置和旋转地图更新把新的特征点加入到环境地图中同时优化已有的地图点这些处理的结果都封装在 ARFrame 里。当你调用 PushARFrame 的时候空间建模系统会从 ARFrame 中提取需要的信息主要是图像和姿态然后用这些信息来构建 3D 模型。所以你看ARFrame 不只是一帧图像那么简单——它包含了 AR Engine 对这一帧的全部理解和分析结果。用 PushFrame 还是 PushARFrame一个实际的决策场景举一个具体的例子来帮你做选择。假设你要做一个房产看房APP有两种场景场景一实时扫描。用户到了一个新房子里拿着手机在房间里走一圈APP 实时构建房间的 3D 模型。这种场景用 PushARFrame 最合适——AR Engine 负责追踪和采集空间建模负责重建用户只需要走就行。场景二从视频重建。你有一个之前拍摄的房间视频文件想从这个视频重建 3D 模型。这种场景只能用 PushFrame——你需要自己逐帧读取视频提取每一帧的图像数据然后手动构造 DataFrame。相机姿态可能需要用一些离线的 SLAM 工具来计算或者如果视频是用稳定的支架拍的可以用一个简单的线性插值来估算。大多数 APP 都是场景一所以 PushARFrame 是最常用的。但知道 PushFrame 的存在也很重要它给了你更多的灵活性。实际开发中的建议优先用 PushARFrame除非你有特殊需求比如从离线视频重建否则直接用 AR Engine 的数据最省事注意帧率不需要每一帧都推给空间建模。如果 AR Engine 的帧率是 30fps你可以每 2-3 帧推一次既能保证覆盖度又不会推太多重复数据监控追踪质量追踪质量差的帧不要推会影响建模效果给用户足够的引导扫描过程中在 UI 上提示用户怎么移动手机、什么时候可以停止AREngine_ARFrame 是连接 AR Engine 和空间建模的数据载体。理解它的作用和质量影响因素能帮你做出更好的空间扫描 APP。