我正在尝试以tflite在Android上运行TensorFlow模型(用于操纵图像),但是我一直在获取java.io.FileNotFoundException。
不必费心阅读所有Java代码-在尝试加载模型时,它甚至在启动之前就失败了:
// Initialize model
try{
MappedByteBuffer tfliteModel
= FileUtil.loadMappedFile(this,
"model.tflite");
tflite = new Interpreter(tfliteModel);
} catch (IOException e){
Log.e("tfliteException", "Error: couldn't load tflite model.", e);
}
build.gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 29
buildToolsVersion "29.0.3"
defaultConfig {
applicationId "com.example.tflite"
minSdkVersion 27
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
// tf lite
aaptOptions {
noCompress "tflite"
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
// tf lite
implementation 'org.tensorflow:tensorflow-lite:+'
// tf lite gpu
implementation 'org.tensorflow:tensorflow-lite-gpu:+'
// tf lite support library
implementation 'org.tensorflow:tensorflow-lite-support:+'
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.tflite">
<uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
MainActivity.java
package com.example.tflite;
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.AssetFileDescriptor;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import org.tensorflow.lite.DataType;
import org.tensorflow.lite.Interpreter;
import org.tensorflow.lite.support.common.FileUtil;
import org.tensorflow.lite.support.image.ImageProcessor;
import org.tensorflow.lite.support.image.TensorImage;
import org.tensorflow.lite.support.image.ops.ResizeOp;
import org.tensorflow.lite.support.image.ops.ResizeWithCropOrPadOp;
import org.tensorflow.lite.support.image.ops.Rot90Op;
import org.tensorflow.lite.support.tensorbuffer.TensorBuffer;
import org.tensorflow.lite.support.model.Model;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
public class MainActivity extends AppCompatActivity {
private static final int PIXEL_SIZE = 3;
// constants
private int REQUEST_IMAGE_SELECT = 101;
private int REQUEST_START = 201;
public static final int MEDIA_ACCESS_PERMISSION_CODE = 101;
private int imageHeight = 0, imageWidth = 0;
// RGB presets
private static final int IMAGE_MEAN = 128;
private static final float IMAGE_STD = 128.0f;
// variables
Button selectButton, startButton;
ImageView imageView;
TextView result;
Bitmap bitmap, outputImage;
Interpreter tflite;
private ByteBuffer imageByteData = null;
private float accuracy = 0;
private int[] imageIntValues;
ImageProcessor imageProcessor =
new ImageProcessor.Builder()
.add(new ResizeOp(100, 100, ResizeOp.ResizeMethod.BILINEAR))
.build();
TensorImage tImage = new TensorImage(DataType.UINT8);
TensorBuffer probabilityBuffer =
TensorBuffer.createFixedSize(new int[]{1, 1001}, DataType.UINT8);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// init
startButton = findViewById(R.id.startButton);
selectButton = findViewById(R.id.selectButton);
imageView = findViewById(R.id.imageView);
result = findViewById(R.id.resultTextView);
// Initialize model
try{
MappedByteBuffer tfliteModel
= FileUtil.loadMappedFile(this,
"model.tflite");
tflite = new Interpreter(tfliteModel);
} catch (IOException e){
Log.e("tfliteException", "Error: couldn't load tflite model.", e);
}
// select button
selectButton.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick(View v) {
askMediaPermission(REQUEST_IMAGE_SELECT);
}
});
// start button
startButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
float[] accuracy = doTfLite();
result.setText(Float.toString(accuracy[0]));
// close interperter
tflite.close();
}
});
}
private void askMediaPermission(int request) {
if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_MEDIA_LOCATION) != PackageManager.PERMISSION_GRANTED)
ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.ACCESS_MEDIA_LOCATION}, MEDIA_ACCESS_PERMISSION_CODE);
else {
selectImage(request);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if(requestCode == MEDIA_ACCESS_PERMISSION_CODE){
if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
// access granted
Toast.makeText(this, "Granted!", Toast.LENGTH_SHORT).show();
}
else {
// access denied
Toast.makeText(this, "Media Access Permissions are required.", Toast.LENGTH_SHORT).show();
}
}
}
private void selectImage(int request) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select"), request);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// image select
if (requestCode == REQUEST_IMAGE_SELECT && resultCode == RESULT_OK && data != null) {
Uri uri = data.getData();
try {
bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
// int array init
imageHeight = bitmap.getHeight();
imageWidth = bitmap.getWidth();
imageIntValues = new int[imageWidth * imageHeight];
// byte array init (for loading model)
imageByteData = ByteBuffer.allocateDirect(imageHeight * imageWidth * PIXEL_SIZE * 4);
imageByteData.order(ByteOrder.nativeOrder());
imageView.setImageBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
}
// start
else if (requestCode == REQUEST_START && resultCode == RESULT_OK ) {
Toast.makeText(this, "Request code of START.", Toast.LENGTH_SHORT).show();
}
}
public float[] doTfLite(){
// Analysis code for every frame
// Preprocess the image
tImage.load(bitmap);
tImage = imageProcessor.process(tImage);
// Running inference
if (tflite != null) {
tflite.run(tImage.getBuffer(), probabilityBuffer.getBuffer());
}
return probabilityBuffer.getFloatArray();
}
//// loading model
//private MappedByteBuffer loadModelFile() throws IOException {
// // open the model using input stream, and memory-map it to load
// AssetFileDescriptor fileDescriptor = this.getAssets().openFd("model.tflite");
// 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);
//}
}
有什么想法吗?
我被困了三天,扫描了整个互联网...并在发布此消息后几个小时解决了问题...
我删除了资产文件夹并重新创建了它。这解决了我的问题。
我没有时间对此进行研究,我也不知道为什么这会有所帮助(因为我已经尝试过两次从头开始),但是我将其发布以供将来参考(也许也用于Google的TFLite开发人员?)。