Android应用开发实践-茶树害虫识别App

一、项目介绍

1 项目背景

茶树是我国的重要经济作物,防治茶树害虫有着重大意义。然而茶树病虫害不仅种类多,而且发生情况严重,茶园多处山地或丘陵地带,现场病虫害诊断和防治困难,为茶叶的生产带来严重威胁,因此迫切需要病虫害识别、诊断、发现、监测预警信息系统。保证茶叶优质高产的重要措施之一就是快速高效地识别害虫并采取应对措施。本项目旨在以茶树害虫的图像为基础,运用TensorFlow训练深度学习模型,并将模型移植到安卓手机上,最终在茶树害虫识别的任务中快速有效地识别害虫。

2 开发工具

2.1 Android Studio

Google公司专门为开发Android应用程序提供了集成开发环境Android Studio,涵盖了所有Android应用开发相关的功能。Android应用程序主要使用Java语言编写,要用到开发工具集SDKSoftware Development Kit,提供java编译工具、Android系统API等,可以直接在Android Studio中下载)。当应用程序中要直接访问硬件,或者需要提高运行效率时,需要将访问硬件、复杂逻辑部分使用C/C++实现。要在Android Studio中开发编译C/C++代码,需要用到工具集NDKNative Development Kit,提供C/C++编译工具、API、打包工具等,可直接在Android Studio中下载)。使用NDK可以将C/C++源码编译成动态链接库,供Java调用。由于Java语言要调用C/C++函数需要用到JNIJava Native Interface)技术,这就要求使用NDK开发C/C++时,C/C++源码要符合JNI规范要求。

2.2 TensorFlow

TensorFlow谷歌基于DistBelief进行研发的第二代人工智能学习系统,其命名来源于本身的运行原理。Tensor(张量)意味着N维数组,Flow(流)意味着基于数据流图的计算,TensorFlow为张量从流图的一端流动到另一端计算过程。TensorFlow是将复杂的数据结构传输至人工智能神经网中进行分析和处理过程的系统。

TensorFlow可被用于语音识别图像识别等多项机器学习和深度学习领域,对2011年开发的深度学习基础架构DistBelief进行了各方面的改进,它可在小到一部智能手机、大到数千台数据中心服务器的各种设备上运行。TensorFlow将完全开源,任何人都可以用。

2.3 TensorFlow Lite

TensorFlow LiteTensorFlow针对移动和嵌入式设备的轻量级解决方案。它使设备上的机器学习预测具有低延迟和小的二进制大小。 TensorFlow Lite还支持硬件加速Android神经网络API

TensorFlow Lite使用许多技术来实现低延迟,如优化移动应用程序的内核,pre-fused**以及允许更小和更快的(fixed-point数学)模型的量化内核。

TensorFlow Lite支持一系列数量化和浮点的核心运算符,这些核心运算符已针对移动平台进行了优化。它们结合pre-fused**和偏差来进一步提高性能和量化精度。此外,TensorFlow Lite还支持在模型中使用自定义操作。

TensorFlow Lite定义了一个新的模型文件格式,基于FlatBuffersFlatBuffers是一个开源的高效的跨平台序列化库。它与协议缓冲区类似,但主要区别在于,FlatBuffers在访问数据之前不需要解析/解包步骤到二级表示,通常与per-object内存分配结合使用。此外,FlatBuffers的代码尺寸比协议缓冲区小一个数量级。

TensorFlow Lite有一个新的基于移动设备优化的解释器,其主要目标是保持应用程序的精简和快速。解释器使用静态图形排序和自定义(less-dynamic)内存分配器来确保最小的负载,初始化和执行延迟。

TensorFlow Lite提供了一个接口来利用硬件加速(如果在设备上可用)。它是通过Android神经网络库,作为Android O-MR1的一部分发布的。

TensorFlow Lite可作为开发人员预览的点,包括以下内容:

·一组核心操作符,既有数量化也有浮点值,其中很多已经针对移动平台进行了调优。这些可以用来创建和运行自定义模型。开发人员也可以编写自己的自定义操作符并在模型中使用它们。

·一个新的FlatBuffers基于模型的文件格式。

·On-device解释器,内核经过优化,可在移动设备上更快执行。

·TensorFlow转换器将TensorFlow-trained模型转换为TensorFlow Lite格式。

·规模较小:当所有支持的操作符链接时,TensorFlow Lite小于300KB,而仅使用支持InceptionV3Mobilenet所需的操作符时,TensorFlow Lite小于200KB

·预训练好的模型:

以下所有型号均可保证开箱即用:

·Inception V3是一种流行的模型,用于检测图像中存在的主要对象。

·MobileNetsmobile-first系列计算机视觉模型,旨在有效提高准确性,同时注意on-device或嵌入式应用程序的受限资源。它们很小,低延迟,低功耗,模型参数化,以满足各种用例的资源约束。它们可以建立在分类,检测,嵌入和分割之上。 MobileNet模型比较小,但是比Inception V3准确度较低

·在设备智能回复上,提供one-touchon-device模型,能通过建议上下文相关的消息来回复传入的文本消息。该模型专为内存受限的设备而建立,例如手表&手机,它已被成功使得Android Wear上的智能回复应用于所有first-partythird-party应用程序。

·MobileNet模型的量化版本,其运行速度比CPU上的non-quantized(浮点)版本快。

·新的Android演示应用程序来说明使用TensorFlow Lite与量化的MobileNet模型进行对象分类。

·JavaC++ API支持

2.4 QUMI_Android

QMUI Android 的设计目的是用于辅助快速搭建一个具备基本设计还原效果的 Android 项目,同时利用自身提供的丰富控件及兼容处理,让开发者能专注于业务需求而无需耗费精力在基础代码的设计上。不管是新项目的创建,或是已有项目的维护,均可使开发效率和项目质量得到大幅度提升。其功能有如下几类:

①全局UI配置:只需要修改一份配置表就可以调整 App 的全局样式,包括组件颜色、导航栏、对话框、列表等。一处修改,全局生效。

②丰富的UI控件:提供丰富常用的 UI 控件,例如 BottomSheetTab、圆角ImageView、下拉刷新等,使用方便灵活,并且支持自定义控件的样式。

③高效的工具方法:提供高效的工具方法,包括设备信息、屏幕信息、键盘管理、状态栏管理等,可以解决各种常见场景并大幅度提升开发效率。


二、项目分工

·辛岑:总体规划,功能模块设计,拍照并保存照片功能的实现,UI优化;

·周恒:搜集茶树害虫图片,训练模型,害虫识别模块的实现,测试程序。

三、功能模块设计

1 概要设计

App需要具备实时拍照并实时识别茶树害虫的功能。具体而言,用户打开App后可以看见一个拍照的窗口以及两个按钮:①切换摄像头(前/后),②检测目标。在检测到目标后,空白处会显示拍摄到的照片,以及检测出害虫的种类名称。

2 详细设计

2.1 拍照并保存

Android内部提供了一个内部类android.view.SurfaceHolder这个类,这个类提供了SurfaceView,这个类可以帮助我们实现照相功能。SurfaceView想必都很熟悉了,使用它我们还可以进行视频音频的播放。在这个类的基础上,我们还可以通过Camera类提供的内部方法,对相机的参数进行一些相应的设置,以达到我们拍照时想要的效果。Camera内部还定义了若干个接口来完成一些相应的操作,比如说按下快门的时候要处理什么样的操作。通过Camera来操控摄像头需要按照步骤来:

1. 首先调用Cameraopen方法来打开摄像头;

2. 接着调用getParammeters来获取相机的参数;

3. 设置相机的相应参数,来达到我们想要的效果;

4. 调用setParammeters来讲我们设置的参数传递到相机,达到我们拍照时想要出现的效果;

5. 在我们进行拍照的时候我们必然需要先进行预览全景,在预览的某一时刻进行拍照,那么这个预览必然就需要一个SurfaceView来帮助我们来显示当前我们预览的场景;

6. 开始拍照...获取图片,然后对图片进行保存,最后释放内存。

简单说一下java文件里如何实现拍照的一个思路。首先我们必然需要打开一个摄像头,然后接着我们需要获取摄像头的参数,然后自定义我们拍照时想要的一些设置,这些设置那么必然需要先传递到摄像头,否则不进行传递的话,摄像头也就不会按照我们设置的参数进行工作。因此我们需要传递参数,传递完参数后,我们就需要进行拍照了,在拍照的时候,我们需要预览景观,那么预览的功能就需要使用到SurfaceView,这个类定义一个表面的视图控件,说白了就是需要一块面积来显示现在用户想看到的东西,然后在预览的时候我们就可以进行拍照了,拍照需要使用takepicture()这个方法来完成,然后获取到图片,最后我们把照片数据通过IO流来写入到内存当中,最后进行保存。

最后我们需要获取一些权限,需要在AndroidManifest.xml文件内部进行权限设置。

2.2 检测目标

首先,在使用python代码编写的TF模型定义中为模型的输入层和输出层Tensor Variable分别指定名字(通过形参‘name’)。名字可以随便起,以方便好记为主,后面还会反复用到。

将使用TensorFlow训练好的模型保存为.pb文件。在模型训练结束后的代码位置,添加下述两句代码,可将模型保存为.pb文件:

output_graph_def=tf.graph_until.convert_variables_to_constants(session,session.graph_def, output_node_names=[output])

with tf.gfile.FastGFile(model\mnist.pb, mode = wb) as f:

f.write(output_graph_def.SerializeToString())

第一个参数用于指定输出的文件存放路径、文件名及格式。我把它放在与代码同级目录的model文件下,取名为mnist.pb

第二个参数 mode用于指定文件操作的模式,’wb’中w代表写文件,b代表将数据以二进制方式写入文件。

如果不指明b’,则默认会以文本txt方式写入文件。现在TF还不支持对文本格式.pb文件的解析,在调用时会出现报错。

注:
①不能使用 tf.train.write_graph()保存模型,因为它只是保存了模型的结构,并不保存训练完毕的参数值
②不能使用 tf.train.saver()保存模型,因为它只是保存了网络中的参数值,并不保存模型的结构。
很显然,我们需要的是既保存模型的结构,又保存模型中每个参数的值。以上两者皆不符合。

然后生成在Android平台上调用tensorflow 模型需要的jar包和so文件。创建接口实现调用:先导入jar包和so文件,定义变量及对象,TensorFlow接口初始化,TF模型调用。

四、界面截图

Android应用开发实践-茶树害虫识别App

Android应用开发实践-茶树害虫识别App

Android应用开发实践-茶树害虫识别App

Android应用开发实践-茶树害虫识别App

五、感悟和体会

本项目着重将传统的安卓App与最新的深度学习技术相结合。我们在学会经典安卓开发的同时,也融入了深度学习的应用。小组合作项目中最重要的是团结,每次商量对策后我们都有相应的总结和提升,在不断的讨论和修改中,最终将整个项目完成。

本项目中的两个难点分别是摄像头的使用和Tensorflow模型的应用。在摄像头的使用中,我们查阅了大量的技术资料,总结出一套完整的摄像头调用流程,经过了多次的测试,失败,再测试,再失败之后,终于调用成功。Tensorflow模型训练也是非常不容易的,首先是搜集图片,然而图片严重不足,我们采用了随机旋转和镜像变换的技术以增加图片的数量。然后是训练模型,本项目中最耗时间的一部分。在训练为.pb文件后,我们又查阅了相关调用的API函数,在不断的努力下,最终取得成功。

这只是一个小小的项目,在实际应用中会有着更加复杂的逻辑关系和技术应用。我们要以这次项目为基础,学习更多安卓开发相关的内容,在未来的学习和工作中,变得更有竞争力。

(更多详细内容请参见课程设计的技术报告)