I'm trying to perform some image classification with flutter using tflite plugin (https://pub.dev/packages/tflite). I have to classify plants and I found this pretrained model on tensorflow hub https://tfhub.dev/google/aiy/vision/classifier/plants_V1/1
Whenever I try to classify an image I get the following error
E/AndroidRuntime(22309): FATAL EXCEPTION: AsyncTask #1
E/AndroidRuntime(22309): Process: com.example.plant_classification, PID: 22309
E/AndroidRuntime(22309): java.lang.RuntimeException: An error occurred while executing doInBackground()
E/AndroidRuntime(22309): at android.os.AsyncTask$4.done(AsyncTask.java:399)
E/AndroidRuntime(22309): at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383)
E/AndroidRuntime(22309): at java.util.concurrent.FutureTask.setException(FutureTask.java:252)
E/AndroidRuntime(22309): at java.util.concurrent.FutureTask.run(FutureTask.java:271)
E/AndroidRuntime(22309): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:289)
E/AndroidRuntime(22309): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
E/AndroidRuntime(22309): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
E/AndroidRuntime(22309): at java.lang.Thread.run(Thread.java:919)
E/AndroidRuntime(22309): Caused by: java.lang.IllegalArgumentException: Cannot convert between a TensorFlowLite tensor with type UINT8 and a Java object of type [[F (which is compatible with the TensorFlowLite type FLOAT32).
E/AndroidRuntime(22309): at org.tensorflow.lite.Tensor.throwIfTypeIsIncompatible(Tensor.java:427)
E/AndroidRuntime(22309): at org.tensorflow.lite.Tensor.copyTo(Tensor.java:251)
E/AndroidRuntime(22309): at org.tensorflow.lite.NativeInterpreterWrapper.run(NativeInterpreterWrapper.java:175)
E/AndroidRuntime(22309): at org.tensorflow.lite.Interpreter.runForMultipleInputsOutputs(Interpreter.java:360)
E/AndroidRuntime(22309): at org.tensorflow.lite.Interpreter.run(Interpreter.java:319)
E/AndroidRuntime(22309): at sq.flutter.tflite.TflitePlugin$RunModelOnBinary.runTflite(TflitePlugin.java:530)
E/AndroidRuntime(22309): at sq.flutter.tflite.TflitePlugin$TfliteTask.doInBackground(TflitePlugin.java:471)
E/AndroidRuntime(22309): at sq.flutter.tflite.TflitePlugin$TfliteTask.doInBackground(TflitePlugin.java:445)
E/AndroidRuntime(22309): at android.os.AsyncTask$3.call(AsyncTask.java:378)
E/AndroidRuntime(22309): at java.util.concurrent.FutureTask.run(FutureTask.java:266)
E/AndroidRuntime(22309): ... 4 more
The code for the classification is the following:
Future recognizeImage() async {
var imageToByte = imageToByteListUint8(
img.decodeImage(
File(imagePath.value).readAsBytesSync().buffer.asUint8List())!, 224);
int startTime = new DateTime.now().millisecondsSinceEpoch;
var recognitions = await Tflite.runModelOnBinary(
binary: imageToByte, // required
numResults: 6, // defaults to 5
threshold: 0.05, // defaults to 0.1
asynch: true // defaults to true
);
_recognitions = recognitions;
int endTime = new DateTime.now().millisecondsSinceEpoch;
print("Inference took ${endTime - startTime}ms\n");
print("Result = " + _recognitions.toString());
}
And to convert the image I use this code:
Uint8List imageToByteListUint8(img.Image image, int inputSize) {
var convertedBytes = Uint8List(1 * inputSize * inputSize * 3);
var buffer = Uint8List.view(convertedBytes.buffer);
int pixelIndex = 0;
for (var i = 0; i < inputSize; i++) {
for (var j = 0; j < inputSize; j++) {
var pixel = image.getPixel(j, i);
buffer[pixelIndex++] = img.getRed(pixel);
buffer[pixelIndex++] = img.getGreen(pixel);
buffer[pixelIndex++] = img.getBlue(pixel);
}
}
return convertedBytes.buffer.asUint8List();
}
The image I pass is a camera picture already resized to 224x224.
I've tried with other models like mobilenet and everything works, but with this model there is this problem I cannot resolve. Any help is appreciated!