一、前言
AR(Augmented Reality:增强现实)
今年年初上的一部电影:《头号玩家》,就是一个虚拟游戏世界,模拟出了各种现实的感觉。
当然,我个人的理解,头号玩家里面的场景我是划分为VR,大部分只是个虚拟现实,把人融入到虚拟的世界里面,而AR则是把虚拟的东西融入到现实的世界中来;
咱们今天说的只是增强视觉方面,当然AR不仅仅只是增强视觉,包括听觉,触觉,味觉,嗅觉等等,使用虚拟的东西可以以更真实的姿态融入到我们现实的世界;
二、AR的基础和核心思想
简单介绍:
1、在2D和3D空间中,跟踪用户的运动状态和运动轨迹,并最终定位它们的位置信息或者相对设备的位置信息比如之前的:支付宝AR红包,以及找宠物的那个游戏;
ARCore工作时要做两件事情,首先跟踪手机的运动轨迹,然后构建出它对现实世界的理解,针对现实的理解,对现实的画像做一个定义,平面,曲面,物体;
主要技术:
1、运动跟踪:
跟随摄像头视角成像的位置,进行位置捕获,ARCore使用称为并发测距和映射的过程来了解手机与周围环境的相对位置
当手机在运动时,计算出手机相对真实世界所在的位置和方向,ARCore 会检测捕获的摄像头图像中的视觉差异特征(称为特征点),
并使用这些点来计算其位置变化;
2、环境感知(环境理解):
具体实现的功能其实就是检测平面,或者说主要功能是为了检测平面,这样可以现实环境中放置虚拟物体的时候位置相对合理,
不会出现物体悬空,或者在斜面上仍然处于水平的姿态,水平面上防止虚拟物品出现倾斜状态等等;识别的时候,如果出现一种纯色,
且上面没有任何物体的平面,平面没有任何纹理,这样是很难识别出来的;
3、光线评估:
ARCore能够判断和感知现实世界的光源位置,使虚拟物体能够形成相应方位的影子,从而增加虚拟物体在现实世界里的真实度。
这个是其一,还有一种是为了,如果防止的物体本色就是一个颜色比较亮丽的,但是周围环境却比较暗淡,这种情况可以自动去
调节物体的亮度(光强度);
三、ARCore功能介绍
1、云瞄点
ArCore客户端:
ARCore可以改变对自身位置和环境的理解来调整姿态。如我们要在ARCore环境中放置一个虚拟对象,首先要确定一个锚点,以确保ARCore能随着时间的推移不断跟踪对象的位置。连接到附近锚点的物体会在整个AR体验期间看起来更逼真,因为瞄点的定位可以使物体保持它们的位置和彼此之间的相对位置和姿势不需要再继续使用的额瞄点,及时废弃掉,有助于减少CPU的资源消耗;
所以理论上:如果虚拟物体锚定到特定的可跟踪对象后,是可以确保虚拟物体与可跟踪对象之间的关系即使在设备移动时也能保持稳定(比如:瞄点定位平面成功后,调整了一下平面上的物体,增加或者减少物体,都不会影响虚拟物体相对平面的位置,仍然使虚拟物体看起来像是在这个平面上,但是,有一种情况,当我去移动这个平面的时候,或者翻转这个平面的时候,物体并没有跟随着平面而翻转)。
云端:
OK,这个东西实际上单机状态下是可以用ArCore独立完成,为啥它又叫做云瞄点呢,其实它里面存在一个数据共享的功能,简单说就是数据上传,某一台设备可以将锚点和附近的特征点发送到云端进行托管,上传后可以将这些锚点与同一环境中 Android 或iOS 设备上的其他用户共享。 这使应用可以渲染连接到这些锚点的相同3D对象,从而让不同的用户能够体验相同的AR效果;
云锚点的数云端据具有以下存储和访问限制:
托管锚点时上传至云端的原始视觉映射数据在七天后舍弃。
锚点会根据存储的稀疏点图在服务器端解析。
生成后,稀疏的点图可用于一天的云锚点解析请求。
之前上传的映射数据永远不会发送至用户的设备。
无法根据稀疏点图确定用户的地理位置或者重建任何图像或用户的物理环境。
任何时候都不会存储请求中用于解析锚点的可视特征描述符。
2、增强图像(在我看来,图片增强功能其实就是在图片识别技术上加上了图片位置定位功能而已)
主要功能:提供一组图片,当摄像头捕捉到图片时,会返回图片的位置,可以做响应的处理和显示
☆每个图像数据库可以存储最多1000 张参考图像的特征点信息。
☆ARCore 可以在环境中同步跟踪最多 20 张图像,但无法跟踪同一图像的多个实例。
☆环境中的物理图像必须至少为 15cm x 15cm 且必须平坦(例如,不能起皱或卷绕在瓶子上)
☆在物理图像被跟踪后,ARCore 会提供对位置、方向和物理大小的估算。 随着 ARCore 收集的数据增多,这些估算会持续优化。
☆ARCore 无法跟踪移动的图像,不过它可以在图像停止移动后继续跟踪。
☆所有跟踪都在设备上完成,所以无需网络连接。 可以在设备端或通过网络更新参考图像,无需应用更新。
ArCore SDK的tools目录下面有个arcoreimg.exe工具,这个是一个命令行工具,作用是获取一组参考图像并生成图像数据库文件:
常用命令:
(1)、检查图片质量,给出图片的评分(建议使用评分75以上的图片)
arcoreimg.exe eval-img
–input_image_path=xx/xx/a.png
例外:
WARNING: Logging before
InitGoogleLogging() is written to STDERR
I1218 11:08:11.665540 6900 distribute.cc:92]
No keypoints to prune.
Failed to get enough keypoints from target image.
(2)、生成图片列表对应的图片数据库:
arcoreimg.exe build-db
--input_images_directory=img
--output_db_path=myimage.imgdb
3、Sceneform(构建和渲染场景):
场景的构建和场景渲染,之前我们更多是在Unity里面听到过,里面使用的是OpenGL,其实ARCore早在17年刚出来的时候,并没有存在Sceneform API,
Sceneform 让 Android 开发者不必学习 3D 图形和 OpenGL 就能使用 ARCore。 它包括一个高级场景图 API,仿真基于物理的渲染器,一个用于导入、
查看和构建 3D 资产的Android Studio插件,并且可以轻松地集成到 ARCore 内进行简单的 AR 应用构建。
Renderable(ModelRenderable类)是一个 3D 模型,包括可由 Sceneform 在界面上渲染的网格、材料和纹理。
Sceneform 提供三种创建可渲染对象的方式:根据标准 Android 微件、根据基本形状/材料以及根据 3D 资产文件(OBJ、FBX、glTF)。
四、ARCode的使用:
环境:
Android Studio3.1及以上;
SDK24(7.0)及以上;
JDK1.8及以上;
支持Open GLSE3.1及以上;
还需要安装一个辅助插件:
集成:
仓库地址引用
allprojects {
repositories {
google()
}
}
包依赖(功能的实现主要是ArCore里面实现的,依赖的这个包只是):
//需要使用java8去构建
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
dependencies {
implementation "com.google.ar.sceneform.ux:sceneform-ux:1.6.0"
}
强制性选择AR
<uses-sdk android:minSdkVersion="{24 or higher}"
<meta-data android:name="com.google.ar.core" android:value="required" />
判断设备是否支持:
public static boolean checkIsSupportedDeviceOrFinish(final Activity activity) {
if (Build.VERSION.SDK_INT < 24) {
Log.e(TAG, "Sceneform requires Android N or later");
Toast.makeText(activity, "Sceneform requires Android N or later", Toast.LENGTH_LONG).show();
activity.finish();
return false;
}
ConfigurationInfo info = ((ActivityManager) activity.getSystemService(Context.ACTIVITY_SERVICE)).getDeviceConfigurationInfo();
String openGlVersionString = info.getGlEsVersion();
if (Double.parseDouble(openGlVersionString) < MIN_OPENGL_VERSION) {
Log.e(TAG, "Sceneform requires OpenGL ES 3.0 later");
Toast.makeText(activity, "Sceneform requires OpenGL ES 3.0 or later", Toast.LENGTH_LONG).show();
activity.finish();
return false;
}
return true;
}
核心类的介绍:
Session
com.google.ar.core.Session类,Session管理AR系统状态并处理Session生命周期。 该类是ARCore API的主要入口点。 该类允许用户创建Session,配置Session,启动/停止Session,最重要的是接收视频帧,以允许访问Camera图像和设备姿势。
Config
com.google.ar.core.Config类,用于保存Session的设置。
Frame
com.google.ar.core.Frame类,该类通过调用update()方法,获取状态信息并更新AR系统。
HitResult
com.google.ar.core.HitResult类,该类定义了命中点射线与估算的真实几何世界之间的交集。
Point
com.google.ar.core.Point类,它代表ARCore正在跟踪的空间点。 它是创建锚点(调用createAnchor方法)时,或者进行命中检测(调用hitTest方法)时,返回的结果。
PointCloud
com.google.ar.core.PointCloud类,它包含一组观察到的3D点和信心值。
Plane
com.google.ar.core.Plane类,描述了现实世界平面表面的最新信息。
Anchor
com.google.ar.core.Anchor类,描述了现实世界中的固定位置和方向。 为了保持物理空间的固定位置,这个位置的数字描述信息将随着ARCore对空间的理解的不断改进而更新。
Pose
com.google.ar.core.Pose类, 姿势表示从一个坐标空间到另一个坐标空间位置不变的转换。 在所有的ARCore API里,姿势总是描述从对象本地坐标空间到世界坐标空间的转换。
随着ARCore对环境的了解不断变化,它将调整坐标系模式以便与真实世界保持一致。 这时,Camera和锚点的位置(坐标)可能会发生明显的变化,以便它们所代表的物体处理恰当的位置。
这意味着,每一帧图像都应被认为是在一个完全独立的世界坐标空间中。锚点和Camera的坐标不应该在渲染帧之外的地方使用,如果需考虑到某个位置超出单个渲染框架的范围,则应该创建一个锚点或者应该使用相对于附近现有锚点的位置。
ImageMetadata
com.google.ar.core.ImageMetadata类,提供了对Camera图像捕捉结果的元数据的访问。
LightEstimate
com.google.ar.core.LightEstimate保存关于真实场景光照的估计信息。
通过 getLightEstimate()得到。
Demo演示效果: