shaqian / flutter_tflite

Flutter plugin for TensorFlow Lite
https://pub.dartlang.org/packages/tflite
MIT License
631 stars 403 forks source link

#import "metal_delegate.h" file not found #184

Open janesy opened 3 years ago

janesy commented 3 years ago

Xcode's output: ↳ /Users/trendlab/.pub-cache/hosted/pub.dartlang.org/image_picker-0.4.12+1/ios/Classes/ImagePickerPlugin.m:113:20: warning: 'UIAlertView' is deprecated: first deprecated in iOS 9.0 - UIAlertView is deprecated. Use UIAlertController with a preferredStyle of UIAlertControllerStyleAlert instead [-Wdeprecated-declarations] [[[UIAlertView alloc] initWithTitle:@"Error" ^ In module 'UIKit' imported from /Users/trendlab/AndroidStudioProjects/flutter_my_tflite/ios/Pods/Target Support Files/image_picker/image_picker-prefix.pch:2: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.3.sdk/System/Library/Frameworks/UIKit.framework/Headers/UIAlertView.h:27:12: note: 'UIAlertView' has been explicitly marked deprecated here @interface UIAlertView : UIView ^ 1 warning generated. /Users/trendlab/.pub-cache/hosted/pub.dartlang.org/tflite-1.1.1/ios/Classes/TflitePlugin.mm:21:9: fatal error: 'metal_delegate.h' file not found

import "metal_delegate.h"

        ^~~~~~~~~~~~~~~~~~
1 error generated.
note: Using new build system
note: Building targets in parallel
note: Planning build
note: Constructing build description

Could not build the precompiled application for the device.

Error launching application on iPhoneX.

dependencies:
  flutter:
    sdk: flutter
  tflite: ^1.1.1
  meta: ^1.1.8
  image_picker: ^0.4.10
  image: ^2.1.4
  test: ^1.12.0
  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^1.0.1
HollererJ commented 3 years ago

Same here .... on android it is working - on iOS I get the message

fatal error: 'metal_delegate.h' file not found

import "metal_delegate.h"

in Xcode it shows file TflitePlugin.mm line 21 import "metal_delegate.h" file not found Bildschirmfoto 2021-02-04 um 16 24 08

cmalbuquerque commented 3 years ago

I have the same problem using iOS Simulator

DonC83 commented 3 years ago

Check the TensorFlowLiteC version in your Podfile.lock, you probably need to downgrade to 2.2.0.

 - TensorFlowLiteC (2.2.0)
  - tflite (1.1.1):
    - Flutter
    - TensorFlowLiteC
DonC83 commented 3 years ago

@janesy issue is related to https://github.com/shaqian/flutter_tflite/issues/139

Theunodb commented 3 years ago

Is there a way to get past this without downgrading?

alifgiant commented 3 years ago

Check the TensorFlowLiteC version in your Podfile.lock, you probably need to downgrade to 2.2.0.

 - TensorFlowLiteC (2.2.0)
  - tflite (1.1.1):
    - Flutter
    - TensorFlowLiteC

I think this solution should be written on the readme, no?

isuru18113 commented 3 years ago

there are so many errors when we downgrade to 2.2.0.

This is what finally I got after all ( Only occurred on IOS)

Didn't find op for builtin opcode 'CONV_2D' version '5' 
Registration Failed
Theunodb commented 2 years ago

Any update on when this issue will be addressed?

mdable2 commented 2 years ago

Any update on this?

swarmidentity commented 2 years ago

This worked for me:

https://github.com/shaqian/flutter_tflite/pull/243

@Theunodb / @mdable2 can one of y'all confirm?

Theunodb commented 2 years ago

I can confirm that this is working.

  tflite:
    git:
      url: https://github.com/swarmidentity/flutter_tflite.git
      ref: 6ed08242a0d4d34432bf18790846b8a3033a7057
UnkoC0wbOy commented 2 years ago

How did you implement the confirmed fix?

irfanmiko15 commented 2 years ago

there are so many errors when we downgrade to 2.2.0.

This is what finally I got after all ( Only occurred on IOS)

Didn't find op for builtin opcode 'CONV_2D' version '5' 
Registration Failed

i have same problem like this after downgrade to 2.2.0,how solve this?

Theunodb commented 2 years ago

The interim fix isn't viable anymore, so i switched from this package to google_mlkit_object_detection: ^0.5.0 for now. Will revert back to this once the package is updated.

This is my new code:

Initialise the detector in the cubit

  initialiseDetector({double confidenceThreshold = 0.5, int maximumLabelsPerObject = 10}) async {
    emit(ShoddyLoading(state.mainShoddyState.copyWith(message: 'Loading object detector')));
    try {
      ObjectDetector objectDetector = await ShoddyHelper.initialiseDetector(
        processingFromDownloadedFile: true,
        modelFile: state.mainShoddyState.modelFile,
        confidenceThreshold: confidenceThreshold,
        maximumLabelsPerObject: maximumLabelsPerObject,
      );
      emit(ShoddyModelLoaded(state.mainShoddyState.copyWith(objectDetector: objectDetector, message: 'Ready to start processing images')));
    } catch (error) {
      emit(ShoddyError(state.mainShoddyState.copyWith(message: error.toString())));
    }
  }

A helper / utilities file to download or use a model file

  static Future<ObjectDetector> initialiseDetector({File? modelFile, bool processingFromDownloadedFile = true, required double confidenceThreshold, required int maximumLabelsPerObject}) async {
    if (processingFromDownloadedFile) {
      if (modelFile != null) {
        return await initializeLocalDetector(modelFile, confidenceThreshold, maximumLabelsPerObject);
      } else {
        File modelFile = await loadModelFileFromFirebase();
        return await initializeLocalDetector(modelFile, confidenceThreshold, maximumLabelsPerObject);
      }
    } else {
      return await initializeFirebaseDetector(confidenceThreshold, maximumLabelsPerObject);
    }
  }

// Download the model file from firebase first
  static Future<File> loadModelFileFromFirebase(String modelName) async {
    try {
      FirebaseModelDownloader downloader = FirebaseModelDownloader.instance;

      List<FirebaseCustomModel> models = await downloader.listDownloadedModels();
      for (FirebaseCustomModel model in models) {
        print('Name: ${model.name}');
      }

      FirebaseModelDownloadConditions conditions = FirebaseModelDownloadConditions(
        iosAllowsCellularAccess: true,
        iosAllowsBackgroundDownloading: false,
        androidChargingRequired: false,
        androidWifiRequired: false,
        androidDeviceIdleRequired: false,
      );

      FirebaseCustomModel model = await downloader.getModel(
        modelName,
        FirebaseModelDownloadType.latestModel,
        conditions,
      );

      File modelFile = model.file;

      return modelFile;
    } catch (exception) {
      print('Failed on loading your model from Firebase: $exception');
      print('The program will not be resumed');
      rethrow;
    }
  }

  // Use a file downloaded from firebase
  static Future<ObjectDetector> initializeLocalDetector(File modelFile, double confidenceThreshold, int maximumLabelsPerObject) async {
    try {
      final options = LocalObjectDetectorOptions(
        mode: DetectionMode.single,
        modelPath: modelFile.path,
        classifyObjects: true,
        multipleObjects: true,
        confidenceThreshold: confidenceThreshold,
        maximumLabelsPerObject: maximumLabelsPerObject,
      );

      return ObjectDetector(options: options);
    } catch (exception) {
      print('Failed on loading your model to the TFLite interpreter: $exception');
      print('The program will not be resumed');
      rethrow;
    }
  }

  // Use the model file directly from firebase
  static Future<ObjectDetector> initializeFirebaseDetector(String modelName, double confidenceThreshold, int maximumLabelsPerObject) async {
    try {
      final options = FirebaseObjectDetectorOptions(
        mode: DetectionMode.single,
        modelName: modelName,
        classifyObjects: true,
        multipleObjects: true,
        confidenceThreshold: confidenceThreshold,
        maximumLabelsPerObject: maximumLabelsPerObject,
      );

      return ObjectDetector(options: options);
    } catch (exception) {
      print('Failed on loading your model to the TFLite interpreter: $exception');
      print('The program will not be resumed');
      rethrow;
    }
  }

The function to process an image

  processImage(File file) async {
    emit(ShoddyModelProcessing(state.mainShoddyState.copyWith(message: 'Looking for objects on the selected image')));
    try {
      List<dynamic>? results = [];
      if (state.mainShoddyState.objectDetector != null) {
        InputImage inputImage = InputImage.fromFilePath(file.path);
        List<DetectedObject> objects = await state.mainShoddyState.objectDetector!.processImage(inputImage);
        if (objects.isNotEmpty) {
          List<ObjectModel> objects = results.map((result) => ObjectModel(result)).toList();
          emit(ShoddyModelProcessed(state.mainShoddyState.copyWith(objects: objects, filteredObjects: objects, message: 'Image processed with results')));
          changeMatchPercentage(0.35);
        } else {
          emit(ShoddyModelProcessed(state.mainShoddyState.copyWith(objects: [], filteredObjects: [], message: 'Image processed with no results')));
        }
      }
    } catch (error) {
      emit(ShoddyError(state.mainShoddyState.copyWith(message: error.toString())));
    }
  }