作品视频链接:http://v.youku.com/v_show/id_XMTU4Mzg4MzY1Mg==.html
Ø 【作品名称】:《AR画报》
Ø 【实验目的】
在Android系统上,开发基于增强现实技术的应用。可以通过手机摄像头扫描的方式,获取与纸质媒体(如杂志)内容相关的视频信息,并能够让用户方便快捷地跳转到对应的网站。除了Target图片的识别,还支持二维码的识别。
希望通过这项应用,丰富纸质媒体的内容,同时将纸媒读者导向互联网入口,为内容生产者、广告主提供更好的展示平台,并且对图片的扫描可以一定程度上代替较为“丑陋”的二维码。
Ø 【实验器材】
Android Studio 1.5.1
Xiaomi Pad (7.9’’): Android 4.4.4 , 1536*2048 xhdpi
Ø 【实验原理】
一、 应用框架
上图所示即为本工程的应用框架。
Android设备首先会从摄像头和预存的图片文件和配置文件Json中获取RGB彩色图像以及(图片文件和配置文件Json中的)ImageTarget信息,然后通过处理单元。处理单元包括两个部分:
1、 ImageTracker:通过图像匹配的算法从Camera获取的Frame中找到与json配置的ImageTarget中最相关的图像,并进行精确的定位和追踪。
2、 BarCodeScanner:从Camera获取的Frame中发现是否存在二维码,并进行解码获取其中的文本信息。
通过处理单元处理后的信息,传送给Augmenter模块,它根据检测到的图像位置和摄像机的位姿,对增强现实的内容(视频)进行投影变换,并将结果用OpenGL绘制出来,显示在屏幕上。
以上部分概括了本作品的工作内容和流程。
二、 EasyAR引擎简介
本作品的增强现实技术主要依靠EasyAR提供的SDK编写,在此对EasyAR做一个简要的介绍。
EasyAR是Easy AugmentedReality的缩写,是视辰信息科技的增强现实解决方案系列的子品牌。它具有强大的跨平台能力,支持Windows/Mac OS/Android/IOS等主流的操作系统,并且能够完整的支持Unity3D。作为一个SDK,它的API设计也非常简洁,对新手比较友好。因此,我选择了EasyAR进行项目的编写。
三、 AndroidNDK的配置
由于EasyAR SDK目前不支持纯Java的API,所以我们需要同时编写Java和C++代码来使用EasyAR。为了能够在Android程序中同时运行C++和Java的代码,Google提供了Android NDK(Native Development Kit),它可以允许用户使用C/C++之类的原声代码在Dalvik虚拟机中执行部分程序。
本次项目也需要配置AndroidNDK,其过程非常繁琐,不过为了能够正常运行程序以及备忘,所以也记录在此:(我使用的IDE是Android Studio 1.5.1,NDK版本为Android NDK r10e)
首先,要想使用NDK,必须先根据Android官方文档修改build.gradle。链接为:http://tools.android.com/tech-docs/android-ndk-preview.修改后再对build..gradle进行EasyAR的相关配置。
对EasyAR的配置可以参考我的代码,也可以参考EasyAR的官方文档http://www.easyar.cn/view/documentapi.html.
容易遇到的问题:
如果你在修改了build.gradle之后,遇到了报错java.lang.UnsatisfiedLinkError: Couldn't load EasyAR from loader dalvik.system.PathClassLoader…… :findLibrary returned null.
这时候需要先CleanProject之后,再Rebuild Project,即可解决这个问题(这个错误研究了我一晚上才搞定……心好累)。
四、 界面说明
如上图所示:左图是APP的启动界面,右图是APP的操作界面。这是我第一次尝试为APP增加启动界面的设置。
主要步骤是:
1、 新建名为GuideActivity的Class和guide.xml的布局文件,绘制启动界面和过渡动画,并且在最后调用MainActivity,释放自己。
2、 在AndroidManifest.xml中增加GuideActivity的属性信息,并将其设置为默认启动的Activity。具体增加的配置信息如下:
<activity
android:name=".GuideActivity"
android:configChanges="orientation…">
<intent-filter>
<actionandroid:name="android.intent.action.MAIN"/>
<categoryandroid:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
在操作界面上有3个按钮,从左到右分别是“重播”、“打开网页”和“扫描二维码”。点击它们可以完成相应的功能。
五、 功能实现
首先,在MainActivity的开始处,需要先调用EasyAR的初始函数,并且创建GLView用于OpenGL绘图。
EasyAR.initialize(this, key); // 使用key初始化EasyAR引擎
nativeInit(); //设置匹配图片namecard和目标配置文件target.json
GLView glView =new GLView(this);
// 继承至SurfaceView,它内嵌的surface专门负责OpenGL渲染。
glView.setRenderer(new Render());
// glView 置于视图的顶部(覆盖显示)
glView.setZOrderMediaOverlay(true);
接下来设置3个按钮的监听函数,它们的OnClickListener都会调用相应的其他函数完成按钮对应的功能,而OnTouchListener则用于显示按钮不同状态下的图片,以达到点击按钮时的动画效果。
为了建立完整的AR场景,一个CameraDevice需要attached到ImageTracker,然后Augmenter需要周期性地从ImageTracker获取新的Frame。attach和newFrame操作让整个AR链条开始工作,而数据则在这个链条上流动。
从CameraDevice产生的Image会在每帧进入ImageTracker并推动tracker运行。这些Image将跟随Frame进入Augmenter。
Target从图像和json文件中构造出来,可以被加载进ImageTracker。当它被tracker检测或跟踪到,将会跟随Frame进入Augmenter。最终移动到AugmentedTarget。
下面介绍AR功能的实现:
在jni文件夹中有5个.cc/.hpp文件。他们是实现AR效果的核心代码。其中ar.hpp和ar.cc中定义了Class AR,实现了包括相机初始化、载入json、图片文件、视频的播放、停止、内存释放、OpenGL的刷新和Resize。
class AR
{
public:
AR();
virtual~AR();
virtualbool initCamera();
virtualvoid loadFromImage(const std::string& path);
virtualvoid loadAllFromJsonFile(const std::string& path);
virtualbool start();
virtualbool stop();
virtualbool clear();
virtualvoid initGL();
virtualvoid resizeGL(int width,int height);
virtualvoid render();
void setPortrait(bool portrait);
};
在helloarvideo.cc中实现了继承自Class AR的Class HelloARVideo,它在Class AR的基础上实现了从摄像头获取图像,并从中得到对应的ImageTargetID、二维码文本。Helloarvideo.cc中实现的若干JNI函数也是C++与Java代码的接口。
Renderer.hpp/.cc实现了通过相机的位姿和图片的位置,将视频流进行投影变换至合适的尺寸。它主要是为了helloarvideo.cc中的功能服务的。
Java文件中还有Render和GLView两个Class。其中Render负责调用MainActivity中在helloarvideo.cc里实现的函数。GLView负责增强后视频的绘制。详细信息可以参照代码中的注释进行了解。
六、 截图
下图蓝框所示部分即为实时播放的视频。
下图为扫描发现二维码的效果。
实际的使用效果可以参考视频AR画报.mp4(优酷链接:http://v.youku.com/v_show/id_XMTU4Mzg4MzY1Mg==.html)
Ø 【小结】
通过本次项目,我进一步熟悉了安卓编程。在之前实验的基础上,又掌握了多了个Activity的使用、Android NDK的使用等新的技能。与此同时,自己编写代码也让我对增强现实技术有了更深层次的了解,看起来十分酷炫的功能能够被自己实现出来,还是有满满的成就感的。
一学期的课程即将结束,我感觉还是收获颇丰的。虽然刚开始从未接触过Android编程,做起实验来非常吃力,但是在老师和助教师兄的指导和包容下,我还是一步一步走了下来。总而言之,这门课程非常值得一选,也希望课程能够越办越好!