ios arkit原理理解

一,视频效果

把虚拟的3d椅子放在了真实的世界里。
更多视频:
https://www.youtube.com/watch?v=8KmVaW8F9Nc
https://www.youtube.com/watch?v=bUEuzBlkWNI

二,应用场景

1,模拟一辆车在马路上行驶的效果,卖车嘛
2,模拟房屋的装修
3,服装。
4,等你来无限脑暴.......

三,arkit的工作原理

1,打开摄像头开始构建3d场景
怎么构建的3d场景呢?
答:打开摄像头,初始化3d场景,以当前摄像头的位置为3d坐标系原点位置,也是rootNode;
初始化的坐标系是世界坐标系, ARKit里坐标系都是使用的右手坐标系。(关于坐标系后面会详细讲到)
摄像头前方z的负方向
摄像头右边x的正方向
摄像头上面y的正方向
附图(坐标系,和右手)
ios arkit原理理解_第1张图片 ios arkit原理理解_第2张图片
2,再把虚拟的3d模型添加到3d场景,与真实世界进行合适的交互。
arkit本身不提供虚拟3d模型的加载能力,而是由专门的3d绘制引擎来加载;市面上用的比较多的是
sceneKit,
unity3D 5.6.2以上,
Unreal 4.1.7以上
如果是做普通的商业应用,建议选择scenekit,原因:
1)sceneKit是系统动态库,对安装包不会有增量
2)sceneKit是OC写的,可以OCS
3)sceneKit虽然能力不如unity3d和Unreal,但是毕竟不是做一款很复杂的游戏,sceneKit完全够用了
3,摄像头在移动时,通过摄像头的位置,角度以及图像检测,实时的计算并渲染出当前的3d世界
ARKit 使用视觉惯性测距技术,对摄像头采集到的图像序列进行计算机视觉分析,并且与设备的运动传感器信息相结合。ARKit 会识别出每一帧图像中的特征点,并且根据特征点在连续的图像帧之间的位置变化,然后与运动传感器提供的信息进行比较,实现了一系列非常庞大的算法计算,最终得到高精度的设备位置和偏转信息,来建立一个非常准确的SLAM(simultaneous localization and mapping)系统,构建虚拟世界和现实世界之间的映射,所以原来添加在3d场景的物理模型相对于相机的真实矩阵位置就能被计算出来。
4,场景解析:目前开放了能力有平地捕捉,环境光估计,尺度估计,iphonex前置摄像头的人脸识别等;以后应该会开放更多能力
  • 平地捕捉:苹果为了让更多的iphone都能支持AR,选择了单目SLAM技术;但是苹果这次单目SLAM就做的非常好,不止能估计平面,还能识别边界。https://v.qq.com/x/page/d0511twrvrj.html该视频中小人跳出桌面的就是用的边界估计。
  • 尺度估计:这个就更厉害了。单目SLAM能非常准确估计尺度的,貌似没有其他公司能做到了。
  • 环境光估计:通过摄像头捕捉并计算捕捉到的场景中光的总量,来给虚拟物体施加正确的光照条件,渲染效果更加真实。
  • iphonex的人脸识别,并不是识别不同人的脸。而是从图像帧里找到一张3D脸;并且提取该脸上51个位置的特征值;将脸型以及脸部表情量化成数据。
AR系统的大致结构图,附图
ios arkit原理理解_第3张图片

四,scenekit重要类的介绍

SCNView:继承UIView,用来显示3D世界的。
SCNScene:可以从3d模型中加载一个3d场景(arkit没有这个能力,必须依赖scenekit去加载虚拟的3d模型)
SCNNode:一个scene的基本构成快,可以把摄像机,灯光,几何体附加到节点上。
SCNGeometry:三维几何体
SCNMaterial:材质,上色,贴图靠它
SCNLight:光源可以附加到节点上 http://www.itdadao.com/articles/c15a923684p0.html
一共有4种光源
  • 环境光(SCNLightTypeAmbient),这种光的特点,没有方向,位置在无穷远处,光均匀的散射到物体上.
  • 点光源(SCNLightTypeOmni),有固定的位置,方向360度,可以衰减
  • 平行方向光(SCNLightTypeDirectional),只有照射的方向,没有位置,不会衰减
  • 聚焦光源(SCNLightTypeSpot),光源有固定的位置,也有方向,也有照射区域 ,可以衰减
看文字太抽象了。
附图:
SCNCamera:虚拟摄像机可以附加到节点上,提供一个场景的视图。
camera是个单例,全场只有1个。

五,ARKit重要类、api的介绍

详细介绍可参考这个文章,或者看源码注释: http://blog.csdn.net/u013263917/article/details/73156679
ARAnchor:锚点,表示3d模型在3d空间的位置和方向, 数据用matrix_float4x4的四位数组表示,参考坐标系是世界坐标系;anchor应该对应一个3d节点node;
ARPlaneAnchor:平地锚点,同上;而且开放了更简单的数据属性来表示平地锚点
问题:matrix_float4x4 transform如何使用?为什么是4*4(后面会讲)
ARFaceAnchor:脸部锚点,含脸部几何信息ARFaceGeometry和ARBlendShapeLocation(这个枚举包含了51种脸部位置,以及对应位置的量化数据;通过这51组数据来绘制对应的ARFaceGeometry),
ARFrame:追踪相机当前的状态,这个状态不仅仅只是位置,还有图像帧,追踪到的3d锚点(数组),环境光等
ARSCNView:继承SCNView,该类就是3d的AR场景图,也就是你肉眼在手机上看到的画面。它持有ARSession,SCNScene,可通过node获取anchor,可通过anchor获取node,实时监测平面等能力。该类非常重要 http://blog.csdn.net/u013263917/article/details/73156918
ARSession:是一个连接底层与AR师徒之间的桥梁,设置追踪配置,启动ar会话,实时监听摄像头捕捉到的数据。ARSCNView所有的代理方法的数据回调都是由ARSession触发的。 该类非常重要 http://blog.csdn.net/u013263917/article/details/73157082
session添加锚点和监听锚点等,具体是干什么用的?锚点不就是矩阵数据吗,单独添加锚点有意义吗?我在github上看了几十个demo,没有人用过ARSession跟锚点相关的接口。
ARConfiguration:会话追踪配置,主要用于追踪相机的位置。可以追踪到x,y,z三轴的数据变化
子类ARWorldTrackingConfiguration:可以实时检测传感器6轴的变化,加上图片识别,作为SLAM的主要数据输入
子类ARFaceTrackingConfiguration:识别出人脸,并且量化成几何信息,以及51组脸部对应位置数据;
ARHitTestResult: hitTest:触发后点击回调结果。这个类主要用户虚拟增强显示技术中现实世界和3D场景中虚拟物体的交互。比如:我们在相机中移动,拖拽3D虚拟物体,都可以通过这个类来获取ARKit所捕捉的结果。可以获取到节点的锚点,距离相机的距离,本地坐标矩阵,世界坐标矩阵
http://www.jianshu.com/p/92aa4491fa4d
ARCamera:是一个相机,连接虚拟场景和现实场景的枢纽;我们在ARSCNView初始化时,会默认创建一个相机,位置就是3D世界坐标系的原点。它的api一般我们无需关心,都是readonly,默认配置好的。
ios arkit原理理解_第4张图片

六,坐标系、矩阵变化的介绍

1,坐标系介绍

ARKit有2种坐标系,世界坐标系和本地坐标系。他们都是右手坐标系
  • 世界坐标系:也叫绝对坐标系,以根节点为原点创建的三维坐标系称为世界坐标系,始终不变的,相机的位置。
  • 本地坐标系:也叫相对坐标系,以场景中的某节点(非根节点)为原点建立的三维坐标系,坐标系原点是父节点的坐标位置。
在做arkit开发会比较多的看到世界矩阵和本地矩阵,其实就是对应这两种坐标系做对应的矩阵变化后,变化到某个位置。
子节点在设置position,rotate,scale时默认是使用的本地坐标系。
下图中位于坐标系中心的就是根节点,此外还有添加的两个节点 NodeA 和 NodeB,其中 NodeA 的父节点是根节点,NodeB 的父节点是 NodeA:
ios arkit原理理解_第5张图片

2,矩阵变换实现

矩阵变化的目的就是实现模型的平移,旋转,缩放等设置和动画。
下面是一组平移+旋转动画的实现
  1. /* 
  2.  动画
  3.  (SCNAction *)rotateByAngle:(CGFloat)angle aroundAxis:(SCNVector3)axis duration:(NSTimeInterval)duration 
  4.  angle:弧度 3.14是半圈 
  5.  [SCNAction rotateByAngle:M_PI aroundAxis:SCNVector3Make(0, 1, 0) duration:2];的意思是,2s内,沿着y轴旋转半圈 
  6.  */  
  7. // 创建动画行为  
  8. SCNAction *rotation = [SCNAction rotateByAngle:M_PI aroundAxis:SCNVector3Make(0, 1, 0) duration:2];  
  9. SCNAction *moveUp = [SCNAction moveTo:SCNVector3Make(0, -1, 0) duration:1];  
  10. SCNAction *moveDown = [SCNAction moveTo:SCNVector3Make(0, -15, 0) duration:1];  
  11. // 顺序执行的动画  
  12. SCNAction *sequence = [SCNAction sequence:@[moveUp,moveDown]];  
  13. // 组合动画的执行  
  14. SCNAction *group = [SCNAction group:@[sequence ,rotation]];  
  15. [shipNode runAction:[SCNAction repeatActionForever:group]];  
sequence动画串行
group动画并行
其他相关动画接口:
http://blog.csdn.net/pzhtpf/article/details/51353071
基本包含:移动,旋转,缩放,淡入淡出
如果仅仅是调用这些接口实现基本动画,好像也是够了。但锚点ARAnchor的属性transform却是一个 matrix_float4x4数据,而且常被使用,这些数据分别对应了什么呢?看下面矩阵变换的原理

3,矩阵变换的原理

为何ARAnchor锚点矩阵数据是 matrix_float4x4 transform 4维的。
答案见: http://www.jianshu.com/p/7faa4a3af589(仅参考)
http://www.opengl-tutorial.org/cn/beginners-tutorials/tutorial-3-matrices/(没讲旋转矩阵)
一个4*4矩阵如下
ios arkit原理理解_第6张图片
最右边的三个矩阵元素 (m12, m13, m14) 是用作位移变换的。m15元素是齐次坐标。(何为齐次坐标,参见:http://www.songho.ca/math/homogeneous/homogeneous.html),该元素是用来投影变换的。
3个元素集(m0, m1, m2),(m4, m5, m6)和(m8, m9, m10) 是用作欧拉变换和仿射变换,例如旋转Rotate,缩放Scale
(m0, m1, m2): +X 轴,向左的向量(left vector)(估计是相对屏幕自己来说),默认为(1,0,0)
(m4, m5, m6) : +Y轴,向上的向量(up vector),默认为(0,1,0)
(m8, m9, m10): +Z轴,向前的向量,默认为(0,0,1).
ios arkit原理理解_第7张图片
在场景坐标系中,为了要表示node的位置、旋转、缩放,我们需要一系列数据才能完美的还原出它正确的姿势。
以及通过一系列矩阵变化,来完成node的动画。

1)模型矩阵

*平移矩阵
将当前矩阵沿x轴正方向平移10
*旋转矩阵
http://www.360doc.com/content/17/0608/11/1489589_661025068.shtml
http://www.cnblogs.com/kesalin/archive/2012/12/06/3D_math.html
绕x轴旋转
绕y轴旋转
绕z轴旋转
*缩放矩阵
在x轴缩放2倍,y轴缩放2倍,z轴缩放2倍
那么怎么做到同时平移+旋转+缩放的呢?
TransformedVector = TranslationMatrix * RotationMatrix * ScaleMatrix * OriginalVector;
注意:这行代码首先执行缩放,接着旋转,最后才是平移。这就是矩阵乘法的工作方式。
第4维的1是什么呢?做什么用的?
第4个分量代表齐次坐标,用来区分向量和点。
若w==1,则向量(x, y, z, 1)为空间中的点。
若w==0,则向量(x, y, z, 0)为方向。
(请务必将此牢记在心。)
网上大多数博文说齐次坐标在放射变换中非常方便,然后就没有后文了。详情可以参考:
http://www.cnblogs.com/csyisong/archive/2008/12/09/1351372.html

2)观察矩阵(视图矩阵)

引用一句话:引擎推动的不是飞船,而是宇宙
上面讲到的模型矩阵是给3d模型做变化的。摄像机也是一个3d节点,也做对应的运动,那么整个视图就不一样了。
因为ARKit加载的并不是虚拟摄像头,而是设备真实摄像头作为camera节点,来观察这个3d世界;camera的运动,以及运动之后视觉的变化,是通过监听传感器数据变化和图像识别再转成对应的视图矩阵,并且将实时渲染出来视图的结果直接返回。这些能力都集成在ARkit里,对观察矩阵有个了解应该就够了。

3)投影矩阵

投影变换的目的是确定 3D 空间的物体如何投影到 2D 平面上,从而形成2D图像,这些 2D 图像再经视口变换就被渲染到屏幕上。前面提到投影变换有两种:正交投影和透视投影。透视投影用的比较广泛,它与真实世界更相近:近处的物体看起来要比远处的物体大;而正交投影没有这个效果,正交投影通常用于CAD或建筑设计。下面分别是正交投影与透视投影效果示意图:
我们应该主要关注透视投影变化,透视投影效果主要由下面的参数确定
[1] 屏幕的宽高比(aspect ratio)——显示区域(投影目标)的宽度与高度的比值;
[2] 垂直视野(field of view),相机的垂直视角。相机在垂直方向上视野的角度大小;
具体关于投影矩阵算法可以参考这篇文章: http://wiki.jikexueyuan.com/project/modern-opengl-tutorial/tutorial12.html
在ARKit中,上面2个参数,以及投影变化后的结果,都是默认设置好的,好像也是不可修改的,因为也不需要修改啊。

七,在ios上接入arkit

最简单demo: https://github.com/MartinLi841538513/ARKitStudy2
1,接入必要步骤
1) info.list配置Camera Usage Description
2) 
2,平地捕捉
3,人脸识别

八,相关资料

github: https://github.com/olucurious/Awesome-ARKit
km地址:

九,不足之处

1,目前只支持A9处理器;且iphone6s以上设备,且ios11以上操作系统
2,只支持水平平面检测,不支持竖直平面检测。(支持竖直平面检测应该只是早晚的问题)
3,相机采景模糊,光照不足,距离过大,移动速度太快都可能影响追踪效果
4,人脸识别目前只支持iphonex的前置摄像头
对比其他平台的优点
1,低功耗
2,世界追踪的实时性和准确性很好
3,实际效果惊艳

十,android tango(google官方开放的ar sdk)

1,需要Unity+Tango的开发方式,Tango本身不提供3D渲染能力。
2,依赖Tango设备,目前市面上该类型设备卖的不好。
详细介绍
http://www.jianshu.com/p/49d76c24ae46
http://get.google.com/tango/

十一,其他ar sdk

现在主流的AR SDK产品主要有easyAR、vuforia、ARKit、metaio、point cloud、hiAR。
Vuforia--不用多说,ARKit出来之前最流行的AR应用开发引擎。
EasyAR--EasyAR是国内最专业的AR引擎,是国内首款投入应用的AR SDK。EasyAR是好用且免费的增强现实(Augmented Reality)开发者引擎。
HiAR--HiAR 增强现实开发平台 HiAR 是亮风台信息科技打造的新一代移动增强现实(AR)开发平台,提供一整套世界领先的增强现实(AR)技术服务。
太虚AR--成都米有网络科技有限公司自主研发集成于Unity3d实现增强现实的SDK开发包,虚拟现实SDK太虚官方网站。
Wikitude--Wikitude是一家专门从事智能手机增强现实的应用,分别出品了两款应用Wikitude drive与Wikitude World Browser。
** Intel RealSense**--RealSense 3D是一套感知计算解决方案,包括世界上最小的3D摄像头,模块比两个硬币摞起来还薄,除了硬件外,英特尔还将提供驱动及软件等全套开发工具
ICreator--依托于iCreator 3D, VR引擎,模型师可以快速创建交互式3D, VR内容,并支持微信平台传播,也为模型师提供可视化3D模型交易功能。
天眼--天眼AR包括天眼云平台和天眼AR浏览器,用户需在天眼云平台完成“AR内容”制作,然后在天眼AR浏览器查看效果。
详情: https://www.cnblogs.com/qiaogaojian/p/6416755.html


其他
1,iphonex faceid人脸追踪(可以先不用,做2次分享)
iphonex前置摄像头,支持人脸识别,这里的人脸识别,是指对比身体的其他部位,比如胳膊,手;
识别出来的人脸,是一个3d拓扑结构的数据,其中有个参数blendShapes是个dictionary,含51个具体的参数;这51个参数的不同组合代表了成千上万种表情;
修改这51种参数,就可以定向修改面部表情;

2,graphTraker算法是否可以接入。
应该是不可以的,它并不能模拟出来3d场景,这个才是最难的
输入是一组连续的图片帧,这个可以把摄像头实时帧作为输入
输出是对应图片帧的4个点,连线后就是一个平面,但是这个平面只是在图片的2d坐标系上,目前没有办法将该平面的2d坐标转化成3d场景里对应的3d坐标,那么就没有办法将3d模型集成过来。

即使只是想做成2d的模拟AR效果,也是不可行的。因为并没有能力做到世界追踪,哪怕是2d的世界追踪。
如果把2d世界追踪能力也集成了,倒是有可能。





你可能感兴趣的:(ios arkit原理理解)