使用机器学习模型在安卓平台实现图片识别、分类
2017年06月30日 由 Neo 发表
727802
0
前段时间苹果WWDC发布会,新的iOS11系统默认支持机器学习,写了一个关于图像识别的小示例,用的是Google提供的视觉模型,那么Google亲儿子安卓平台对于机器学习的支持如何那?
今天我们写一个在安卓端运行的机器学习的案例,首先AndroidStudio 版本需要2.0以上,可前往
此处下载对应平台的对应版本。
创建一个新的Android Studio工程,在这里我们使用在tensorflow已训练好的物体分类模型,模型将图片进行分类,把准备的训练模型文件tensorflow_inception_graph.pb和retrained_labels.txt文件放进assets文件夹内。
在主目录创建一个jniLibs文件夹,将.so包放到各自架构的子文件夹中。
完成了上述操作以后,我们就可以使用Tensorflow api了,通过TensorFlowInferenceInterface开放了我们所需要的全部接口。现在我们就能够用模型文件的路径调用并且加载tensorflow,输入一张图片来获取预测的结果。
在需要调用模型的.java文件中,导入包:
- import org.tensorflow.contrib.android.TensorFlowInferenceInterface
在该java类定义的首行,导入so文件:
{
System.loadLibrary(“tensorflow_inference”)
}
1)创建自定义Config文件用来初始化模型调用时所需的参数
public static final String MODEL_FILE = “file:///android_asset/stripped_graph.pb” //模型存放路径
public static final String INPUT_NODE = “input”; //输入变量的名称
public static final String INPUT_NODE = “output”; //输出变量的名称
public static final int NUM_CLASSES = 10; //样本集的类别数量
public static final int HEIGHT = 224; //图片高
public static final int WIDTH = 224; //图片宽
public static final int CHANNEL = 3; //通道数:RGB
public floats inputs = new float[HEIGHT*WIDTH*CHANNEL]; //用于存储的模型输入数据
public floats outputs = new float[NUM_CLASSES]; //用于存储模型的输出数据
2)Tensorflow 接口初始化
private TensorFlowInferenceInterface inferenceInterface = new TensorFlowInferenceInterface();
inferenceInterface.initializeTensorFlow(getAssets(), MODEL_FILE);
在完成上述两步之后,就可以反复调用模型。
3)TF模型的调用
处理获取到的图片给图像传入给图像模型
public static Bitmap resizeBitmap(Bitmap bitmap) {
try {
// resize
int width = bitmap.getWidth();
int height = bitmap.getHeight();
float scaleWidth = ((float) Config.INPUT_SIZE) / width;
float scaleHeight = ((float) Config.INPUT_SIZE) / height;
Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight);
Bitmap newbm = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);
return newbm;
} catch (Exception e) {
return null;
}
}
//初始化TensorFlowImageClassifier
classifier = new TensorFlowImageClassifier();
try {
classifier.initializeTensorFlow(
getAssets(), Config.MODEL_FILE, Config.LABEL_FILE,
Config.NUM_CLASSES, Config.INPUT_SIZE, Config.IMAGE_MEAN, Config.IMAGE_STD, Config.INPUT_NAME, Config.OUTPUT_NAME);
} catch (final IOException e) {
}
//调用识别图片
try {
// resize
Bitmap newbm =
resizeBitmap(bitmap); List results=classifier.recognizeImage(newbm) } catch (Exception e) { }
在最后返回的Recognition数组里面就是图像识别的结果了,结果是一个扫描出来的数组,有该识别物体的类别名、识别率等数据。
最后看看效果:
72%风景,23%建筑
动物,可能图片里面东西太多,识别出了人群....总体来说识别率还是可以。
总结:在安卓平台实现这个demo花费的时间比iOS要多得多,iOS因为有新的ML框架,实现起来只需要导入学习框架,Xcode会自动生成解析类,只需要调用这个解析类来识别图片即可,Android Studio则需要很多的前置准备条件,需要下载安卓平台所需的jar包,.so文件,还需要将tensorflow训练好的模型.pb文件导入到项目,这个案例使用的是一个已经训练好的物体分类模型,在集成过程中因为Android Studio版本问题,还有安卓sdk版本问题出现了模型解析类编译报错等一系列问题,最后不得不更新AndroidStudio和sdk编译版本,这个案例在AS2.2,Android6.0编译环境下完成并且成功运行。
由于训练完的模型是存在设备本地的,识别效率也非常快,基本察觉不到延时,但是和iOS一样,模型文件本身是占用一定空间的,这样就会导致软件安装所占用的空间会略大,本文示例安装完的后的软件包是95M,iOS使用Google Restnet50模型生成的安装ipa文件大小是118M。
代码:
[download id="2"]