ARCore之路-技术原理(二)

版权声明:David Wang原创ARCore文章,仅供学习研究之用,不得用于任何商业目的,未经授权不得转载! https://blog.csdn.net/yolon3000/article/details/81545114

  前文说过,ARCore 使用三个主要功能将虚拟内容与通过手机摄像头看到的现实世界整合:运动跟踪、
环境理解、光估计。那么我们就来详细说一下这三个方面的原理,然后一并学习一下ARCore带来的新概念。

一、运动跟踪

这里写图片描述

  在2D和3D空间中跟踪用户的运动并最终定位它们的位置是任何AR应用程序的基础,当我们的移动设备在现实世界中移动时,ARCore 会通过一个名为并行测距与映射(Concurrent Odometry and Mapping ,COM)的过程来理解手机相对于周围世界的位置。 ARCore 会检测捕获的摄像头图像中的视觉差异特征(称为特征点),并使用这些点来计算其位置变化。 这些视觉信息将与设备 IMU 的惯性测量结果结合,一起用于估测摄像头随着时间推移而相对于周围世界的姿态(位置和方向)。如上图所示,在图中,我们可以看到用户的位置是如何与真实沙发上识别的特征点相关联的,以前为了成功跟踪运动(位置),我们需要预先训练我们的特征点,有了ARCore,它个实时的自动为我们做这些,这种跟踪技术是非常新的,当然,它也有它的不足,后面我们会谈到。
  在开发中,通过将渲染 3D 内容的虚拟摄像头的姿态与 ARCore 提供的设备摄像头的姿态对齐,开发者能够从正确的透视角度渲染虚拟内容,渲染的虚拟图像可以叠加到从设备摄像头获取的图像上,让虚拟内容看起来就像现实世界的一部分一样。

二、环境理解

这里写图片描述

  ARCore 会通过检测特征点和平面来不断改进它对现实世界环境的理解。ARCore 可以查找看起来位于常见水平或垂直表面(例如桌子或墙)上的成簇特征点,并让这些表面可以用作应用程序的平面, ARCore 也可以确定每个平面的边界,并将该信息提供给应用,使用此信息将可以将虚拟物体置于平坦的表面上。由于 ARCore 使用特征点来检测平面,因此可能无法正确检测像白墙一样没有纹理的平坦表面,这一点是由算法的底层设计决定的,除非附加其它算法,否则这个问题不可解。在后续的文章中我们将详细讨论环境理解的细节,看一下下面这张图:
这里写图片描述

  在上面的图像中我们看到的是一个通过网格识别的真实世界表面,这个平面是由白点标识,在场景中,我们可以看到用户是如何将各种虚拟物体放置在表面上的。环境理解和啮合对于创建AR视觉表现来说是必不可少的。

三、光估计

这里写图片描述

  ARCore 可以检测其环境光线的相关信息,并提供给定摄像头图像的平均光强度和色彩校正,利用这些光照信息,我们可以使用与周围环境相同的光照来照亮您的虚拟物体,提升虚拟物体的真实感。在上图中,处于强光中的猫与处于阴影中的猫的颜色保持了与真实场景中光照的一致。利用ARCore,还可以用来估计光源的位置和光照方向,这样,可以让虚拟物体产生与真实光照一样的阴影效果,进一步提升虚拟物体的真实性。

四、其它概念

  用户交互
  ARCore 利用命中测试来获取对应于手机屏幕的 (x,y) 坐标(通过点按或应用支持的任何其他交互提供),并将一条射线投影到摄像头的视野中,返回这条射线贯穿的任何平面或特征点以及交叉位置在现实世界空间中的姿态。 这让用户可以选择环境中的物体或者与它们互动。

  定向点
  借助定向点,可以将虚拟物体置于倾斜的表面上。当执行会返回特征点的命中测试时,ARCore 将查看附近的特征点并使用这些特征点估算表面在给定特征点处的角度,然后,ARCore 会返回一个将该角度考虑在内的姿态。由于 ARCore 使用成簇特征点来检测表面的角度,因此可能无法正确检测像白墙一样没有纹理的表面。

  锚点和可跟踪对象
  姿态会随着 ARCore 改进它对自身位置和环境的理解而变化,当我们要放置一个虚拟物体时,需要定义一个锚点来确保 ARCore 可以跟踪物体随时间推移的位置,很多时候,需要基于命中测试返回的姿态创建一个锚点,以此来绑定虚拟物体与真实环境的位置关系。姿态会发生变化,这就意味着 ARCore 可能会更新平面和特征点等环境物体随时间推移的位置。 平面和特征点是一种特殊类型的物体,称为可跟踪对象,顾名思义,ARCore 可以随着时间推移跟踪这些物体。 我们可以将虚拟物体锚定到特定的可跟踪对象,确保虚拟物体与可跟踪对象之间的关系即使在设备移动时也能保持稳定。 这意味着,如果将一个虚拟的 Android 小雕像放在书桌上,即使 ARCore 稍后调整了与书桌关联的平面的姿态,Android 小雕像仍会看起来位于桌子上。注:为了减少 CPU 开销,请尽可能重用锚点并在不再需要时分离锚点。
  锚点描述了在现实世界中一个固定的位置和方向。为了保持在物理空间的固定位置,这个位置的数值描述将会随着ARCore对空间的理解的改进而更新。使用getPose()获取这个Anchor的当前数值位置,这个位置每次update()被调用的时候都可能改变,但不会自发地改变。

  增强图像
  使用增强图像可以构建能够响应特定 2D 图像(如产品包装或电影海报)的 AR 应用, 用户可以在将手机的摄像头对准特定图像时触发 AR 体验,例如,他们可以将手机的摄像头对准电影海报,使人物弹出,然后引发一个场景。可离线编译图像以创建图像数据库,也可以从设备实时添加单独的图像。 注册后,ARCore 将检测这些图像、图像边界,然后返回相应的姿态。

  共享
  借助 ARCore 的 Cloud Anchors API,您可以创建适用于 Android 和 iOS 设备的协作性或多人游戏应用。使用云锚点,一台设备可以将锚点和附近的特征点发送到云端进行托管。 可以将这些锚点与同一环境中 Android 或 iOS 设备上的其他用户共享。 这使应用可以渲染连接到这些锚点的相同 3D 对象,从而让用户能够同步拥有相同的 AR 体验。由于国内网络环境问题,我们可能无法使用Cloud Anchors。

  帧(com.google.ar.core.Frame)
  Frame最直观的理解是照相机获取的一帧图像,背景渲染的画面就来自摄像头获取图像帧。在ARCore中,Frame还包含更丰富的内容,还提供了某一个时刻AR的状态。这些状态包括:当前帧中环境的光线,如在绘制内容的时候根据光线控制物体绘制的颜色,使得更真实;当前Frame中检测到的特征点云和它的Pose用来绘制点云;当前Frame中包含的Anchor和检测到的Plane集合用于绘制内容和平面;手机设备当前的Pose、帧获取的时间戳、AR跟踪状态和摄像头的视图矩阵等。

  特征点云(com.google.ar.core.PointCloud)
  ARCore在检测平面的时候,显示的一个个小白点,就是特征点云。特征点云包含了被观察到的3D点和信心值的集合,还有它被ARCore检测时的时间戳。

  二维平面(com.google.ar.core.Plane)
  ARCore中所有的内容,都要依托于平面类进行渲染。如演示中的Android机器人,只有在检测到网格的地方才能放置。ARCore中平面可分为水平朝上、朝下、垂直和非水平平面类型,Plane描述了对一个真实世界二维平面的认知,如平面的中心点、平面的x和z轴方向长度,组成平面多边形的顶点。检测到的平面还分为三种状态,分别是正在跟踪,可恢复跟踪和永不恢复跟踪。如果是没有正在跟踪的平面,包含的平面信息可能不准确。两个或者多个平面还会被被自动合并成一个父平面。如果这种情况发生,可以通过子平面找到它的父平面。

  交集(com.google.ar.core.HitResult/PlaneHitResult/PointCloudHitResult)
  点击平面的时候,从设备点击处朝手机面向方向发出一条射线,和被检测平面的是否有交集。抽象的概括,HitResult就是射线和真实世界几何体的交集。我们可以中获取当前设备到有交集几何体的距离,交集的Pose,如果是平面交集就是PlaneHitResult,如果是点云就是PoinCludHitResult,PlaneHitResult中可以判断交集点是否在被检测的集合范围内,是否在平面的正面。

  空间位置(com.google.ar.core.Pose)
  Pose表示从一个坐标系到另一个坐标系的转换。在所有的ARCore APIs中,Pose总是描述从物体的局部坐标系到世界坐标系的变换,也就是说,来自ARCore API的Pose可以被认为等同于OpenGL的模型矩阵或DirectX的世界矩阵。随着ARCore对环境的了解不断变化,它将调整坐标系模式以便与真实世界保持一致。 这时,Camera和锚点的位置(坐标)可能会发生明显的变化,以便它们所代表的物体处理恰当的位置。因此,每一帧图像都应被认为是在一个完全独立的世界坐标空间中。锚点和Camera的坐标不应该在渲染帧之外的地方使用,如果需考虑到某个位置超出单个渲染框架的范围,则应该创建一个锚点或者应该使用相对于附近现有锚点的位置。

  空间光线(com.google.ar.core.LightEstimate)
  LightEstimate给我们提供了一个接口来查询当前帧的光环境。我们可以获取当前相机视图的像素强度,一个范围在(0.0,1.0)的值,0代表黑色,1代表白色。使用该光线属性绘制内容,可以使虚拟物体更真实。

  会话(com.google.ar.core.Session)
  Session是ARCore中重要的功能是管理AR系统的状态,处理Session生命周期,是ARCore API的主要入口。在开始使用ARCore API的时候,通过设置的Config来检查当前设备是否支持ARCore。在Activity中对应的生命周期方法中需要处理Session的生命周期,这样AR系统会根据需要开始和暂停相机帧的采集,初始化和释放相关的资源。
  Session是ARCore API的一个类com.google.ar.core.Session。它管理了AR系统的状态,有自己的生命周期,开始和停止访问摄像头图像帧的获取。Session管理AR系统的全部状态,包含跟踪的Anchor信息、通过session.add(Pose)和session.removeAnchor(anchors)保存和删除。session.getAllPlanes()返回被检测到的平面、当前投影矩阵等。当ARCore App退至后台,Activity调用onPause()方法时,也需要通过session.pause()暂停Session,来停止摄像机的图像获取,在App呈现在前台的时候,onResume()方法中调用session.resume(Config)可以重新启用Session,获取摄像机图像等。可以通过调用session.update()方法来获取最新的相机帧,更新设备的位置,更新被跟踪的Anchor信息,更新被检查的平面。在AR系统在每一帧画面的渲染过程中,我们从Session中获取当前相机反馈的Frame,根据需要保存、获取和删除Anchor,获取系统检测到的所有Plane,设置纵横缩放比,获取投影矩阵(渲染3d效果)等用于渲染相关工作。

  配置(com.google.ar.core.Config)
  在当前市面上,并不是所有的Android设备都支持ARCore。那么这时候我们就要用到Config,它保存了用于配置Session相关设置。我们可以针对是否开启平面检测和光线感知,获取帧时没有新图片是否阻塞等几个选项创建Config。默认Config开启平面检测和光线感知,获取帧时没有新图片阻塞。 在使用ARCore之前,使用创建的Config,检查当前设备是否支持ARCore,是一个比较好的做法。配置文件主要包括:光线评估子系统的行为Config.LightingMode,包含开启或者禁止光线评估;平面检测子系统的行为Config.PlaneFindingMode,包含开启和禁止平面检测;update()的行为Config.UpdateMode。在大多数设备中,摄像头被配置每秒捕捉30帧。当调用update()从摄像机获取帧的时,没有新的相机图片包含两种行为:立即返回和阻塞等待。

这里写图片描述

参考文献

1、基本概念 https://developers.google.cn/ar/discover/concepts
2、ARCore带来的新概念 https://blog.csdn.net/p106786860/article/details/78533538
3、ARCore开发的起步 https://blog.csdn.net/p106786860/article/details/78620542

猜你喜欢

转载自blog.csdn.net/yolon3000/article/details/81545114