vladiH / flutter_vision

A Flutter plugin for managing both Yolov5 model and Tesseract v4, accessing with TensorFlow Lite 2.x. Support object detection, segmentation and OCR on both iOS and Android.
https://pub.dev/packages/flutter_vision
MIT License
70 stars 30 forks source link

two models at once #43

Open neryabCommitted opened 2 months ago

neryabCommitted commented 2 months ago

hey, because of budget consideration I'm forced to run two yolo models at the same time (instead of training one that combines them).

it it possible with flutterVision?

from what i've seen for some reason it only inference the second model loaded

Future<void> loadYoloModel() async {
    await vision1.loadYoloModel(
      labels: 'assets/labels1.txt',
      modelPath: 'assets/model1.tflite',
      modelVersion: "yolov5",
      numThreads: 4,
      useGpu: true,
    );

    await vision2.loadYoloModel(
      labels: 'assets/labels2.txt',
      modelPath: 'assets/model2.tflite',
      modelVersion: "yolov5",
      numThreads: 4,
      useGpu: true,
    );
  }
a-sajjad72 commented 1 month ago

hey @neryabCommitted you can create a drop down menu.. by which you can switch to your model from model1.tflite to model2.tflite. if you'd say i will share a code snippet that allows you to switch between your models.

neryabigon commented 1 month ago

thank you, that can be helpful

a-sajjad72 commented 1 month ago

thank you, that can be helpful

I had put all the models in the project_directory/assets/models/ folder and the labels in the project_directory/assets/labels.txt file. The vision object is an instance of the FlutterVision class that I created to handle the detection tasks. The modelPath is the path to the selected model from the dropdown menu and the modelPaths is a list of available models. If you have any further questions, feel free to ask.

  1. Dropdown Menu for Model Selection:

    DropdownButton<String>(
     value: selectedModel,
     onChanged: (String? newValue) {
       setState(() {
         selectedModel = newValue!;
       });
       loadYoloModel(selectedModel);
     },
     items: modelPaths.map<DropdownMenuItem<String>>((String value) {
       return DropdownMenuItem<String>(
         value: value,
         child: Text(value),
       );
     }).toList(),
    ),
  2. List of Available Models:

    final List<String> modelPaths = [
     'best_float16.tflite',
     'best_float32.tflite',
     'best_full_integer_quant.tflite',
     'best_int8.tflite',
     'best_integer_quant.tflite',
    ];
  3. Loading the Selected Model:

    Future<void> loadYoloModel(String modelPath) async {
     await vision.loadYoloModel(
       labels: 'assets/labels.txt',
       modelPath: 'assets/models/$modelPath',
       modelVersion: "yolov8",
       quantization: false,
       numThreads: 2,
       useGpu: true,
     );
    }
  4. Passing the Selected Model Path to the Detection Widget:

    Widget task(Options option) {
     if (option == Options.imagev8) {
       return YoloImageV8(vision: vision, modelPath: selectedModel);
     }
     return const Center(child: Text("Trieu Tasca"));
    }
  5. Using the Selected Model in the Detection Widget:

    class YoloImageV8 extends StatefulWidget {
     final FlutterVision vision;
     final String modelPath;
    
     const YoloImageV8({Key? key, required this.vision, required this.modelPath})
         : super(key: key);
    
     @override
     State<YoloImageV8> createState() => _YoloImageV8State();
    }
    
    class _YoloImageV8State extends State<YoloImageV8> {
     @override
     void initState() {
       super.initState();
       loadYoloModel(widget.modelPath).then((value) {
         setState(() {
           yoloResults = [];
           isLoaded = true;
         });
       });
     }
    
     Future<void> loadYoloModel(String modelPath) async {
       await widget.vision.loadYoloModel(
         labels: 'assets/labels.txt',
         modelPath: 'assets/models/$modelPath',
         modelVersion: "yolov8",
         quantization: false,
         numThreads: 2,
         useGpu: true,
       );
       setState(() {
         isLoaded = true;
       });
     }
    }

Make sure the logs on the console shows you the positive result whenever you choose any model from the dropdown menu. It will be something like,

I/tflite  (12680): Replacing 465 node(s) with delegate (TfLiteXNNPackDelegate) node, yielding 29 partitions.
I/tflite  (12680): Replacing 211 node(s) with delegate (TfLiteXNNPackDelegate) node, yielding 145 partitions.
I/tflite  (12680): Replacing 465 node(s) with delegate (TfLiteXNNPackDelegate) node, yielding 29 partitions.