使用深度学习和 Tensorflow 在 Android 上进行闪电检测:设置 TFLite 模型





5.00/5 (5投票s)
在本文中,我们将在 Android 环境中设置 TFLite 模型,并创建一个可用的演示应用程序。
引言
在前一篇文章中,我们介绍了基于模型的应用程序在 Android 环境中的基本设置。
MainActivity.java 文件
这是一个非常重要的文件,它促进了用户与我们的 Android 应用程序的交互。我们将逐行或逐块地浏览此文件。
该文件位于 com.ruturaj.detectlightning
包中。 com.ruturaj.detectlightning.mlkit
包含对象检测所需的所有类文件。
让我们从包开始
package com.ruturaj.detectlightning;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import com.google.mlkit.common.model.LocalModel;
import com.google.mlkit.vision.objects.custom.CustomObjectDetectorOptions;
import com.ruturaj.detectlightning.mlkit.CameraSource;
import com.ruturaj.detectlightning.mlkit.CameraSourcePreview;
import com.ruturaj.detectlightning.mlkit.GraphicOverlay;
import com.ruturaj.detectlightning.mlkit.ObjectDetectorProcessor;
import com.ruturaj.detectlightning.mlkit.PreferenceUtils;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity implements ActivityCompat.OnRequestPermissionsResultCallback {
一些重要的变量和字符串在 class-globally
中定义
private static final String OBJECT_DETECTION_CUSTOM = "Lightning";
private static final String TAG = "MainActivity";
private static final int PERMISSION_REQUESTS = 1;
private CameraSource cameraSource = null;
private CameraSourcePreview preview;
private GraphicOverlay graphicOverlay;
private String selectedModel = OBJECT_DETECTION_CUSTOM;
如果您熟悉 Android 生命周期,我相信您知道以下方法!
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
从后置摄像头为我们的直播设置预览。
preview = findViewById(R.id.preview_view);
if (preview == null) {
Log.e(OBJECT_DETECTION_CUSTOM, "Preview is null");
}
接下来,我们在屏幕上检测到闪电的部分绘制一个图形叠加层(在本例中是一个边界框),同时处于相机模式。
graphicOverlay = findViewById(R.id.graphic_overlay);
if (graphicOverlay == null) {
Log.e(OBJECT_DETECTION_CUSTOM, "graphicOverlay is null");
}
接下来,我们检查我们的应用程序是否已经拥有所需的权限,如果没有,我们在运行时请求它们
if (allPermissionsGranted()) {
createCameraSource(selectedModel);
} else {
getRuntimePermissions();
}
}
调用 CameraSource
类以使用我们的模型将相机视图显示到屏幕上
if (allPermissionsGranted()) {
createCameraSource(selectedModel);
} else {
getRuntimePermissions();
}
}
当存储在 assets
文件夹中的模型运行时,我们调用 LocalModel
类来构建模型并检测对象。 CustomObjectDetectorOptions
通常用于实时检测相机视野中最突出的对象。
try {
if (OBJECT_DETECTION_CUSTOM.equals(model)) {
Log.e(OBJECT_DETECTION_CUSTOM, "Using Custom Object Detector Processor");
LocalModel localModel =
new LocalModel.Builder()
.setAssetFilePath("model.tflite")
.build();
CustomObjectDetectorOptions customObjectDetectorOptions =
PreferenceUtils.getCustomObjectDetectorOptionsForLivePreview(this, localModel);
cameraSource.setMachineLearningFrameProcessor(
new ObjectDetectorProcessor(this, customObjectDetectorOptions));
} else {
Log.e(OBJECT_DETECTION_CUSTOM, "Unknown model: " + model);
}
} catch (Exception e) {
Log.e(OBJECT_DETECTION_CUSTOM, "Can not create image processor: " + model, e);
Toast.makeText(
getApplicationContext(),
"Can not create image processor: " + e.getMessage(),
Toast.LENGTH_LONG)
.show();
}
}
一旦授予权限,并且应用程序显示预览,就启动相机。
private void startCameraSource() {
if (cameraSource != null) {
try {
if (preview == null) {
Log.e(TAG, "resume: Preview is null");
}
if (graphicOverlay == null) {
Log.e(TAG, "resume: graphOverlay is null");
}
preview.start(cameraSource, graphicOverlay);
} catch (IOException e) {
Log.e(TAG, "Unable to start camera source.", e);
cameraSource.release();
cameraSource = null;
}
}
}
以下代码在发生中断时维护 Android UI 生命周期
@Override
public void onResume() {
super.onResume();
Log.e(TAG, "onResume");
createCameraSource(selectedModel);
startCameraSource();
}
应用程序暂停的处理方式如下
@Override
protected void onPause() {
super.onPause();
preview.stop();
}
关闭应用程序会销毁相机预览
@Override
public void onDestroy() {
super.onDestroy();
if (cameraSource != null) {
cameraSource.release();
}
}
在 onCreate
调用授予对所需权限的访问权限之后
private String[] getRequiredPermissions() {
try {
PackageInfo info =
this.getPackageManager()
.getPackageInfo(this.getPackageName(), PackageManager.GET_PERMISSIONS);
String[] ps = info.requestedPermissions;
if (ps != null && ps.length > 0) {
return ps;
} else {
return new String[0];
}
} catch (Exception e) {
return new String[0];
}
}
private boolean allPermissionsGranted() {
for (String permission : getRequiredPermissions()) {
if (!isPermissionGranted(this, permission)) {
return false;
}
}
return true;
}
private void getRuntimePermissions() {
List<String> allNeededPermissions = new ArrayList<>();
for (String permission : getRequiredPermissions()) {
if (!isPermissionGranted(this, permission)) {
allNeededPermissions.add(permission);
}
}
if (!allNeededPermissions.isEmpty()) {
ActivityCompat.requestPermissions(
this, allNeededPermissions.toArray(new String[0]), PERMISSION_REQUESTS);
}
}
@Override
public void onRequestPermissionsResult(
int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
Log.i(TAG, "Permission granted!");
if (allPermissionsGranted()) {
createCameraSource(selectedModel);
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
private static boolean isPermissionGranted(Context context, String permission) {
if (ContextCompat.checkSelfPermission(context, permission)
== PackageManager.PERMISSION_GRANTED) {
Log.i(TAG, "Permission granted: " + permission);
return true;
}
Log.i(TAG, "Permission NOT granted: " + permission);
return false;
}
}
您会在代码中看到很多 Log.e…
的实例。这只是为了使 Logcat 检查在视觉上突出。当我执行 e- Error
日志时,跟踪以红色显示 - 易于查看。
其他类文件
类文件名 | 描述 |
BitmapUtils | 用于位图转换的 utils 函数。 |
CameraImageGraphic | 在背景中绘制相机图像。 |
CameraSource | 管理相机并允许在相机顶部进行 UI 更新(例如,覆盖额外的图形或显示额外的信息)。它以指定的速率从相机接收预览帧,并将这些帧发送到子类的检测器/分类器,并尽可能快地处理它们。 |
CameraSourcePreview | 在屏幕上预览相机图像。 |
FrameMetaData | 包含有关帧的附加信息。 |
GraphicOverlay | 渲染一系列自定义图形,以叠加在预览之上(即,相机预览)。创建者可以添加图形对象、更新这些对象并删除它们,从而触发视图中的适当绘制和失效。 |
InferenceInfoGraphic | 一个图形实例,用于在叠加视图中渲染推理信息(延迟、FPS、分辨率)。 |
ObjectDetectorProcessor | 一个运行对象检测器的处理器。 |
ObjectGraphic | 在预览中绘制检测到的对象信息。 |
PreferenceUtils | 一个用于检索共享首选项的实用程序类。 |
ScopedExecutor | 包装现有执行程序,以提供一种方法来后续取消提交的 Runnable。 |
VisionImageProcessor | 一个用于使用各种视觉检测器和自定义图像模型处理图像的接口。 |
VisionProcessorBase | 提取视觉帧处理器的基类。 子类需要实现此接口以定义他们想要使用检测结果做什么,并指定检测器对象。 |
后续步骤
在 下一篇文章 中,我们将在 Android 设备上对我们的应用程序进行实时测试。