一、前言
本设计为基于TensorFlow2.3.0的花卉识别Android APP。TensorFlow2.3.0的API简单易用,训练好后模型导出tflite格式供Anroid APP使用。
开发环境:
- Windows 10
- Python 3.7.3
- TensorFlow 2.3.0
- Anaconda 4.12.0
二、准备数据集
准备"雏菊", "蒲公英","玫瑰","向日葵", "郁金香"5种花卉的图片,数据量越多越好。
三、训练模型
执行train_model.py训练模型
四、导出tflite格式模型
Android端使用的是tflite格式模型文件,因此使用TFLiteConverter转换为.tflite格式模型,代码如下:
import tensorflow as tf
model = tf.keras.models.load_model("model.h5")
converter = tf.lite.TFLiteConverter.from_keras_model(model)
tflite_model = converter.convert()
open("model.tflite", "wb").write(tflite_model)
五、编写Android APP
1. 编写布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="50dp"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="基于TensorFlow的花卉识别"
android:textColor="@color/black"
android:textSize="25sp" />
<androidx.cardview.widget.CardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
app:cardCornerRadius="20dp">
<ImageView
android:id="@+id/iv_flower"
android:layout_width="200dp"
android:layout_height="200dp"
android:scaleType="centerCrop"
android:src="@drawable/tulips" />
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="10dp"
app:cardCornerRadius="20dp">
<ScrollView
android:layout_width="wrap_content"
android:layout_height="320dp"
android:layout_margin="10dp"
android:layout_marginTop="10dp">
<TextView
android:id="@+id/tv_flower_detail"
android:layout_width="360dp"
android:layout_height="200dp"
android:text="@string/tulips"
android:textColor="@color/black"
android:textSize="18sp" />
</ScrollView>
</androidx.cardview.widget.CardView>
<Button
android:id="@+id/choose_image"
android:layout_width="230dp"
android:layout_height="50dp"
android:layout_gravity="center"
android:layout_marginTop="50dp"
android:background="@drawable/angle_button"
android:onClick="choose_image"
android:text="选择图片"
android:textColor="@android:color/white"
android:textSize="20sp" />
</LinearLayout>
效果图:
2. 编写MainActivity代码
private String[] neededPermissions = new String[]{
Manifest.permission.READ_PHONE_STATE
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = this.getWindow();
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(Color.GRAY);
}
setContentView(R.layout.activity_main);
/*
* 在选择图片的时候,在android 7.0及以上通过FileProvider获取Uri,不需要文件权限
*/
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
List<String> permissionList = new ArrayList<>(Arrays.asList(neededPermissions));
permissionList.add(Manifest.permission.READ_EXTERNAL_STORAGE);
neededPermissions = permissionList.toArray(new String[0]);
}
initView();
TFLiteLoader loader = TFLiteLoader.newInstance(this);
interpreter = loader.get();
showToast("模型加载成功!");
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.tulips);
}
private void initView() {
tv_flower_detail = findViewById(R.id.tv_flower_detail);
iv_flower = findViewById(R.id.iv_flower);
}
private void showToast(String text) {
Toast.makeText(this, text, Toast.LENGTH_LONG).show();
}
// 更换图片
public void choose_image(View view) {
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
startActivityForResult(intent, 0);
}
private int maxIndex = 0;
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (data == null || data.getData() == null) {
showToast("获取图片失败");
return;
}
try {
bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), data.getData());
} catch (IOException e) {
e.printStackTrace();
}
// 识别图片
detect_image();
// 更新显示的图片
iv_flower.setImageBitmap(bitmap);
// 更新花卉的介绍
tv_flower_detail.setText(flower_detail[maxIndex]);
}
// 识别图片
public void detect_image() {
// bitmap convert to array
float[][][][] pixels = getScaledMatrix(bitmap, ddims);
interpreter.run(pixels, output);
for (int j = 0; j < 5; j++) {
BigDecimal b = new BigDecimal(output[0][j]);
float f1 = b.setScale(3, BigDecimal.ROUND_HALF_UP).floatValue();
Log.i("Test", f1 + "--> "+ j);
}
float max =output[0][0];
for(int i = 1; i < 5;i++){
if(max < output[0][i]){
max = output[0][i];
maxIndex = i;
}
}
String text = class_names[maxIndex];
// 显示Toast
showToast(text);
}
六、实际运行效果
七、资料下载
APK下载 flower.apk - 蓝奏云
APP源码下载 https://item.taobao.com/item.htm?ft=t&id=681144452049
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)