当前位置: 首页 > news >正文

Android 中集成 TensorFlow Lite图片识别

c5494e0d0040a885c764744a2cc414f6.png

在上图通过手机的相机拍摄到的物体识别出具体的名称,这个需要通过TensorFlow 训练的模型引用到项目中;以下就是详细地集成 TensorFlow步骤,请按照以下步骤进行操作:

  1. 在项目的根目录下的 build.gradle 文件中添加 TensorFlow 的 Maven 仓库。在 repositories 部分添加以下行:

allprojects {repositories {// 其他仓库...maven {url 'https://google.bintray.com/tensorflow'}}
}
  1. 在应用的 build.gradle 文件中添加 TensorFlow Lite 的依赖。在 dependencies 部分添加以下行:

implementation 'org.tensorflow:tensorflow-lite:2.5.0'
  1. 将 TensorFlow Lite 模型文件添加到你的 Android 项目中。将模型文件(.tflite)复制到 app/src/main/assets 目录下。如果 assets 目录不存在,可以手动创建。

  2. 创建一个 TFLiteObjectDetectionAPIModel类,用于加载和运行 TensorFlow Lite 模型。以下是一个示例代码:

import org.tensorflow.lite.Interpreter;
public class TFLiteObjectDetectionAPIModel implements Classifier {private static final Logger LOGGER = new Logger();// Only return this many results.private static final int NUM_DETECTIONS = 10;// Float modelprivate static final float IMAGE_MEAN = 128.0f;private static final float IMAGE_STD = 128.0f;// Number of threads in the java appprivate static final int NUM_THREADS = 4;private boolean isModelQuantized;// Config values.private int inputSize;// Pre-allocated buffers.private Vector<String> labels = new Vector<String>();private int[] intValues;// outputLocations: array of shape [Batchsize, NUM_DETECTIONS,4]// contains the location of detected boxesprivate float[][][] outputLocations;// outputClasses: array of shape [Batchsize, NUM_DETECTIONS]// contains the classes of detected boxesprivate float[][] outputClasses;// outputScores: array of shape [Batchsize, NUM_DETECTIONS]// contains the scores of detected boxesprivate float[][] outputScores;// numDetections: array of shape [Batchsize]// contains the number of detected boxesprivate float[] numDetections;private ByteBuffer imgData;private Interpreter tfLite;private TFLiteObjectDetectionAPIModel() {}/** Memory-map the model file in Assets. */private static MappedByteBuffer loadModelFile(AssetManager assets, String modelFilename)throws IOException {AssetFileDescriptor fileDescriptor = assets.openFd(modelFilename);FileInputStream inputStream = new FileInputStream(fileDescriptor.getFileDescriptor());FileChannel fileChannel = inputStream.getChannel();long startOffset = fileDescriptor.getStartOffset();long declaredLength = fileDescriptor.getDeclaredLength();return fileChannel.map(FileChannel.MapMode.READ_ONLY, startOffset, declaredLength);}/*** Initializes a native TensorFlow session for classifying images.** @param assetManager The asset manager to be used to load assets.* @param modelFilename The filepath of the model GraphDef protocol buffer.* @param labelFilename The filepath of label file for classes.* @param inputSize The size of image input* @param isQuantized Boolean representing model is quantized or not*/public static Classifier create(final AssetManager assetManager,final String modelFilename,final String labelFilename,final int inputSize,final boolean isQuantized)throws IOException {final TFLiteObjectDetectionAPIModel d = new TFLiteObjectDetectionAPIModel();InputStream labelsInput = null;String actualFilename = labelFilename.split("file:///android_asset/")[1];labelsInput = assetManager.open(actualFilename);BufferedReader br = null;br = new BufferedReader(new InputStreamReader(labelsInput));String line;while ((line = br.readLine()) != null) {LOGGER.w(line);d.labels.add(line);}br.close();d.inputSize = inputSize;try {d.tfLite = new Interpreter(loadModelFile(assetManager, modelFilename));} catch (Exception e) {throw new RuntimeException(e);}d.isModelQuantized = isQuantized;// Pre-allocate buffers.int numBytesPerChannel;if (isQuantized) {numBytesPerChannel = 1; // Quantized} else {numBytesPerChannel = 4; // Floating point}d.imgData = ByteBuffer.allocateDirect(1 * d.inputSize * d.inputSize * 3 * numBytesPerChannel);d.imgData.order(ByteOrder.nativeOrder());d.intValues = new int[d.inputSize * d.inputSize];d.tfLite.setNumThreads(NUM_THREADS);d.outputLocations = new float[1][NUM_DETECTIONS][4];d.outputClasses = new float[1][NUM_DETECTIONS];d.outputScores = new float[1][NUM_DETECTIONS];d.numDetections = new float[1];return d;}@Overridepublic List<Recognition> recognizeImage(final Bitmap bitmap) {// Log this method so that it can be analyzed with systrace.Trace.beginSection("recognizeImage");Trace.beginSection("preprocessBitmap");// Preprocess the image data from 0-255 int to normalized float based// on the provided parameters.bitmap.getPixels(intValues, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());imgData.rewind();for (int i = 0; i < inputSize; ++i) {for (int j = 0; j < inputSize; ++j) {int pixelValue = intValues[i * inputSize + j];if (isModelQuantized) {// Quantized modelimgData.put((byte) ((pixelValue >> 16) & 0xFF));imgData.put((byte) ((pixelValue >> 8) & 0xFF));imgData.put((byte) (pixelValue & 0xFF));} else { // Float modelimgData.putFloat((((pixelValue >> 16) & 0xFF) - IMAGE_MEAN) / IMAGE_STD);imgData.putFloat((((pixelValue >> 8) & 0xFF) - IMAGE_MEAN) / IMAGE_STD);imgData.putFloat(((pixelValue & 0xFF) - IMAGE_MEAN) / IMAGE_STD);}}}Trace.endSection(); // preprocessBitmap// Copy the input data into TensorFlow.Trace.beginSection("feed");outputLocations = new float[1][NUM_DETECTIONS][4];outputClasses = new float[1][NUM_DETECTIONS];outputScores = new float[1][NUM_DETECTIONS];numDetections = new float[1];Object[] inputArray = {imgData};Map<Integer, Object> outputMap = new HashMap<>();outputMap.put(0, outputLocations);outputMap.put(1, outputClasses);outputMap.put(2, outputScores);outputMap.put(3, numDetections);Trace.endSection();// Run the inference call.Trace.beginSection("run");tfLite.runForMultipleInputsOutputs(inputArray, outputMap);Trace.endSection();// Show the best detections.// after scaling them back to the input size.final ArrayList<Recognition> recognitions = new ArrayList<>(NUM_DETECTIONS);for (int i = 0; i < NUM_DETECTIONS; ++i) {final RectF detection =new RectF(outputLocations[0][i][1] * inputSize,outputLocations[0][i][0] * inputSize,outputLocations[0][i][3] * inputSize,outputLocations[0][i][2] * inputSize);// SSD Mobilenet V1 Model assumes class 0 is background class// in label file and class labels start from 1 to number_of_classes+1,// while outputClasses correspond to class index from 0 to number_of_classesint labelOffset = 1;recognitions.add(new Recognition("" + i,labels.get((int) outputClasses[0][i] + labelOffset),outputScores[0][i],detection));}Trace.endSection(); // "recognizeImage"return recognitions;}@Overridepublic void enableStatLogging(final boolean logStats) {}@Overridepublic String getStatString() {return "";}@Overridepublic void close() {}public void setNumThreads(int num_threads) {if (tfLite != null) tfLite.setNumThreads(num_threads);}@Overridepublic void setUseNNAPI(boolean isChecked) {if (tfLite != null) tfLite.setUseNNAPI(isChecked);}
}

确保替换 modelPath 参数为你的模型文件在 assets 目录中的路径。

  1. 在你的应用程序中使用 TFLiteObjectDetectionAPIModel 类进行推理。以下是一个简单的示例:

@Override
public void onPreviewSizeChosen(final Size size, final int rotation) {final float textSizePx =TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, TEXT_SIZE_DIP, getResources().getDisplayMetrics());borderedText = new BorderedText(textSizePx);borderedText.setTypeface(Typeface.MONOSPACE);tracker = new MultiBoxTracker(this);int cropSize = TF_OD_API_INPUT_SIZE;try {detector =TFLiteObjectDetectionAPIModel.create(getAssets(),TF_OD_API_MODEL_FILE,TF_OD_API_LABELS_FILE,TF_OD_API_INPUT_SIZE,TF_OD_API_IS_QUANTIZED);cropSize = TF_OD_API_INPUT_SIZE;} catch (final IOException e) {e.printStackTrace();LOGGER.e(e, "Exception initializing classifier!");Toast toast =Toast.makeText(getApplicationContext(), "Classifier could not be initialized", Toast.LENGTH_SHORT);toast.show();finish();}
// 解析输出数据
// ...

根据你的模型和任务,你可能需要根据模型的规范和文档来解析输出数据。

cc8d5bde50aea06a58a14a2b5b0820b9.png

输出解析文本数据

需要项目源码私聊

相关文章:

Android 中集成 TensorFlow Lite图片识别

在上图通过手机的相机拍摄到的物体识别出具体的名称&#xff0c;这个需要通过TensorFlow 训练的模型引用到项目中&#xff1b;以下就是详细地集成 TensorFlow步骤&#xff0c;请按照以下步骤进行操作&#xff1a; 在项目的根目录下的 build.gradle 文件中添加 TensorFlow 的 Ma…...

NSSCTF之Misc篇刷题记录(16)

NSSCTF之Misc篇刷题记录&#xff08;16&#xff09; [黑盾杯 2020]encrypt[UTCTF 2020]Spectre[UTCTF 2020]Observe closely NSSCTF平台&#xff1a;https://www.nssctf.cn/ PS&#xff1a;所有FLAG改为NSSCTF [黑盾杯 2020]encrypt UTAxSlUwTkRWRVo3Um1GclpWOWxibU55ZVhCMGFX…...

域名解析--nslookup和dig

dig (Domain Information Groper) dig 是一个功能强大且更灵活的 DNS 查询工具&#xff0c;通常在 Linux 和 macOS 等 Unix-like 操作系统上使用。以下是 dig 的一些常见用法和区别&#xff1a; 查询域名信息 dig example.com这将返回与指定域名相关的 DNS 记录&#xff0c;…...

EXCEL如何把一个单元格内的文本和数字分开?例如:龚龚15565 = 龚龚 15565

使用工具&#xff1a;WPS 举例&#xff1a; EXCEL如何把一个单元格内的文本和数字批量分开&#xff1f;不使用数据分列。 第一步、将第二行数据冻结 第二步、在B1、C1单元格输入需要分开的示例 第三步、点击选中B1单元格&#xff0c;输入快捷键【CTRLE】进行填充。B2单元格也是…...

uniapp抽取组件绑定事件中箭头函数含花括号无法解析

版本: "dcloudio/uni-ui": "^1.4.27", "vue": "> 2.6.14 < 2.7"... 箭头函数后含有花括号的时候, getData就拿不到val参数 , 解决办法就是去除花括号 // 错误代码: <SearchComp change"(val) > { getData({ val …...

猫头虎博主第四期赠书活动:《精通Go语言:(第2版) 》

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…...

【学习总结】EasyExcel合并同列不同行,表格数据相同的行

实体类 Data HeadRowHeight(50) ContentStyle(horizontalAlignment HorizontalAlignmentEnum.CENTER, verticalAlignment VerticalAlignmentEnum.CENTER, wrapped BooleanEnum.TRUE) public class CriterionDataExportDTO {ColumnWidth(15)ExcelProperty(value "所属…...

Tokenview X-ray功能:深入探索EVM系列浏览器的全新视角

Tokenview作为一家领先的多链区块浏览器&#xff0c;为了进一步优化区块链用户的使用体验&#xff0c;我们推出了X-ray&#xff08;余额透视&#xff09;功能。该功能将帮助您深入了解EVM系列浏览器上每个地址的交易过程&#xff0c;以一种直观、简洁的方式呈现地址的进出账情况…...

【洛谷 P1364】医院设置 题解(图论+深度优先搜索)

医院设置 题目描述 设有一棵二叉树&#xff0c;如图&#xff1a; 其中&#xff0c;圈中的数字表示结点中居民的人口。圈边上数字表示结点编号&#xff0c;现在要求在某个结点上建立一个医院&#xff0c;使所有居民所走的路程之和为最小&#xff0c;同时约定&#xff0c;相邻接…...

【Java基础】- RMI原理和使用详解

【Java基础】- RMI原理和使用详解 文章目录 【Java基础】- RMI原理和使用详解一、什么RMI二、RMI原理2.1 工作原理图2.2 工作原理 三、RMI远程调用步骤3.1 RMI远程调用运行流程图3.2 RMI 远程调用步骤 四、JAVA RMI简单实现4.1 如何实现一个RMI程序4.2 JAVA实现RMI程序 一、什么…...

无水印免费4K视频素材网站 可商用-Free Stock Video

Free Stock Video是一个在线无水印免费4K视频素材网站&#xff0c;提供各种类型的4k、1080p的视频素材共免费下载&#xff0c;包括美食、水、自然、冬季、无人机、云朵、慢动作、夕阳、动态背景、缩时摄影、旅游和烟火&#xff0c;也可通过关键词搜索方式找到相关视频素材内容&…...

kubesphere中间件部署

微服务部署前中间件部署 一、MySQL部署 1.1 使用Docker实现MySQL主从复制 docker run -p 3307:3306 --name mysql-master \ -v /mydata/mysql/master/log:/var/log/mysql \ -v /mydata/mysql/master/data:/var/lib/mysql \ -v /mydata/mysql/master/conf:/etc/mysql \ -e My…...

使用 AWS S3 SDK 访问 COS-腾讯云国际站代充

腾讯云国际站对象存储&#xff08;Cloud Object Storage&#xff0c;COS&#xff09;提供了 AWS S3 兼容的 API&#xff0c;因此当用户的数据从 S3 迁移到 COS 之后&#xff0c;只需要进行简单的配置修改&#xff0c;即可让客户端应用轻松兼容 COS 服务。下面unirech小编主要介…...

c语言每日一练(15)

前言&#xff1a;每日一练系列&#xff0c;每一期都包含5道选择题&#xff0c;2道编程题&#xff0c;博主会尽可能详细地进行讲解&#xff0c;令初学者也能听的清晰。每日一练系列会持续更新&#xff0c;上学期间将看学业情况更新。 五道选择题&#xff1a; 1、程序运行的结果…...

如何利用软文推广进行SEO优化(打造优质软文,提升网站排名)

在当今的互联网时代&#xff0c;SEO优化成为了网站推广的关键。而软文推广作为一种有效的推广方式&#xff0c;其优点不仅仅局限于SEO&#xff0c;还可以带来更多的曝光和用户流量。本文将深入探讨如何做好软文推广&#xff0c;从而提升网站排名和流量。 了解目标受众群体 内容…...

Java线程池ExecutorService和Executors应用(Spring Boot微服务)

记录&#xff1a;476 场景&#xff1a;在Spring Boot微服务中使用ExecutorService管理Java线程池。使用Executors创建线程池。使用Runnable接口实现类提交线程任务到线程池执行。 版本&#xff1a;JDK 1.8,Spring Boot 2.6.3。 1.线程和线程池基础 JDK自带线程和线程池包位…...

机器学习笔记之最优化理论与方法(八)无约束优化问题——常用求解方法(中)

机器学习笔记之最优化理论与方法——基于无约束优化问题的常用求解方法[中] 引言回顾&#xff1a;最速下降算法的缺陷经典牛顿法基本介绍经典牛顿法的问题经典牛顿法的优点与缺陷经典牛顿法示例 修正牛顿法介绍拟牛顿法拟牛顿法的算法过程 矩阵 B k 1 \mathcal B_{k1} Bk1​的…...

Django系列:Django简介与MTV架构体系概述

Django系列 Django简介与MTV架构体系概述 作者&#xff1a;李俊才 &#xff08;jcLee95&#xff09;&#xff1a;https://blog.csdn.net/qq_28550263 邮箱 &#xff1a;291148484163.com 本文地址&#xff1a;https://blog.csdn.net/qq_28550263/article/details/132890054 【介…...

锐捷交换机WEB管理系统EXCU_SHELL密码信息泄漏漏洞

一、漏洞简介 锐捷交换机 WEB 管理系统 EXCU_SHELL存在密码信息泄露漏洞&#xff0c;攻击者可从漏洞获取到管理员账号密码&#xff0c;从而以管理员权限登录。 二、影响版本 锐捷交换机 WEB 管理系统 三、资产测绘 hunterweb.body"img/free_login_ge.gif"&&…...

线性代数(六) 线性变换

前言 《线性空间》定义了空间&#xff0c;这章节来研究空间与空间的关联性 函数 函数是一个规则或映射&#xff0c;将一个集合中的每个元素&#xff08;称为自变量&#xff09;映射到另一个集合中的唯一元素&#xff08;称为因变量&#xff09;。 一般函数从 “A” 的每个元…...

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...

label-studio的使用教程(导入本地路径)

文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具

作者&#xff1a;来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗&#xff1f;了解下一期 Elasticsearch Engineer 培训的时间吧&#xff01; Elasticsearch 拥有众多新功能&#xff0c;助你为自己…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案

问题描述&#xff1a;iview使用table 中type: "index",分页之后 &#xff0c;索引还是从1开始&#xff0c;试过绑定后台返回数据的id, 这种方法可行&#xff0c;就是后台返回数据的每个页面id都不完全是按照从1开始的升序&#xff0c;因此百度了下&#xff0c;找到了…...

从零实现STL哈希容器:unordered_map/unordered_set封装详解

本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说&#xff0c;直接开始吧&#xff01; 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用

1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)

UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中&#xff0c;UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化&#xf…...

【JVM】Java虚拟机(二)——垃圾回收

目录 一、如何判断对象可以回收 &#xff08;一&#xff09;引用计数法 &#xff08;二&#xff09;可达性分析算法 二、垃圾回收算法 &#xff08;一&#xff09;标记清除 &#xff08;二&#xff09;标记整理 &#xff08;三&#xff09;复制 &#xff08;四&#xff…...

Python 训练营打卡 Day 47

注意力热力图可视化 在day 46代码的基础上&#xff0c;对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...

echarts使用graphic强行给图增加一个边框(边框根据自己的图形大小设置)- 适用于无法使用dom的样式

pdf-lib https://blog.csdn.net/Shi_haoliu/article/details/148157624?spm1001.2014.3001.5501 为了完成在pdf中导出echarts图&#xff0c;如果边框加在dom上面&#xff0c;pdf-lib导出svg的时候并不会导出边框&#xff0c;所以只能在echarts图上面加边框 grid的边框是在图里…...