Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Drawing the bounding boxes on detection #46

Open
hafidhhusna opened this issue Aug 3, 2024 · 3 comments
Open

Drawing the bounding boxes on detection #46

hafidhhusna opened this issue Aug 3, 2024 · 3 comments

Comments

@hafidhhusna
Copy link

i have the problem on the bounding boxes not drawn when i tried to run the inference on my flutter app code

import 'package:flutter/material.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:ultralytics_yolo/predict/detect/detect.dart';
import 'package:ultralytics_yolo/ultralytics_yolo.dart';
import 'package:ultralytics_yolo/yolo_model.dart';

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

@OverRide
State createState() => _ScanControllerState();
}

class _ScanControllerState extends State {
final controller = UltralyticsYoloCameraController();
bool _cameraPermissionGranted = false;
ObjectDetector? predictor;

@OverRide
void initState() {
super.initState();
_checkCameraPermission();
}

Future _checkCameraPermission() async {
try {
final cameraStatus = await Permission.camera.status;
print('Initial Camera status: $cameraStatus');

  if (!cameraStatus.isGranted) {
    print('Requesting camera permission...');
    final statuses = await [Permission.camera].request();
    print('Permission statuses after request: $statuses');

    setState(() {
      _cameraPermissionGranted = statuses[Permission.camera] == PermissionStatus.granted;
    });
  } else {
    setState(() {
      _cameraPermissionGranted = true;
    });
  }
} catch (e) {
  print('Error checking/requesting camera permission: $e');
  setState(() {
    _cameraPermissionGranted = false;
  });
}

print('Final Camera Permission granted: $_cameraPermissionGranted');

}

@OverRide
Widget build(BuildContext context) {
return Scaffold(
body: !_cameraPermissionGranted
? Center(child: Text('Camera permission not granted'))
: FutureBuilder(
future: _initObjectDetector(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
} else if (snapshot.hasError) {
print('Error initializing detector: ${snapshot.error}');
return Center(child: Text('Error initializing detector: ${snapshot.error}'));
}

            predictor = snapshot.data;

            if (predictor == null) {
              print('Predictor initialization failed');
              return Center(child: Text('Predictor initialization failed'));
            }

            return Stack(
              children: [
                UltralyticsYoloCameraPreview(
                  predictor: predictor!,
                  controller: controller,
                  onCameraCreated: () async {
                    try {
                      print('Attempting to load model...');
                      await predictor!.loadModel(useGpu: false);
                      print('Model loaded successfully');
                    } catch (e) {
                      print('Error loading model: $e');
                    }
                  },
                ),
                StreamBuilder<double?>(
                  stream: predictor!.inferenceTime,
                  builder: (context, snapshot) {
                    final inferenceTime = snapshot.data;

                    print('Inference Time StreamBuilder updated: ${inferenceTime?.toStringAsFixed(2) ?? 'N/A'} ms');

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

                        print('FPS Rate StreamBuilder updated: ${fpsRate?.toStringAsFixed(2) ?? 'N/A'}');

                        return Times(
                          inferenceTime: inferenceTime,
                          fpsRate: fpsRate,
                        );
                      },
                    );
                  },
                ),
              ],
            );
          },
        ),
);

}

Future _initObjectDetector() async {
final model = LocalYoloModel(
id: '',
modelPath: 'assets/model/BILI.tflite',
task: Task.classify,
format: Format.tflite,
metadataPath: 'assets/metadata/metadata.yaml',
);

try {
  final detector = ObjectDetector(model: model);
  print('ObjectDetector initialized successfully');
  return detector;
} catch (e) {
  print('Error initializing ObjectDetector: $e');
  rethrow;
}

}
}

class Times extends StatelessWidget {
final double? inferenceTime;
final double? fpsRate;

const Times({
Key? key,
required this.inferenceTime,
required this.fpsRate,
}) : super(key: key);

@OverRide
Widget build(BuildContext context) {
return Positioned(
bottom: 10,
left: 10,
child: Column(
children: [
Text('Inference Time: ${inferenceTime?.toStringAsFixed(2) ?? 'N/A'} ms'),
Text('FPS Rate: ${fpsRate?.toStringAsFixed(2) ?? 'N/A'}'),
],
),
);
}
}

@XeroDays
Copy link
Contributor

XeroDays commented Aug 7, 2024

Try this code, i am using another class which has the model, you just need to put the model here and load the model.


import 'package:camera/camera.dart';
import 'package:flutter/material.dart';
import 'package:intelpro/controller/loadercontroller.dart';
import 'package:intelpro/screens/screenpreview.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:ultralytics_yolo/ultralytics_yolo.dart';

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

  @override
  State<LiveView> createState() => _LiveViewState();
}

class _LiveViewState extends State<LiveView> {
  final controller = UltralyticsYoloCameraController();

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: FutureBuilder<bool>(
          future: _checkPermissions(),
          builder: (context, snapshot) {
            final allPermissionsGranted = snapshot.data ?? false;
            return !allPermissionsGranted
                ? Container()
                : FutureBuilder<ObjectDetector>(
                    future: _initObjectDetectorWithLocalModel(),
                    builder: (context, snapshot) {
                      final predictor = snapshot.data;
                      return predictor == null
                          ? Container()
                          : Stack(
                              children: [
                                UltralyticsYoloCameraPreview(
                                    controller: controller,
                                    predictor: predictor,
                                    onCameraCreated: () {
                                      predictor.loadModel(useGpu: true);
                                    }),
                                StreamBuilder(
                                    stream: predictor.detectionResultStream,
                                    builder: (context, snapshot) {
                                      final detectionResult = snapshot.data;

                                      return detectionResult == null
                                          ? Container()
                                          : Stack(
                                              children: detectionResult
                                                  .map((detectedObject) {
                                              final boundingBox =
                                                  detectedObject!.boundingBox;
                                              return Positioned(
                                                left: boundingBox.left,
                                                top: boundingBox.top,
                                                width: boundingBox.width,
                                                height: boundingBox.height,
                                                child: Container(
                                                  decoration: BoxDecoration(
                                                    color: Colors.green
                                                        .withOpacity(0.5),
                                                    border: Border.all(
                                                      color: Colors.green,
                                                      width: 2,
                                                    ),
                                                    borderRadius:
                                                        BorderRadius.circular(
                                                            5),
                                                  ),
                                                  child: //add label and confidence label
                                                      SingleChildScrollView(
                                                    child: Column(
                                                      children: [
                                                        Text(
                                                          detectedObject.label,
                                                          style:
                                                              const TextStyle(
                                                                  color: Colors
                                                                      .black,
                                                                  fontSize: 16),
                                                        ),
                                                        Text(
                                                          (detectedObject
                                                                      .confidence *
                                                                  100)
                                                              .toInt()
                                                              .toString(),
                                                          style:
                                                              const TextStyle(
                                                                  color: Colors
                                                                      .black,
                                                                  fontSize: 16),
                                                        ),
                                                      ],
                                                    ),
                                                  ),
                                                ),
                                              );
                                            }).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: () {
            controller.dispose();
            controller.closeCamera();
            controller.pauseLivePrediction();
            controller.toggleLensDirection();

            Navigator.pushReplacement(
              context,
              MaterialPageRoute(builder: (context) => const ScreenPreview()),
            );
          },
        ),
      ),
    );
  }

  Future<ObjectDetector> _initObjectDetectorWithLocalModel() async {
    return ObjectDetector(model: LoaderController.model!);
  }

  Future<bool> _checkPermissions() async {
    List<Permission> permissions = [];

    var cameraStatus = await Permission.camera.status;
    if (!cameraStatus.isGranted) permissions.add(Permission.camera);

    var storageStatus = await Permission.storage.status;
    if (!storageStatus.isGranted) permissions.add(Permission.storage);

    if (permissions.isEmpty) {
      return true;
    } else {
      try {
        Map<Permission, PermissionStatus> statuses =
            await permissions.request();
        return statuses[Permission.camera] == PermissionStatus.granted &&
            statuses[Permission.storage] == PermissionStatus.granted;
      } on Exception catch (_) {
        return false;
      }
    }
  }
}

class Times extends StatelessWidget {
  const Times({
    super.key,
    required this.inferenceTime,
    required this.fpsRate,
  });

  final double? inferenceTime;
  final double? fpsRate;

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Align(
        alignment: Alignment.bottomCenter,
        child: Container(
            margin: const EdgeInsets.all(20),
            padding: const EdgeInsets.all(20),
            decoration: const BoxDecoration(
              borderRadius: BorderRadius.all(Radius.circular(10)),
              color: Colors.black54,
            ),
            child: Text(
              '${(inferenceTime ?? 0).toStringAsFixed(1)} ms  -  ${(fpsRate ?? 0).toStringAsFixed(1)} FPS',
              style: const TextStyle(color: Colors.white70),
            )),
      ),
    );
  }
}

@hafidhhusna
Copy link
Author

can you provide me with the loadercontroller and screenpreview code?

@glenn-jocher
Copy link
Member

Hello!

Thank you for reaching out. It looks like you're making great progress with your Flutter app using Ultralytics YOLO. Unfortunately, I can't provide specific code for LoaderController and ScreenPreview as these are custom classes specific to your project. However, I can guide you on how to structure these components.

LoaderController

The LoaderController class should handle the loading of your YOLO model. Here's a basic example:

import 'package:ultralytics_yolo/ultralytics_yolo.dart';

class LoaderController {
  static YoloModel? model;

  static Future<void> loadModel() async {
    model = LocalYoloModel(
      id: 'your_model_id',
      modelPath: 'assets/model/BILI.tflite',
      task: Task.detect,
      format: Format.tflite,
      metadataPath: 'assets/metadata/metadata.yaml',
    );
    await model!.load();
  }
}

ScreenPreview

The ScreenPreview class can be a simple screen that displays the camera preview along with the detected objects. Here's a basic example:

import 'package:flutter/material.dart';

class ScreenPreview extends StatelessWidget {
  const ScreenPreview({Key? key}) : super(key: key);

  @hafidhhusna
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Screen Preview'),
      ),
      body: Center(
        child: Text('This is the screen preview.'),
      ),
    );
  }
}

Integration

Make sure to initialize the LoaderController before using it in your LiveView class:

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await LoaderController.loadModel();
  runApp(const LiveView());
}

If you encounter any issues, please ensure you are using the latest versions of the Ultralytics packages. If the problem persists, feel free to share more details, and we can troubleshoot further together.

Happy coding! 😊

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants