一、AR简介:
增强现实技术(Augmented Reality,简称 AR),是一种实时地计算摄影机影像的位置及角度并加上相应图像、视频、3D模型的技术,这种技术的目标是在屏幕上把虚拟世界套在现实世界并进行互动.
一个最简单地AR场景实现所需要的技术以及步骤包含如下:
- 多媒体捕捉现实图像:如摄像头
- 三维建模:3D立体模型
- 传感器追踪:主要追踪现实世界动态物体的六轴变化,这六轴分别是X、Y、Z轴位移及旋转。其中位移三轴决定物体的方位和大小,旋转三周决定物体显示的区域。
- 坐标识别及转换:3D模型显示在现实图像中不是单纯的frame坐标点,而是一个三维的矩阵坐标。这基本上也是学习AR最难的部分,好在ARKit帮助我们大大简化了这一过程。
- 除此之外,AR还可以与虚拟物体进行一些交互。
二、 ARKit概述及特点介绍:
- ARKit是2017年6月6日,苹果发布iOS11系统所新增框架,它能够帮助我们以最简单快捷的方式实现AR技术功能。
- ARKit框架提供了两种AR技术:
- 基于3D场景(SceneKit)实现的增强现实,
- 基于2D场景(SpriktKit)实现的增强现实
- AR效果必须要依赖于苹果的游戏引擎框架(3D引擎SceneKit,2D引擎SpriktKit),主要原因是游戏引擎才可以加载物体模型。
- 虽然ARKit框架中视图对象继承于UIView,但是由于目前ARKit框架本身只包含相机追踪,不能直接加载物体模型,所以只能依赖于游戏引擎加载ARKit
开发环境:
- Xcode版本:Xcode9及以上
- iOS系统:iOS11及以上
- iOS设备要求:处理器A9及以上(iPhone6s 、iPhone6sPlus、iPhone7 iPhone7Plus、iPhoneSE、iPad Pro(9.7、10.5、12.9)、iPad(2017))
- MacOS系统:10.12.4及以上 (安装Xcode9对Mac系统版本有要求)
三、ARKit框架简介:
ARKit并不是一个独立就能够运行的框架,而是必须要SceneKit一起用才可以,换一句话说,如果只有ARKit,而没有SceneKit,那么ARKit和一般的相机没有任何区别。
相机捕捉现实世界图像,由ARKit来实现;在图像中显示虚拟3D模型,由SceneKit来实现。
继承关系:ARKit框架中中显示3D虚拟增强现实的视图ARSCNView继承于SceneKit框架中的SCNView,而SCNView又继承于UIKit框架中的UIView;
UIView的作用是将视图显示在iOS设备的window中,SCNView的作用是显示一个3D场景,ARScnView的作用也是显示一个3D场景,只不过这个3D场景是由摄像头捕捉到的现实世界图像构成
ARSCNView只是一个视图容器,它的作用是管理一个ARSession
在一个完整的虚拟增强现实体验中,ARKit框架只负责将真实世界画面转变为一个3D场景,这一个转变的过程主要分为两个环节:由ARCamera负责捕捉摄像头画面,由ARSession负责搭建3D场景。
ARKit在3D现实场景中添加虚拟物体使用的是父类SCNView的功能,这个功能早在iOS8时就已经添加(SceneKit是iOS8新增),ARSCNView所有跟场景和虚拟物体相关的属性及方法都是自己父类SCNView的。
四、ARKit工作原理及工作流程
ARKit提供两种虚拟增强现实视图,他们分别是3D效果的ARSCNView和2D效果的ARSKView。无论是使用哪一个视图都是用了相机图像作为背景视图,而这一个相机的图像就是由框架中的相机类ARCamera来捕捉的。
ARSCNView与ARCamera两者之间并没有直接的关系,它们之间是通过AR会话,也就是ARKit框架中非常重量级的一个类ARSession来搭建沟通桥梁的。
要想运行一个ARSession会话,你必须要指定一个称之为ARSessionConfiguration(会话追踪配置)的对象,ARSessionConfiguration的主要目的就是负责追踪相机在3D世界中的位置以及一些特征场景的捕捉(例如平面捕捉)。
ARSessionConfiguration是一个父类,为了更好的看到增强现实的效果,苹果官方建议我们使用它的子类ARWorldTrackingSessionConfiguration,该类只支持A9芯片之后的机型,也就是iPhone6s之后的机型。
ARSession搭建沟通桥梁的参与者主要有两个ARWorldTrackingSessionConfiguration与ARFrame。
ARWorldTrackingSessionConfiguration(会话追踪配置)的作用是跟踪设备的方向和位置,以及检测设备摄像头看到的现实世界的表面。它的内部实现了一系列非常庞大的算法计算以及调用了你的iPhone必要的传感器来检测手机的移动及旋转甚至是翻滚。
当ARWorldTrackingSessionConfiguration计算出相机在3D世界中的位置时,它本身并不持有这个位置数据,而是将其计算出的位置数据交给ARSession去管理,而相机的位置数据对应的类就是ARFrame。
ARSession类一个属性叫做currentFrame,维护的就是ARFrame这个对象。
ARCamera只负责捕捉图像,不参与数据的处理。它属于3D场景中的一个环节,每一个3D Scene都会有一个Camera,它觉得了我们看物体的视野。
ARKit框架工作流程:
ARSCNView加载场景SCNScene
SCNScene启动相机ARCamera开始捕捉场景
捕捉场景后ARSCNView开始将场景数据交给Session
Session通过管理ARSessionConfiguration实现场景的追踪并且返回一个ARFrame
-
给ARSCNView的scene添加一个子节点(3D物体模型)
ARSessionConfiguration捕捉相机3D位置的意义就在于能够在添加3D物体模型的时候计算出3D物体模型相对于相机的真实的矩阵位置,在3D坐标系统中,有一个世界坐标系和一个本地坐标系。类似于UIView的Frame和Bounds的区别。
五、ARKit全框架API类图介绍:
5.1、ARAnchor
ARAnchor表示一个物体在3D空间的位置和方向(ARAnchor通常称为物体的3D锚点,有点像UIKit框架中CALayer的Anchor), ARFrame表示的也是物体的位置和方向,但是ARFrame通常表示的是AR相机的位置和方向以及追踪相机的时间,还可以捕捉相机的帧图片。也就是说ARFrame用于捕捉相机的移动,其他虚拟物体用ARAnchor
5.2、ARCamera
ARCamera是一个相机,它是连接虚拟场景与现实场景之间的枢纽。在ARKit中,它是捕捉现实图像的相机,在SceneKit中它又是3D虚拟世界中的相机。
一般我们无需去创建一个相机,因为当我们初始化一个AR试图时,他会为我们默认创建一个相机,而且这个相机就是摄像头的位置,同时也是3D世界中的原点所在(x=0,y=0,z=0)
5.3、ARError
ARError是一个描述ARKit错误的类,这个错误来源于几个方面,例如设备不支持,或者当相机常驻后台时ARSession会断开等问题
5.4、ARFrame
ARFrame主要是追踪相机当前的状态,这个状态不仅仅只是位置,还有图像帧及时间等参数
5.5、ARHitTestResult
ARHitTestResult:点击回调结果,这个类主要用于虚拟增强现实技术(AR技术)中现实世界与3D场景中虚拟物体的交互。 比如我们在相机中移动。拖拽3D虚拟物体,都可以通过这个类来获取ARKit所捕捉的结果。
5.6、ARLightEstimate
ARLightEstimate是一个灯光效果,它可以让你的AR场景看起来更加的好
5.7、ARPlaneAnchor
ARPlaneAnchor是ARAnchor的子类,笔者称之为平地锚点。ARKit能够自动识别平地,并且会默认添加一个锚点到场景中,当然要想看到真实世界中的平地效果,需要我们自己使用SCNNode来渲染这个锚点,锚点只是一个位置。
5.8、ARPointCloud
ARPointCloud:点状渲染云,主要用于渲染场景
5.9、 ARSCNView
AR视图, ARKit支持3D的AR场景和2D的AR场景,ARSCNView是3D的AR场景视图,该类是整个ARKit框架中唯一两个有代理的类其中之一。该类非常重要,且API较多,将在后续小节介绍
5.10、 ARSession
ARSession是一个连接底层与AR视图之间的桥梁,其实ARSCNView内部所有的代理方法都是由ARSession来提供的。
ARSession获取相机位置数据主要有两种方式
- push。 实时不断的获取相机位置,由ARSession主动告知用户。通过实现ARSession的代理- (void)session:(ARSession *)session didUpdateFrame:(ARFrame *)frame来获取
- pull。 用户想要时,主动去获取。ARSession的属性currentFrame来获取
5.11、ARSessionConfiguration
ARSessionConfiguration会话追踪配置,主要就是追踪相机的配置。注意:该类还有一个子类:ARWorldTrackingSessionConfiguration,它们在同一个API文件中
追踪对其方式,这个决定了参考坐标系(参照物)
typedef NS_ENUM(NSInteger, ARWorldAlignment) {
/* 相机位置 vector (0, -1, 0) /
ARWorldAlignmentGravity,
/** 相机位置及方向. vector (0, -1, 0) heading :(0, 0, -1) */
ARWorldAlignmentGravityAndHeading,
/** 相机方向. */
ARWorldAlignmentCamera
}
/平面检测类型*/
typedef NS_OPTIONS(NSUInteger, ARPlaneDetection) {
/ 不检测. */
ARPlaneDetectionNone = 0,
/** 平地检测 */
ARPlaneDetectionHorizontal = (1 << 0),
}
六、技术要点
6.1、技术要点
6.1、技术难点
- ARKit只能没有图片识别的功能的,或者他这能识别相机的平面,如果要实现图片识别被动触发arkit,需要用其他的frame(比如CoreML 的图片识别的技术),于是Arkit跟CoreML,如何交互,是需要思考的。