也许你曾经听说过增强现实——目前是移动领域一个热门的技术。你将会从这篇介绍性的文章当中,学习到什么是增强现实技术,以及如何在你的安卓应用程序当中利用这门技术。
增强现实的定义
在我们开始讨论如何去编写增强现实应用之前,让我们退一步看一下它的定义是什么。维基百科定义增强现实如下:
"增强现实(AR)是一种通过计算机虚拟化技术,把真实世界中的声音和图像信息加到用户的感官感觉上的方式。它通常也被称作叫介导现实(mediated reality),像是现实被计算机给修改了(更可能是减弱而不是增强)。总而言之,这项技术主要提升了个人对现实的感知。"
最近移动开发者已经开始利用起增强现实技术,他们获取摄像头的输入并且实时地叠加图像,通常来说是根据图像去显示一些真实世界的东西或者一个虚拟的标志或者对象。
这并不是说今天产生了什么新的对增强现实技术的更宽泛的定义。有人可能会说,你看,Google 的 Sky Map 就不是通过摄像头去绘制的,但是我们也称之增强现实,它已经把其他增强现实做的事情都做了(见下图)。其实,真的不要太纠结于这些定义,更应该去想想你的应用程序有哪些可以利用实时地现实数据的机会。比如说,eBay 最近宣称他们加了增强现实特性到他们的时尚应用程序当中。这个特性允许用户去看自己戴不同太阳眼镜的样子。
本基础教程的剩下内容会讨论虚拟现实技术的各个方面,以及他们如何应用在安卓上。教程不会深入到具体的实现过程上。那样的话会超出本教程的范围,当然如果读者对这部分特别感兴趣,我们可以继续沿着这条路往前走并且提供一些具体的教程。
为什么要重新发明轮子?你应用程序上已经存在简单的 AR 底层支持
已经觉得不堪重负了?也许你有一些数据,希望别人在增强现实的环境中去探索,但是你不想在你的应用程序中把整个 AR 底层都实现一遍。如果真的把这些东西都加到你的项目中,看上去会毁了你的整个项目,这个时候你打算怎么办?
试着去用一些已经存在的 AR 服务,比如 Layar。他们同时提供了安卓和苹果平台的客户端。举例来说,这个 Layar 服务允许任何人去添加数据,然后显示给用户,并且封装了 AR 的一些细节。更好的是,它是跨平台的,所以你可以同时做安卓和苹果平台的客户端。
提供你自定义的 AR 实现:基础部分
现在我们有一个共同的增强现实的定义,让我们开始讨论把它和你 AR 应用程序中的安卓组件结合在一起。
典型的 AR 实现包含两个主要的部分:我们正在增强地“实时”数据,以及用于增强的“元”数据。以真实世界的例子来说,我们正在增强地实时数据通常会结合后者摄像头的取景器信息,当前的位置,以及设备面对的方向。这些信息稍后会跟“元”数据进行交叉引用。
例如,如果我们想在取景器中看到加油站的位置,AR “服务”必须有每个加油站的增强数据,包括他们的维度和经度。使用这些信息,结合设备/摄像头指向的方向,我们可以大致地得到每个加油站在取景器窗口的位置,并且在上面显示一个燃料图标。
增强数据源(比如:加油站位置列表)可以是任何东西,但是通常预读取的数据库或者是网络服务,可以过滤一些附近有趣的地点。
剩下的 AR 实现部分由这些内容组成:使用设备摄像头的 API,图像 的API,以及利用传感器 的API去实时数据上加入增强数据,创建一个良好的增强体验。
关键 AR 组件 #1:摄像头数据
在增强现实中,安卓摄像头里面显示的实时反馈叫做现实。通过 android.hardware.Camera 包的一些 API 可以获取到摄像头数据。
如果你的应用不需要分析帧数据,那么可以使用一个带有 SetPreviewDisplay() 方法的 SurfaceHolder 对象去开启一个预览。通过这个方法,你就可以显示现在摄像头正在录制什么内容。无论如何,如果你的应用需要帧数据,可以通过一个合法的 Camera.PreviewCallback 对象去调用 SetPreviewCallback() 方法。
关键 AR 组件 #2:位置数据
对于大多数增强现实的应用来说,只有摄像头的反馈是不够的。你还需要去确定设备的位置(以及用户的位置)。想要完成这个任务的话,你通常会需要用到 android.location 包以及 LocationManager 类的一些 API,它们会提供给你合适的或者是大概的位置信息。这样的话,你的应用就可以监听到位置事件,并且用这些去确定设备附近有哪些有趣的实时的东西。
如果你正在构建一个增强现实的应用,并且准备利用计算机视觉技术去分析摄像头的反馈(换句话说,通过对输入的图像进行数据提取,计算机会“看到”一些东西),从而确定在哪儿放置增强数据,你也许不需要去知道设备的位置。计算机视觉技术目前研究的比较深入。大多数的解决方案可以从 OpenCV 库中获取到。更多关于 OpenCV 的信息可以从 OpenCV wiki 里面找到。
当不使用位置数据的时候,经常会用一个 “marker” 或者是 “tag” 代替。那是一个非常易于识别的对象,可以方便我们快速的确定要绘制的物体的方向和缩放情况。比如说,AndAR 使用一个非常简单的 marker ,方便在上面绘制一个立方体,作为 AR 能力的测试。
关键 AR 组件 #3:传感器数据
传感器数据对 AR 实现是非常重要的。比如说,当我们需要试着去保持跟摄像头反馈的数据同步的时候,知道手机的旋转方向非常有用。
在安卓设备上去确定旋转方向,你会需要利用到 android.hardware.SensorManager 包。有一些你可能会用到的传感器:
1. Sensor.TYPE_MAGNETIC_FIELD
2. Sensor.TYPE_ACCELEROMETER
3. Sensor.TYPE_ROTATION_VECTOR
这些传感器的使用,让用户移动设备的同时,在屏幕里面可以看到相关的变化,从而使得用户有一种身临其境的感觉。当摄像头的反馈展现出来的时候,效果值得商榷,但是在其他应用当中,比如说探索已经预先存储好的图像数据的时候(比如说 Google Sky Map 或者是 Street View),这项技术还是挺有用的,特别是对用户来说很直观。
结合到一起:图层遮罩
当然,整个增强现实的重点当然是通过摄像头的反馈区绘制一些东西,增强用户所实时看到的。概念上,基于摄像头的反馈绘制东西是非常简单的。至于你如何去实现呢,看你自己了。
你可以读取摄像头反馈的每一帧,加入一个遮罩,并且在屏幕上绘制一层(允许是一个 BitMap 或者是 一个 3D 表面的纹理)。具体来说,你可以利用 android.hardware.Camera.PreviewCallback 类,它允许你去得到应用每一帧的图像。
另外,你可以使用一个标准的 Surface Holder 加上 android.hardware.Camera 对象,然后就可以轻松地绘制在该表面的上方了。
最后,你绘制什么,以及如何绘制,都取决于你不同的应用程序的需求——安卓有不少的 2D 或者是 3D 图像的 API 可以用,尤其是一些 android.graphics 和 android.opengl 包里面的 API。
存储和访问增强数据
所以说,这些增强的数据从哪里来呢?通常来说,你应该是从你自己的数据库里面获取得到,有可能是存储在本地,或者是通过云服务存储在线上的数据库。如果你已经想预先把数据存在设备里面,你可能会想使用一个 SQLite 数据库简单快速的查询;你会发现 SQLite 的 API 在 android.database.sqlite 包里面。对于基于 web 的数据来说,你可能会想要连接到一个 web 的服务上,然后用通常的方法:HTTP 和 XML 解析来处理。对于这种情况,你可以简单的使用 java.net.URL 类以及一个 XML 解析的类,比如说 XmlPullParser 类,来解析出结果。
结论
增强现实是一个很广泛的话题,触及到了安卓开发的方方面面,以及许多的 API。在这个基础教程中,你已经学到了什么是增强现实,以及安卓组件如何处理(以及相关安卓 API)。现在,你可以结合这些新的知识,加上你对安卓 SDK 的了解,去加强你已经写好的应用程序,或者是构建新的增强现实的应用程序。
原文地址:http://code.tutsplus.com/tutorials/android_augmented-reality--mobile-4457