其实准备ARKit已经很久了,确切地说当WWDC开始介绍时就开始了。其后参加了苹果的ARKit workShop,加上自己有点事,所以文章一直没发出来,现在再发一篇上手文章,也没什么意义。所以本篇文章重在workShop上苹果工程师的解惑和我对ARKit的理解, 最后会简单介绍一下相关技术。
AR(Argument Reality)大家都知道,就是将3D模型渲染在摄像头图像之上,混合渲染达到虚拟物品就好像是现实的一部分。ARKit解决了模型定位难的问题,结合CoreMotion运动数据与图像处理数据,来建立一个非常准确的SLAM系统,构建虚拟世界和现实世界之间的映射。同时能够分析环境自动给模型添加光源,实际效果还是比较惊艳的。
从结构上看,ARKit提供了一套简单易用的AR框架,但框架之外,需要很多的三维空间、游戏编程、3D模型、GPU渲染的知识来理解AR技术。ARKit最重要的两个类是ARSession与ARSCNView
类似与AVFoudation,ARKit中由ARSesseion类来配置SLAM系统的建立。设置RSession的配置选项为ARWorldTrackingSessionConfiguration来追踪设备的方向与位置,并且能够检测平面。这个选项只有A9处理器之上才支持。其他型号处理器(6S以下)只能追踪设备的方向。
ARKit的提供了自带的两个渲染类:ARSCNView和ARSKView,后者用来渲染2D模型。之前鲜有问津的SceneKit算是有了用武之地。这两个类会自动开启摄像头并建立虚拟空间与现实空间之间的映射。同时ARKit也支持自定义用OpenGL或Metal实现渲染类,但要自己管理与ARSession之间的通信,同时要遵循iOS GPU命令不能在后台调用的规则。
其他比较重要的类有ARAnchor、ARHitTestResult、ARFrame、ARCamera。
HitTest的返回,世界中的ARAnchor。
与UIKit中的hitTest不同,ARKit的HitTest以设备方向配合视图坐标,建立一条世界中的射线,所有在射 线上的ARAnchor, 会以由近到远的方式返回。此外SCeneKit的HitTest返回虚拟物品。
场景中的摄像机,用来控制模型视图变换和投影变换。同时提供6DOF(自由度信息,方向+位置)与追踪信息。
从框架接口来看,ARKit 暴露出来的能力并不多且小心翼翼。
AR的能力,由三部分组成:
目前看 ARKit 只提供了3D渲染的入口,其他两个都被封装起来了,所以目前来看渲染是差异化的主要途径,但不唯一。ARKit workShop 上,面对大家提出的苛刻问题,苹果工程师大量提到特征点。其实计算机视觉是可以在场景理解这一层面做一些自定义的。如果苹果开放更多的能力,那AR的能力完全可以作为任何一个APP的特性。
此外,ARKit还存在一些问题:
汇总了一下workShop上,比较感兴趣的问题和苹果工程师的回答,掺杂自己的理解。
1 . ARFrame提供的YUV特征,如何获取RGB特征?
答:使用Metal去获取特征点的RGB值。
(这个我一般是用OpenGL的shader去做,我想苹果工程师是说将图像用Metal转成位图后,根据坐标去获取RGB值。但特征点不多的话,直接在CPU中利用公式计算一下不就行了吗?不过也许Metal有更强大的方法。)
2 . ARKit中怎么做虚拟环境?
答:利用Cube背景。
(这个在VR中用的比较多,就是用一个贴满背景的立方体包裹住摄像机所在的空间,网上的资料较多。)
3 . ARKit的如何模拟光源的?为什么不产生阴影。
答:ARKit通过图像的环境来设置模型的环境光强度,而环境光是不产生阴影的。
(我猜苹果应该是通过像素值来确定环境光的,如果用高级一点的方法完全可以添加直射光。光照有许多模型,只有带方向的光才会产生阴影,如果想用ARKit做出阴影,可以看我的回答。)
4 . AVFoudation与ARSession之间的切换会有问题吗?
答: ARSession底层也是用AVFoudation的,如果重新打开ARKit,只需要重新 run 一下 ARSession 可以了,但切换时会有卡顿。
(我自己试了一下,切换时确实有轻微的卡顿,切换后ARSession就停止摄像头采集了,但3D渲染会继续,只是丧失了空间定位与检测识别的能力。)
5 . ARKit是否支持前置摄像头?
答:不支持。ARKit并不是一个用于前置摄像头环境的技术,因为空间有限,能提供的信息也非常有限。
(这个问题是很多参会者关心的问题,但 ARKit 团队似乎不是很 care ,说到底还是因为前置摄像头的场景中,用户很少会移动,画面中一般大部分都是人脸,这样 ARKit 的定位与检测能力无法很好使用。建议由类似需求的同学好好梳理,是不是想要的是3D渲染而不是AR。)
6 . ARKit的最大应用范围是多少?
答:100米是 ARKit 在保持较好用户体验的最大测量距离。
(这个其实我有点没太听清,实际数字应该是100米以上)
7 . ARKit如何做marker?
答:ARKit不会提供这样的能力,如果想实现的,可以用 ARKit 提供的特征点来跑自己的计算机视觉。
(熟悉计算机视觉的同学应该都明白,其实marker就是一种简单的图像识别,如果 ARKit 提供的特征点可靠的话,完全可以自己做特征匹配。现场问了苹果工程师,他们的特征点是什么特征,他们不愿回答,不过看使用场景的话,应该是一种边缘敏感的低维特征,应该类似 PCA + SURF)。
8 . ARKit合适支持A8?性能如何?
答:支持A8处理器并不在计划中(这里指的是空间定位能力,A8只支持空间方向追踪),ARKit 的大部分计算都是在CPU上处理的,在A8处理器上的性能损耗在 15% ~ 25%, 在A9处理器上的性能损耗在 10% ~ 15%。
(看他们的意思,大量的计算,在A8上应该是比较低效的,解释了为什么A8上的追踪能力是阉割版的。性能应该说还不错,与游戏类似)
9 . 如何追踪实际的物体?
答:可以在已识别的物体位置上,添加一个node, 这样就能在之后的处理中一直保持这个物体的追踪。
(这次的wrokShop,苹果大量提到他们的特征点,如果他们真的足够重视的话,应该开放特征检测的过程与特征向量,希望后期能够开放吧)
10 . 如何连接两个不同 ARKit 世界?
答:ARKit没有计划支持这些,比较 tricky 的做法是将两个手机紧挨着启动ARKit。
(这个也是很多参会者关注的问题,相信不少人已经有了自己的解决方案,这里我后期会出一篇文章讲解。)
AR说到底还是一种游戏技术,AR提供了定位、检测平面的功能,这些功能并没有暴露出来供我们自定义,那么只能在渲染方面做出差异。
目前ARKit支持的3D渲染引擎,有sceneKit,Unity3D,UE。后两者都是成熟的游戏引擎,能够提供完整的游戏功能,但没有我们没有使用,主要因为:
最终决定还是用sceneKit,主要出于一下考虑:
ARKit和OpenGL一样,使用右手坐标系
将模型加载到空间中,需要6个自由度(6DOF)的信息来指定模型的表现:
分别是沿三个坐标轴的平移与旋转。
可以使用旋转矩阵、欧拉角、四元数来定义空间旋转,ARKit的这三种方式均有运用。
把空间旋转分解成绕三个局部坐标轴的平面旋转,分别是pitch(俯仰角,绕x轴),yaw(偏航角,绕y轴),roll(翻滚角,绕z轴),然后以一定顺序做旋转(sceneKit中是 roll -> yew -> pitch),欧拉角是使用三个 3*3 矩阵连乘实现,而且存在万向锁的问题。
当pitch为90°时,pitch与yew的旋转轴重合了,这时飞机丧失了一个旋转的维度。
将三维空间的旋转表示成四维空间的超球面上位移, 概念有点复杂。简单来说,我们只需要旋转轴 u→=(x,y,z) ,和角度 emoji 来构造一个单位四元数 q:
那么旋转可以定位为:
对任何需要旋转的点
visual-inertial odometry :基于视觉和惯性的测量方法,惯性数据是指角速度和加速度,这些都由Core Motion提供,加上图像特征,能够更准确地建立SLAM系统。ARKit会将提取到的特征点映射的空间中,也就是说特征点是由三维坐标的,我们可以利用特征点来确定图像中物体的远近。实测效果不错,误差在分米级别。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。