flutter-ml / google_ml_kit_flutter

A flutter plugin that implements Google's standalone ML Kit
MIT License
974 stars 742 forks source link

Model wont load from phone storage #279

Closed Toolenaar closed 2 years ago

Toolenaar commented 2 years ago

Hi I am building a tool to test Models. For this I want to be able to load a model in an android emulator. However when I try to load this from storage I keep getting 'java.io.FileNotFoundException'. The model works when I load it from the assets folder. But I just cant get it to load from another file path. Any idea why? Or if this is even possible?

I am using the following to load a file opened from the the file_picker plugin

 Future<String> _getModelFromLocalFile(io.File sourcFile) async {
    final byteData = await sourcFile.readAsBytes();
    final file = File('${(await getTemporaryDirectory()).path}/models/model.tflite');
    await file.parent.create(recursive: true);
    await file.writeAsBytes(byteData.buffer.asUint8List(byteData.offsetInBytes, byteData.lengthInBytes));

    return file.path;
  }

Output:

E/ModelUtils(17377): Failed to open model file E/ModelUtils(17377): java.io.FileNotFoundException: /data/user/0/com.example.ml_test_app/cache/models/model.tflite E/ModelUtils(17377): at android.content.res.AssetManager.nativeOpenAssetFd(Native Method) E/ModelUtils(17377): at android.content.res.AssetManager.openFd(AssetManager.java:848) E/ModelUtils(17377): at com.google.mlkit.common.internal.model.ModelUtils.getModelLoggingInfo(com.google.mlkit:common@@18.1.0:6) E/ModelUtils(17377): at com.google.mlkit.vision.label.custom.internal.zzf.zzc(com.google.mlkit:image-labeling-custom@@17.0.1:2) E/ModelUtils(17377): at com.google.mlkit.vision.label.custom.internal.zze.tryLoad(com.google.mlkit:image-labeling-custom@@17.0.1:1) E/ModelUtils(17377): at com.google.mlkit.common.sdkinternal.model.CustomModelLoader.load(com.google.mlkit:common@@18.1.0:3) E/ModelUtils(17377): at com.google.mlkit.vision.label.custom.internal.zzf.load(com.google.mlkit:image-labeling-custom@@17.0.1:2) E/ModelUtils(17377): at com.google.mlkit.common.sdkinternal.ModelResource.zza(com.google.mlkit:common@@18.1.0:4) E/ModelUtils(17377): at com.google.mlkit.common.sdkinternal.zzl.run(Unknown Source:10) E/ModelUtils(17377): at com.google.mlkit.common.sdkinternal.zzp.run(com.google.mlkit:common@@18.1.0:2) E/ModelUtils(17377): at com.google.mlkit.common.sdkinternal.MlKitThreadPool.zze(com.google.mlkit:common@@18.1.0:4) E/ModelUtils(17377): at com.google.mlkit.common.sdkinternal.MlKitThreadPool.zzc(com.google.mlkit:common@@18.1.0:1) E/ModelUtils(17377): at com.google.mlkit.common.sdkinternal.zzi.run(Unknown Source:2) E/ModelUtils(17377): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) E/ModelUtils(17377): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) E/ModelUtils(17377): at com.google.mlkit.common.sdkinternal.MlKitThreadPool.zzd(com.google.mlkit:common@@18.1.0:2) E/ModelUtils(17377): at com.google.mlkit.common.sdkinternal.zzj.run(Unknown Source:2) E/ModelUtils(17377): at java.lang.Thread.run(Thread.java:919) E/MobileVisionBase(17377): Error preloading model resource E/MobileVisionBase(17377): com.google.mlkit.common.MlKitException: Failed to initialize detector. E/MobileVisionBase(17377): at com.google.mlkit.vision.vkp.PipelineManager.start(com.google.mlkit:vision-internal-vkp@@18.2.2:70) E/MobileVisionBase(17377): at com.google.mlkit.vision.label.custom.internal.zzf.zzf(com.google.mlkit:image-labeling-custom@@17.0.1:6) E/MobileVisionBase(17377): at com.google.mlkit.vision.label.custom.internal.zze.tryLoad(com.google.mlkit:image-labeling-custom@@17.0.1:2) E/MobileVisionBase(17377): at com.google.mlkit.common.sdkinternal.model.CustomModelLoader.load(com.google.mlkit:common@@18.1.0:3) E/MobileVisionBase(17377): at com.google.mlkit.vision.label.custom.internal.zzf.load(com.google.mlkit:image-labeling-custom@@17.0.1:2) E/MobileVisionBase(17377): at com.google.mlkit.common.sdkinternal.ModelResource.zza(com.google.mlkit:common@@18.1.0:4) E/MobileVisionBase(17377): at com.google.mlkit.common.sdkinternal.zzl.run(Unknown Source:10) E/MobileVisionBase(17377): at com.google.mlkit.common.sdkinternal.zzp.run(com.google.mlkit:common@@18.1.0:2) E/MobileVisionBase(17377): at com.google.mlkit.common.sdkinternal.MlKitThreadPool.zze(com.google.mlkit:common@@18.1.0:4) E/MobileVisionBase(17377): at com.google.mlkit.common.sdkinternal.MlKitThreadPool.zzc(com.google.mlkit:common@@18.1.0:1) E/MobileVisionBase(17377): at com.google.mlkit.common.sdkinternal.zzi.run(Unknown Source:2) E/MobileVisionBase(17377): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) E/MobileVisionBase(17377): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) E/MobileVisionBase(17377): at com.google.mlkit.common.sdkinternal.MlKitThreadPool.zzd(com.google.mlkit:common@@18.1.0:2) E/MobileVisionBase(17377): at com.google.mlkit.common.sdkinternal.zzj.run(Unknown Source:2) E/MobileVisionBase(17377): at java.lang.Thread.run(Thread.java:919) E/MobileVisionBase(17377): Caused by: java.io.FileNotFoundException: /data/user/0/com.example.ml_test_app/cache/models/model.tflite E/MobileVisionBase(17377): at android.content.res.AssetManager.nativeOpenAssetFd(Native Method) E/MobileVisionBase(17377): at android.content.res.AssetManager.openFd(AssetManager.java:848) E/MobileVisionBase(17377): at com.google.mlkit.vision.vkp.PipelineManager.zzb(com.google.mlkit:vision-internal-vkp@@18.2.2:1) E/MobileVisionBase(17377): at com.google.mlkit.vision.vkp.PipelineManager.start(com.google.mlkit:vision-internal-vkp@@18.2.2:47) E/MobileVisionBase(17377): ... 15 more E/ModelUtils(17377): Failed to open model file E/ModelUtils(17377): java.io.FileNotFoundException: /data/user/0/com.example.ml_test_app/cache/models/model.tflite E/ModelUtils(17377): at android.content.res.AssetManager.nativeOpenAssetFd(Native Method) E/ModelUtils(17377): at android.content.res.AssetManager.openFd(AssetManager.java:848) E/ModelUtils(17377): at com.google.mlkit.common.internal.model.ModelUtils.getModelLoggingInfo(com.google.mlkit:common@@18.1.0:6) E/ModelUtils(17377): at com.google.mlkit.vision.label.custom.internal.zzf.zzc(com.google.mlkit:image-labeling-custom@@17.0.1:2) E/ModelUtils(17377): at com.google.mlkit.vision.label.custom.internal.zze.tryLoad(com.google.mlkit:image-labeling-custom@@17.0.1:1) E/ModelUtils(17377): at com.google.mlkit.common.sdkinternal.model.CustomModelLoader.load(com.google.mlkit:common@@18.1.0:3) E/ModelUtils(17377): at com.google.mlkit.vision.label.custom.internal.zzf.load(com.google.mlkit:image-labeling-custom@@17.0.1:2) E/ModelUtils(17377): at com.google.mlkit.common.sdkinternal.ModelResource.zza(com.google.mlkit:common@@18.1.0:4) E/ModelUtils(17377): at com.google.mlkit.common.sdkinternal.zzl.run(Unknown Source:10) E/ModelUtils(17377): at com.google.mlkit.common.sdkinternal.zzp.run(com.google.mlkit:common@@18.1.0:2) E/ModelUtils(17377): at com.google.mlkit.common.sdkinternal.MlKitThreadPool.zze(com.google.mlkit:common@@18.1.0:4) E/ModelUtils(17377): at com.google.mlkit.common.sdkinternal.MlKitThreadPool.zzc(com.google.mlkit:common@@18.1.0:1) E/ModelUtils(17377): at com.google.mlkit.common.sdkinternal.zzi.run(Unknown Source:2) E/ModelUtils(17377): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) E/ModelUtils(17377): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) E/ModelUtils(17377): at com.google.mlkit.common.sdkinternal.MlKitThreadPool.zzd(com.google.mlkit:common@@18.1.0:2) E/ModelUtils(17377): at com.google.mlkit.common.sdkinternal.zzj.run(Unknown Source:2) E/ModelUtils(17377): at java.lang.Thread.run(Thread.java:919)

fbernaly commented 2 years ago

To ensure that in both platforms that file will be accesible and you wont have to copy the file in 2 different folder (one for iOS and one for Android), we decided to go with assets folder. All the files in assets folder will be available for both platforms.

For you logs I guess you tested with Image Labeler, so, look at this in our README, it specifies where to put your models:

https://github.com/bharat-biradar/Google-Ml-Kit-plugin/tree/master/packages/google_mlkit_image_labeling#load-local-custom-model

Also, in the Android native side, when the model is loaded to pass it to the native API, it will always use setAssetFilePath: https://github.com/bharat-biradar/Google-Ml-Kit-plugin/blob/master/packages/google_mlkit_image_labeling/android/src/main/java/com/google_mlkit_image_labeling/ImageLabelDetector.java#L124-L125

I hope that helps.