ultralytics / yolo-flutter-app

A Flutter plugin for Ultralytics YOLO computer vision models
https://ultralytics.com
GNU Affero General Public License v3.0
36 stars 14 forks source link

Unhandled Exception: type '_Map<Object?, Object?>' is not a subtype of type 'Map<String, dynamic>?' in type cast when casting json. #5

Closed vominhmanh closed 1 month ago

vominhmanh commented 2 months ago

It throws an error: Unhandled Exception: type '_Map<Object?, Object?>' is not a subtype of type 'Map<String, dynamic>?' in type cast when I called detect function as the following code:

    String modelPath = await _copy('assets/tflite/yolov8n_int8.tflite');
    String metadataPath = await _copy('assets/tflite/metadata.yaml');
    final model = LocalYoloModel(
      id: '',
      task: Task.detect /* or Task.classify */,
      format: Format.tflite /* or Format.coreml*/,
      modelPath: modelPath,
      metadataPath: metadataPath,
    );
    objectDetector = ObjectDetector(model: model);
    await objectDetector!.loadModel(useGpu: false);

    List<DetectedObject?>? detectedObjs=
        await objectDetector!.detect(imagePath: await _copy('assets/dog.jpeg'));   // --> error occurs here

I tried digging into the package code, at ~\AppData\Local\Pub\Cache\hosted\pub.dev\ultralytics_yolo-0.0.3\lib\ultralytics_yolo_platform_channel.dart, I found this line of code throwing the error:

@override
  Future<List<DetectedObject?>?> detectImage(String imagePath) async {
    final result =
        await methodChannel.invokeMethod<List<Object?>>('detectImage', {
      'imagePath': imagePath,
    }).catchError((_) {
      return <DetectedObject?>[];
    });

    final objects = <DetectedObject>[];

    result?.forEach((json) {
      json = json as Map<String, dynamic>?;  // Error occurs here as type of json is '_Map<Object?, Object?>' 
      if (json == null) return;
      objects.add(DetectedObject.fromJson(json as Map));
    });

    return objects;
  }

I tried modifying the code to: json = Map<String, dynamic>.from (json as Map);, then the error disappeared. So, is this the bug from package or due to the mismatch between flutter/dart environment and the package ?

pderrenger commented 2 months ago

Hello there!

Thanks for reporting this issue and diving into the details. It sounds like you've encountered a type casting challenge that's common with dynamic languages. Your solution json = Map<String, dynamic>.from(json as Map); indeed adjusts the type casting to accommodate Dart's type system better. This is more about ensuring compatibility between variable types in Dart than specifically a bug with the package itself. However, your proactive solution provides a clearer path for type casting, which can be beneficial for others facing similar errors.

If you have further questions or run into more issues, feel free to reach out or check our docs at https://docs.ultralytics.com for guidance.

Happy coding! πŸ˜ŠπŸ‘

Taron133 commented 2 months ago
UltralyticsYoloCameraPreview(
         controller: controller,
         predictor: predictor,
         onCameraCreated: () {
           predictor.loadModel(useGpu: true);
         }
       ),
       StreamBuilder<List<ClassificationResult?>?>(
         stream: predictor.classificationResultStream,
         builder: (context, snapshot) {
           final classificationResults = snapshot.data; //"type '_Map<Object?, Object?>' is not a subtype of type 'Map<String, dynamic>' in type cast"

          if (classificationResults == null ||
              classificationResults.isEmpty) {
            return Container();
          }

          return ClassificationResultOverlay(
            classificationResults: classificationResults,
          );
        },
       ),
       ),

"type '_Map<Object?, Object?>' is not a subtype of type 'Map<String, dynamic>' in type cast" "package:ultralytics_yolo/ultralytics_yolo_platform_channel.dart"

@override
  Stream<List<ClassificationResult?>?> get classificationResultStream =>
      predictionResultsEventChannel.receiveBroadcastStream().map(
        (result) {
          final objects = <ClassificationResult>[];
          result = result as List;

          for (dynamic json in result) {
            json = json as Map<String, dynamic>;
            objects.add(ClassificationResult.fromJson(json));
          }

          return objects;
        },
      );

Fix: objects.add(ClassificationResult.fromJson(Map<String, dynamic>.from (json as Map)));

github-actions[bot] commented 1 month ago

πŸ‘‹ Hello there! We wanted to give you a friendly reminder that this issue has not had any recent activity and may be closed soon, but don't worry - you can always reopen it if needed. If you still have any questions or concerns, please feel free to let us know how we can help.

For additional resources and information, please see the links below:

Feel free to inform us of any other issues you discover or feature requests that come to mind in the future. Pull Requests (PRs) are also always welcomed!

Thank you for your contributions to YOLO πŸš€ and Vision AI ⭐