ultralytics / yolo-flutter-app

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

Need help getting detected object name #39

Closed nikhilgarala-tecblic closed 4 months ago

nikhilgarala-tecblic commented 4 months ago

Hey there,

I'm currently trying to retrieve the detected object names, but I'm unable to find any properties that provide this information. Could someone please guide me on how to achieve this? Any help would be greatly appreciated.

Thanks!

pderrenger commented 4 months ago

@nikhilgarala-tecblic hello!

Thanks for reaching out! To retrieve the detected object names, you can access the names attribute from the model's metadata. Here's a step-by-step guide to help you achieve this:

  1. Load your model: Ensure you have your model loaded using the Ultralytics YOLO framework.
  2. Run inference: Perform inference on your image or video.
  3. Access the detected object names: Extract the class indices from the results and map them to the corresponding object names.

Here's a sample code snippet to illustrate this:

import torch

# Load the model
model = torch.hub.load('ultralytics/yolov5', 'yolov5s')

# Perform inference
img = 'path/to/your/image.jpg'
results = model(img)

# Get the detected object names
detected_objects = results.pandas().xyxy[0]['name'].tolist()

print("Detected objects:", detected_objects)

In this example:

Make sure you have the latest version of the Ultralytics YOLO package to avoid any compatibility issues. You can update it using:

pip install --upgrade ultralytics

If you encounter any issues or have further questions, feel free to ask. The YOLO community and the Ultralytics team are here to help! 😊

nikhilgarala-tecblic commented 4 months ago

Hello @pderrenger,

Thank you for your response. We are currently using Ultralytics for object detection in a live camera. While our model successfully detects objects, we are unable to retrieve the object names in Flutter. I have attached the code for your reference. Could you please take a moment to assist us? Your help would be greatly appreciated.

import 'dart:io' as io; import 'dart:io';

import 'package:flutter/material.dart'; import 'package:path/path.dart'; import 'package:path_provider/path_provider.dart'; import 'package:flutter/services.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:ultralytics_yolo/ultralytics_yolo.dart'; import 'package:ultralytics_yolo/yolo_model.dart'; import 'package:ultralytics_yolo_example/common_widget/common_filepath.dart';

void main() { runApp(const MyApp()); }

class MyApp extends StatefulWidget { const MyApp({super.key});

@override State createState() => _MyAppState(); }

class _MyAppState extends State {

final controller = UltralyticsYoloCameraController();

@override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( body: FutureBuilder( future: _checkPermissions(), builder: (context, snapshot) { debugPrint("Error Permission :: ${snapshot.error.toString()} == ${!snapshot.data!}"); if (!snapshot.hasData || !snapshot.data!) { return (Platform.isAndroid) ? Center( child: Column( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: [ ElevatedButton( onPressed: () { setState(() { _checkPermissions(); }); }, child: const Text("Ask Permission"), ) ], ), ) : Container(); // Show some error or loading widget } debugPrint("Error2 Permission :: ${snapshot.error.toString()}"); return FutureBuilder( future: _initObjectDetectorWithLocalModel(), builder: (context, snapshot) { debugPrint("Object Detector :: ${snapshot.data.toString()}"); if (!snapshot.hasData) { return Container( child: Center( child: Column( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: [ ElevatedButton( onPressed: (){ setState(() { _checkPermissions(); }); }, child: const Text("Ask for Permission"), ) ], ), ), ); // Show some error or loading widget } final predictor = snapshot.data; debugPrint("----- Predictor ::: ${predictor!.}"); debugPrint("----- Predictor length ::: ${predictor!.detectionResultStream.}"); return predictor == null ? Container() : Stack( children: [ UltralyticsYoloCameraPreview( controller: controller, predictor: predictor, onCameraCreated: () { predictor.loadModel(useGpu: true); }, boundingBoxesColorList: const [ Colors.black, Colors.amber, Colors.deepOrange, ], loadingPlaceholder: const Center( child: Wrap( direction: Axis.vertical, crossAxisAlignment: WrapCrossAlignment.center, children: [ CircularProgressIndicator( color: Colors.white, strokeWidth: 2, ), SizedBox(height: 20), Text( 'Loading model...', ), ]), ), ), StreamBuilder<double?>( stream: predictor.inferenceTime, builder: (context, snapshot) { final inferenceTime = snapshot.data;

                          return StreamBuilder<double?>(
                            stream: predictor.fpsRate,
                            builder: (context, snapshot) {
                              final fpsRate = snapshot.data;

                              return Times(
                                inferenceTime: inferenceTime,
                                fpsRate: fpsRate,
                              );
                            },
                          );
                        },
                      ),
                    ],
                  );
          },
        );
      },
    ),
    floatingActionButton: FloatingActionButton(
      child: const Icon(Icons.abc),
      onPressed: () {
        _checkPermissions().then((valued) {
          if (valued) {
            controller.toggleLensDirection();
          } else {
            debugPrint("All Permission Not Granted");
          }
        });
      },
    ),
  ),
);

}

Future _initObjectDetectorWithLocalModel() async { if (Platform.isAndroid) { debugPrint("____Android Run____"); final metadataPath = await _copy(CommonFilepath.meta_yaml); final modelPath = await _copy(CommonFilepath.tflite_path);

  final model = LocalYoloModel(
    id: '',
    task: Task.detect,
    format: Format.tflite,
    modelPath: modelPath,
    metadataPath: metadataPath,
  );
  return ObjectDetector(model: model);
} else {
  debugPrint("________________IOS Run________________");
  final modelPath = await _copy(CommonFilepath.mlmodel_tflite_path);
  final model = LocalYoloModel(
    id: '',
    task: Task.detect,
    format: Format.coreml,
    modelPath: modelPath,
  );
  return ObjectDetector(model: model);
}

}

dux-tecblic commented 4 months ago

@pderrenger thank you for the quick response and providing the Python code snippet for getting coordinates of bounding boxes but we have requirement of getting coordinates of bounding boxes or class name in Flutter/Dart. How do we achieve this?

FYI base model is YOLOv8n.

pderrenger commented 4 months ago

Hello @dux-tecblic,

Thank you for providing the additional context. To retrieve the detected object names in Flutter/Dart using the Ultralytics YOLO model, you can follow these steps:

  1. Ensure you have the latest version: Make sure you are using the latest version of the ultralytics_yolo package to avoid any compatibility issues.

  2. Modify your code to extract class names: You can access the detection results, including class names, from the detectionResultStream. Here's an updated version of your code to help you achieve this:

import 'dart:io' as io;
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
import 'package:flutter/services.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:ultralytics_yolo/ultralytics_yolo.dart';
import 'package:ultralytics_yolo/yolo_model.dart';
import 'package:ultralytics_yolo_example/common_widget/common_filepath.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final controller = UltralyticsYoloCameraController();

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: FutureBuilder<bool>(
          future: _checkPermissions(),
          builder: (context, snapshot) {
            if (!snapshot.hasData || !snapshot.data!) {
              return (Platform.isAndroid)
                  ? Center(
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.center,
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: <Widget>[
                          ElevatedButton(
                            onPressed: () {
                              setState(() {
                                _checkPermissions();
                              });
                            },
                            child: const Text("Ask Permission"),
                          )
                        ],
                      ),
                    )
                  : Container(); // Show some error or loading widget
            }
            return FutureBuilder<ObjectDetector>(
              future: _initObjectDetectorWithLocalModel(),
              builder: (context, snapshot) {
                if (!snapshot.hasData) {
                  return Center(
                    child: CircularProgressIndicator(),
                  ); // Show some error or loading widget
                }
                final predictor = snapshot.data;
                return predictor == null
                    ? Container()
                    : Stack(
                        children: [
                          UltralyticsYoloCameraPreview(
                            controller: controller,
                            predictor: predictor,
                            onCameraCreated: () {
                              predictor.loadModel(useGpu: true);
                            },
                            boundingBoxesColorList: const [
                              Colors.black,
                              Colors.amber,
                              Colors.deepOrange,
                            ],
                            loadingPlaceholder: const Center(
                              child: Wrap(
                                  direction: Axis.vertical,
                                  crossAxisAlignment: WrapCrossAlignment.center,
                                  children: [
                                    CircularProgressIndicator(
                                      color: Colors.white,
                                      strokeWidth: 2,
                                    ),
                                    SizedBox(height: 20),
                                    Text(
                                      'Loading model...',
                                    ),
                                  ]),
                            ),
                          ),
                          StreamBuilder<List<DetectionResult>>(
                            stream: predictor.detectionResultStream,
                            builder: (context, snapshot) {
                              if (!snapshot.hasData) {
                                return Container();
                              }
                              final detectionResults = snapshot.data!;
                              return Column(
                                children: detectionResults.map((result) {
                                  return Text(
                                    'Detected: ${result.className}, Confidence: ${result.confidence}',
                                    style: TextStyle(color: Colors.white),
                                  );
                                }).toList(),
                              );
                            },
                          ),
                          StreamBuilder<double?>(
                            stream: predictor.inferenceTime,
                            builder: (context, snapshot) {
                              final inferenceTime = snapshot.data;

                              return StreamBuilder<double?>(
                                stream: predictor.fpsRate,
                                builder: (context, snapshot) {
                                  final fpsRate = snapshot.data;

                                  return Times(
                                    inferenceTime: inferenceTime,
                                    fpsRate: fpsRate,
                                  );
                                },
                              );
                            },
                          ),
                        ],
                      );
              },
            );
          },
        ),
        floatingActionButton: FloatingActionButton(
          child: const Icon(Icons.abc),
          onPressed: () {
            _checkPermissions().then((valued) {
              if (valued) {
                controller.toggleLensDirection();
              } else {
                debugPrint("All Permission Not Granted");
              }
            });
          },
        ),
      ),
    );
  }

  Future<ObjectDetector> _initObjectDetectorWithLocalModel() async {
    if (Platform.isAndroid) {
      final metadataPath = await _copy(CommonFilepath.meta_yaml);
      final modelPath = await _copy(CommonFilepath.tflite_path);

      final model = LocalYoloModel(
        id: '',
        task: Task.detect,
        format: Format.tflite,
        modelPath: modelPath,
        metadataPath: metadataPath,
      );
      return ObjectDetector(model: model);
    } else {
      final modelPath = await _copy(CommonFilepath.mlmodel_tflite_path);
      final model = LocalYoloModel(
        id: '',
        task: Task.detect,
        format: Format.coreml,
        modelPath: modelPath,
      );
      return ObjectDetector(model: model);
    }
  }

  Future<bool> _checkPermissions() async {
    final status = await Permission.camera.request();
    return status.isGranted;
  }

  Future<String> _copy(String assetPath) async {
    final directory = await getApplicationDocumentsDirectory();
    final path = join(directory.path, basename(assetPath));
    final file = io.File(path);
    if (!await file.exists()) {
      final byteData = await rootBundle.load(assetPath);
      await file.writeAsBytes(byteData.buffer.asUint8List());
    }
    return path;
  }
}

In this updated code:

This should help you retrieve and display the detected object names in your Flutter application. If you have any further questions or run into issues, feel free to ask. The YOLO community and the Ultralytics team are here to support you! 😊

dux-tecblic commented 4 months ago

Thank you for your instant reply @pderrenger! Your suggested modifications in the code worked for us.

pderrenger commented 4 months ago

Hello @dux-tecblic,

I'm glad to hear that the suggested modifications worked for you! 🎉

If you encounter any further issues or have additional questions, please don't hesitate to reach out. Also, if you haven't already, make sure to keep your packages updated to the latest versions to benefit from the latest features and bug fixes.

For any other queries or troubleshooting, the Ultralytics documentation is a great resource, and the community is always here to help.

Happy coding! 😊

nikhilgarala-tecblic commented 4 months ago

Thanks @pderrenger for your quick reply! Your code really helped us out. Appreciate your assistance!

pderrenger commented 4 months ago

Hello @nikhilgarala-tecblic,

Thank you for your kind words! I'm delighted to hear that the code modifications were helpful for your project. 😊

If you encounter any further issues or have additional questions, please ensure you are using the latest versions of the Ultralytics packages. This helps in avoiding any known bugs and taking advantage of the latest features and improvements.

For any other queries or troubleshooting, you can always refer to the Ultralytics documentation, which is a comprehensive resource.

Feel free to reach out here if you need more assistance. The YOLO community and the Ultralytics team are always here to support you!

Happy coding and best of luck with your project! 🚀