基于TensorFlow2.3.0的花卉识别Android APP设计

2023-05-16

一、前言

        本设计为基于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);
        

    }

六、实际运行效果

基于TensorFlow花卉识别

七、资料下载

APK下载 flower.apk - 蓝奏云

APP源码下载 https://item.taobao.com/item.htm?ft=t&id=681144452049

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于TensorFlow2.3.0的花卉识别Android APP设计 的相关文章

随机推荐

  • 常用Log抓取方法

    1 最常用抓取方法 尽可能保存issue现场 xff0c 记录issue时间 adb pull data logs 2 使用电脑cmd连接device xff0c 并使之正常输出logcat信息 adb logcat gt 路径 main
  • jq获取和设置标签的css样式、jq给标签增加或移除class属性

    1 jQuery获取和设置标签的css样式 jQuery既可以直接获取标签的css样式 xff0c 也可以设置样式 xff0c 包括行内 内部 外部样式 xff1b 思路 xff1a 先要选取这个标签 xff0c 然后再获取或者设置样式 x
  • LwIP多TCP连接问题

    多个TCP连接的问题困扰了我很久 xff0c 前段时间解决了这个问题 xff0c 现在写下我的感受 xff1a 多个TCP可以绑定多个端口 xff0c 这里我是绑定一个端口 xff0c 这样更加复合实际应用 xff08 我的多个TCP的功能
  • GitHub Pages 绑定个人域名

    文章目录 一 购买域名二 配置域名解析三 GitHub Pages 绑定个人域名四 本地设置 CNAME五 重新发布网站 之前我们已经使用 github 搭建好了个人网站 xff0c 可以通过 xxx github io 来访问自己的网站
  • Pycharm提示 Unresolved reference 的解决办法

    有时候a py和b py在一个目录里面 xff0c 但是在a py种写import b有时会提示Unresolved reference xff0c Pycharm常见 xff0c 解决办法是setting gt Project gt Pr
  • 解决idea新建maven项目时一直loading问题

    idea里新建maven项目时 xff0c 在create from archetype时 xff0c 一直显示loading archetype list 原因 idea一直读自己的配置里缓存导致的 解决 方案一 把 C Users Ad
  • 安装windows时install.wim文件过大的解决方案

    安装windows时install wim文件过大的解决方案 问题描述解决方法 问题描述 windows镜像文件中 xff0c install wim大于4GB 直接解压镜像到u盘制作启动盘的方法只能用fat32格式 xff0c 不支持大于
  • Ubuntu 14 桌面图标消失解决办法

    1 使用ctrl 43 alt 43 F1进入字符命令界面 xff0c 登录账户 2 使用命令mv config config bk xff0c 相当于删除备份文件 xff0c 重启后页面正常
  • 在vue项目中使用Lottie动画(随看随用)

    前言 xff1a Lottie是一个IOS xff0c Android和React Native库 xff0c 可以实时渲染动画 xff0c 动画被转化成JSON文件 xff0c 节省了很多资源 xff0c 允许应用程序像使用静态图像一样轻
  • 对于python中“FileNotFoundError: [Errno 2] No such file or directory”的解决办法

    在我们使用vscode运行Python代码时遇到的情况 一 出现原因 xff1a 这里是由于Vscode中 xff0c python里的路径是相对与工作目录来进行定位的 所以在多级目录情况下 xff0c 若不设置绝对路径 xff0c 往往找
  • 《构建Debian的精彩世界》

    2007 10 06 星期六 12 04 darkblue 这段时间在公司一直使用Ubuntu系统 xff0c 其实刚来的时候用的是Debian xff0c 也是我头一次安装 配置和使用Debian系统 后来为了统一开发环境 xff0c 才
  • 由于找不到VCRUNTIME140_1.dll,无法继续执行代码。重新安装程序可能会解决此问题

    重装office之后双击Excel和PowerPoint无法正常打开 并弹出如下提示 并且 docx文件和 xls文件图标变成了下图所示 双击 docx xff0c 弹出Global Labeling Management Print To
  • Java 在Linux使用crontab进行定时任务设置并执行jar

    需求 xff1a 通过java执行linux命令 xff0c 通过crontab定时执行jar 通过java执行定时任务时需要监理shell文件和一个txt文件 xff0c 通过将txt文件设置到crontab中 xff0c 定时调用 sh
  • apache配置多个版本php

    主要虚拟主机配置信息 FcgidInitialEnv PHPRC D phpstudy php55n 指定php目录 AddHandler fcgid script php FcgidWrapper D phpstudy php55n ph
  • 解决 Could not find com.android.tools.build:gradle 问题

    现在CSDN的文章也不靠谱 xff0c 都是复制粘贴 回到问题 repositories 也设置了 下载 gradle 6 8 1 all zip setting gradle use gradle from 选择 gradle wrapp
  • #移动开发者大会#总结

    移动开发者大会 总结 xff08 有限的发言者 xff09 xff1a 李开复 xff1a 1 Android将在中国一骑绝尘 今年底中国将有4000万台Android手机 xff0c 2000万台iPhone 明年底总数会翻一倍 xff0
  • 2011河北金融学院CSDN高校俱乐部动员大会

    2011年11月24日下午二点 xff0c 我校CSDN高校俱乐部动员大会在教学楼B123举行 该次大会主要针对大一学生召开 xff0c 号召大家了解并加入CSDN高校俱乐部 俱乐部指导老师王洪涛老师 计算机协会指导老师杜光辉老师 以及优秀
  • “激情与梦想 我的程序员之路”—2012高校巡讲

    2012年3月29日下午2点半 xff0c CSDN高校俱乐部项目主管潘永强老师在我校进行了一场以 激情与梦想 xff0c 我的程序员之路 为主题的演讲 信息管理与工程系团总支书记陈春燕 指导老师王洪涛以及杜光辉 刘冲等7位老师出席了该次讲
  • Linux基础.交叉编译工具链,makefile

    一 交叉工具链大纲 1 什么是交叉工具链 xff1f 什么是交叉编译 xff1f 2 安装交叉工具链方法 xff0c 结合环境变量PATH xff0c 工具链选项 3 Makefile使用 xff0c Makefile书写规则 4 嵌入式静
  • 基于TensorFlow2.3.0的花卉识别Android APP设计

    一 前言 本设计为基于TensorFlow2 3 0的花卉识别Android APP TensorFlow2 3 0的API简单易用 xff0c 训练好后模型导出tflite格式供Anroid APP使用 开发环境 xff1a Window