【问题标题】:Integrating a custom AutoML tflite model with flutter app将自定义 AutoML tflite 模型与 Flutter 应用程序集成
【发布时间】:2020-03-28 19:28:25
【问题描述】:

我是 Flutter 的新手,基本上,我按照在线教程使用 Google 的 AutoML API 训练自定义图像标记模型,然后将模型下载为三个文件(dict.txt、manifest.json、model.tflite),现在我正在尝试将它与我的颤振应用程序集成。

这是我加载和运行 TFlite 模型的代码:

Future loadModel() async {
    try{
      res = await Tflite.loadModel(
          model: "assets/models/model.tflite",
          labels: "assets/models/dict.txt",
      );
      print("loading tf model...");
      print(res);
    }on PlatformException{
      print ("Failed to load model");
    }
  }

Future recognizeImageBinary(File image) async {
    var imageBytes = await image.readAsBytesSync();
    var bytes = imageBytes.buffer.asUint8List();
    img.Image oriImage = img.decodeJpg(bytes);
    img.Image resizedImage = img.copyResize(oriImage, height: 112, width: 112);

    var recognitions = await Tflite.runModelOnBinary(
      binary: imageToByteListUint8(resizedImage, 112),
      numResults: 2,
      threshold: 0.4,
      asynch: true
    );
    setState(() {
      _recognitions = recognitions;
    });
  }

根据教程,AutoML自定义训练模型是Uint8类型的,所以我用下面的函数来转换它:

Uint8List imageToByteListUint8(img.Image image, int inputSize) {
    var convertedBytes = Uint8List(4 * 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();
  }

我遇到了这样的异常:

E/AndroidRuntime( 6372): FATAL EXCEPTION: AsyncTask #2
E/AndroidRuntime( 6372): Process: com.soton.gca_app, PID: 6372
E/AndroidRuntime( 6372): java.lang.RuntimeException: An error occurred while executing doInBackground()
E/AndroidRuntime( 6372):    at android.os.AsyncTask$3.done(AsyncTask.java:318)
E/AndroidRuntime( 6372):    at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
E/AndroidRuntime( 6372):    at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
E/AndroidRuntime( 6372):    at java.util.concurrent.FutureTask.run(FutureTask.java:242)
E/AndroidRuntime( 6372):    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243)
E/AndroidRuntime( 6372):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
E/AndroidRuntime( 6372):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
E/AndroidRuntime( 6372):    at java.lang.Thread.run(Thread.java:760)
E/AndroidRuntime( 6372): 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( 6372):    at org.tensorflow.lite.Tensor.throwIfTypeIsIncompatible(Tensor.java:316)
E/AndroidRuntime( 6372):    at org.tensorflow.lite.Tensor.throwIfDataIsIncompatible(Tensor.java:304)
E/AndroidRuntime( 6372):    at org.tensorflow.lite.Tensor.copyTo(Tensor.java:183)
E/AndroidRuntime( 6372):    at org.tensorflow.lite.NativeInterpreterWrapper.run(NativeInterpreterWrapper.java:166)
E/AndroidRuntime( 6372):    at org.tensorflow.lite.Interpreter.runForMultipleInputsOutputs(Interpreter.java:311)
E/AndroidRuntime( 6372):    at org.tensorflow.lite.Interpreter.run(Interpreter.java:272)
E/AndroidRuntime( 6372):    at sq.flutter.tflite.TflitePlugin$RunModelOnBinary.runTflite(TflitePlugin.java:478)
E/AndroidRuntime( 6372):    at sq.flutter.tflite.TflitePlugin$TfliteTask.doInBackground(TflitePlugin.java:419)
E/AndroidRuntime( 6372):    at sq.flutter.tflite.TflitePlugin$TfliteTask.doInBackground(TflitePlugin.java:393)
E/AndroidRuntime( 6372):    at android.os.AsyncTask$2.call(AsyncTask.java:304)
E/AndroidRuntime( 6372):    at java.util.concurrent.FutureTask.run(FutureTask.java:237)
E/AndroidRuntime( 6372):    ... 4 more

我现在真的很困惑,有人可以在这里帮忙吗?

【问题讨论】:

  • TFLite 模型要求输入具有float32dtype,而您提供的输入是dtype=uint8。确保将img.getRed( pixel ) 和其他两个值转换为float
  • @ShubhamPanchal 我尝试按照您的建议将图像转换为 float32list,它仍然给我上面相同的错误

标签: tensorflow flutter dart tensorflow-lite google-cloud-automl


【解决方案1】:

@Shubham 看来异常还是存在的,就算我用的方法:

Uint8List imageToByteListFloat32(img.Image image, int inputSize, double mean, double std) {
    var convertedBytes = Float32List(1 * inputSize * inputSize * 3 );
    var buffer = Float32List.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) - mean) / std).toDouble();
        buffer[pixelIndex++] = ((img.getGreen(pixel) - mean) / std).toDouble();
        buffer[pixelIndex++] = ((img.getBlue(pixel) - mean) / std).toDouble();
      }
    }
    return convertedBytes.buffer.asUint8List();
  }

【讨论】:

    猜你喜欢
    • 2018-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-04
    • 2022-10-19
    相关资源
    最近更新 更多