From dfc9ed098cd2785bb6b81bc17c92214e4a2b46ea Mon Sep 17 00:00:00 2001 From: hdnh2006 Date: Wed, 12 Apr 2023 19:50:31 +0200 Subject: [PATCH 01/13] all yolov5 models are supported --- anylabeling/configs/autolabel_yolov5l.yaml | 90 +++++++++++++++++++ anylabeling/configs/autolabel_yolov5n.yaml | 90 +++++++++++++++++++ anylabeling/configs/autolabel_yolov5x.yaml | 90 +++++++++++++++++++ anylabeling/services/auto_labeling/model.py | 6 +- .../services/auto_labeling/model_manager.py | 4 + 5 files changed, 277 insertions(+), 3 deletions(-) create mode 100644 anylabeling/configs/autolabel_yolov5l.yaml create mode 100644 anylabeling/configs/autolabel_yolov5n.yaml create mode 100644 anylabeling/configs/autolabel_yolov5x.yaml diff --git a/anylabeling/configs/autolabel_yolov5l.yaml b/anylabeling/configs/autolabel_yolov5l.yaml new file mode 100644 index 0000000..316bf82 --- /dev/null +++ b/anylabeling/configs/autolabel_yolov5l.yaml @@ -0,0 +1,90 @@ +type: yolov5 +name: yolov5l +display_name: YOLOv5l Ultralytics +model_path: anylabeling_assets/models/yolov5/yolov5l.onnx +input_width: 640 +input_height: 640 +score_threshold: 0.5 +nms_threshold: 0.45 +confidence_threshold: 0.45 +classes: + - person + - bicycle + - car + - motorcycle + - airplane + - bus + - train + - truck + - boat + - traffic light + - fire hydrant + - stop sign + - parking meter + - bench + - bird + - cat + - dog + - horse + - sheep + - cow + - elephant + - bear + - zebra + - giraffe + - backpack + - umbrella + - handbag + - tie + - suitcase + - frisbee + - skis + - snowboard + - sports ball + - kite + - baseball bat + - baseball glove + - skateboard + - surfboard + - tennis racket + - bottle + - wine glass + - cup + - fork + - knife + - spoon + - bowl + - banana + - apple + - sandwich + - orange + - broccoli + - carrot + - hot dog + - pizza + - donut + - cake + - chair + - couch + - potted plant + - bed + - dining table + - toilet + - tv + - laptop + - mouse + - remote + - keyboard + - cell phone + - microwave + - oven + - toaster + - sink + - refrigerator + - book + - clock + - vase + - scissors + - teddy bear + - hair drier + - toothbrush diff --git a/anylabeling/configs/autolabel_yolov5n.yaml b/anylabeling/configs/autolabel_yolov5n.yaml new file mode 100644 index 0000000..a6f8bf4 --- /dev/null +++ b/anylabeling/configs/autolabel_yolov5n.yaml @@ -0,0 +1,90 @@ +type: yolov5 +name: yolov5n +display_name: YOLOv5n Ultralytics +model_path: anylabeling_assets/models/yolov5/yolov5n.onnx +input_width: 640 +input_height: 640 +score_threshold: 0.5 +nms_threshold: 0.45 +confidence_threshold: 0.45 +classes: + - person + - bicycle + - car + - motorcycle + - airplane + - bus + - train + - truck + - boat + - traffic light + - fire hydrant + - stop sign + - parking meter + - bench + - bird + - cat + - dog + - horse + - sheep + - cow + - elephant + - bear + - zebra + - giraffe + - backpack + - umbrella + - handbag + - tie + - suitcase + - frisbee + - skis + - snowboard + - sports ball + - kite + - baseball bat + - baseball glove + - skateboard + - surfboard + - tennis racket + - bottle + - wine glass + - cup + - fork + - knife + - spoon + - bowl + - banana + - apple + - sandwich + - orange + - broccoli + - carrot + - hot dog + - pizza + - donut + - cake + - chair + - couch + - potted plant + - bed + - dining table + - toilet + - tv + - laptop + - mouse + - remote + - keyboard + - cell phone + - microwave + - oven + - toaster + - sink + - refrigerator + - book + - clock + - vase + - scissors + - teddy bear + - hair drier + - toothbrush diff --git a/anylabeling/configs/autolabel_yolov5x.yaml b/anylabeling/configs/autolabel_yolov5x.yaml new file mode 100644 index 0000000..8867083 --- /dev/null +++ b/anylabeling/configs/autolabel_yolov5x.yaml @@ -0,0 +1,90 @@ +type: yolov5 +name: yolov5x +display_name: YOLOv5x Ultralytics +model_path: anylabeling_assets/models/yolov5/yolov5x.onnx +input_width: 640 +input_height: 640 +score_threshold: 0.5 +nms_threshold: 0.45 +confidence_threshold: 0.45 +classes: + - person + - bicycle + - car + - motorcycle + - airplane + - bus + - train + - truck + - boat + - traffic light + - fire hydrant + - stop sign + - parking meter + - bench + - bird + - cat + - dog + - horse + - sheep + - cow + - elephant + - bear + - zebra + - giraffe + - backpack + - umbrella + - handbag + - tie + - suitcase + - frisbee + - skis + - snowboard + - sports ball + - kite + - baseball bat + - baseball glove + - skateboard + - surfboard + - tennis racket + - bottle + - wine glass + - cup + - fork + - knife + - spoon + - bowl + - banana + - apple + - sandwich + - orange + - broccoli + - carrot + - hot dog + - pizza + - donut + - cake + - chair + - couch + - potted plant + - bed + - dining table + - toilet + - tv + - laptop + - mouse + - remote + - keyboard + - cell phone + - microwave + - oven + - toaster + - sink + - refrigerator + - book + - clock + - vase + - scissors + - teddy bear + - hair drier + - toothbrush diff --git a/anylabeling/services/auto_labeling/model.py b/anylabeling/services/auto_labeling/model.py index 49937b1..ec75657 100644 --- a/anylabeling/services/auto_labeling/model.py +++ b/anylabeling/services/auto_labeling/model.py @@ -11,7 +11,7 @@ class Model: BASE_DOWNLOAD_URL = ( - "https://github.com/vietanhdev/anylabeling-assets/raw/main/" + "https://github.com/hdnh2006/anylabeling-assets/releases/download/v0.0.0/" ) class Meta: @@ -57,8 +57,8 @@ def get_model_abs_path(self, model_path): " while..." ) relative_path = model_path.replace("anylabeling_assets/", "") - download_url = self.BASE_DOWNLOAD_URL + relative_path - home_dir = os.path.expanduser("~") + download_url = self.BASE_DOWNLOAD_URL + relative_path.replace("models/yolov5/","") + home_dir = os.getcwd() model_abs_path = os.path.abspath( os.path.join(home_dir, "data", relative_path) ) diff --git a/anylabeling/services/auto_labeling/model_manager.py b/anylabeling/services/auto_labeling/model_manager.py index 4133fde..5b6b07b 100644 --- a/anylabeling/services/auto_labeling/model_manager.py +++ b/anylabeling/services/auto_labeling/model_manager.py @@ -21,10 +21,14 @@ class ModelManager(QObject): model_configs = { "segment_anything_vit_b": "autolabel_segment_anything.yaml", + "yolov5n": "autolabel_yolov5n.yaml", "yolov5s": "autolabel_yolov5s.yaml", "yolov5m": "autolabel_yolov5m.yaml", + "yolov5l": "autolabel_yolov5l.yaml", + "yolov5x": "autolabel_yolov5x.yaml", } + def __init__(self): super().__init__() self.model_infos = {} From 5a2cedb5fee80eb949bd0fb5cc47879ae0d4ac42 Mon Sep 17 00:00:00 2001 From: hdnh2006 Date: Wed, 12 Apr 2023 20:46:08 +0200 Subject: [PATCH 02/13] GPU support for segment anything --- anylabeling/services/auto_labeling/model.py | 2 +- anylabeling/services/auto_labeling/segment_anything.py | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/anylabeling/services/auto_labeling/model.py b/anylabeling/services/auto_labeling/model.py index f482ae4..2bbe506 100644 --- a/anylabeling/services/auto_labeling/model.py +++ b/anylabeling/services/auto_labeling/model.py @@ -57,7 +57,7 @@ def get_model_abs_path(self, model_path): " while..." ) relative_path = model_path.replace("anylabeling_assets/", "") - download_url = self.BASE_DOWNLOAD_URL + relative_path.replace("models/yolov5/","") + download_url = self.BASE_DOWNLOAD_URL + relative_path.replace("models/yolov5/","").replace("models/segment_anything/","") home_dir = os.getcwd() model_abs_path = os.path.abspath( os.path.join(home_dir, "data", relative_path) diff --git a/anylabeling/services/auto_labeling/segment_anything.py b/anylabeling/services/auto_labeling/segment_anything.py index 0b65adc..a6f63e5 100644 --- a/anylabeling/services/auto_labeling/segment_anything.py +++ b/anylabeling/services/auto_labeling/segment_anything.py @@ -54,11 +54,13 @@ def __init__(self, config_path, on_message) -> None: raise Exception(f"Decoder not found: {decoder_model_abs_path}") # Load models + cuda = True if onnxruntime.get_device() == 'GPU' else False + providers = ['CUDAExecutionProvider', 'CPUExecutionProvider'] if cuda else ['CPUExecutionProvider'] self.encoder_session = onnxruntime.InferenceSession( - encoder_model_abs_path + encoder_model_abs_path, providers=providers ) self.decoder_session = onnxruntime.InferenceSession( - decoder_model_abs_path + decoder_model_abs_path, providers=providers ) # Mark for auto labeling From d152eac4e202ad077a6234ded1c8dddac77cd8ef Mon Sep 17 00:00:00 2001 From: hdnh2006 Date: Thu, 13 Apr 2023 10:51:02 +0200 Subject: [PATCH 03/13] yolov8 list menu added --- anylabeling/services/auto_labeling/model_manager.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/anylabeling/services/auto_labeling/model_manager.py b/anylabeling/services/auto_labeling/model_manager.py index 5b6b07b..5bcf720 100644 --- a/anylabeling/services/auto_labeling/model_manager.py +++ b/anylabeling/services/auto_labeling/model_manager.py @@ -26,6 +26,11 @@ class ModelManager(QObject): "yolov5m": "autolabel_yolov5m.yaml", "yolov5l": "autolabel_yolov5l.yaml", "yolov5x": "autolabel_yolov5x.yaml", + "yolov8n": "autolabel_yolov8n.yaml", + "yolov8s": "autolabel_yolov8s.yaml", + "yolov8m": "autolabel_yolov8m.yaml", + "yolov8l": "autolabel_yolov8l.yaml", + "yolov8x": "autolabel_yolov8x.yaml", } From 49bf719046efca8c1f51448da5bd3261de40014c Mon Sep 17 00:00:00 2001 From: hdnh2006 Date: Thu, 13 Apr 2023 11:13:47 +0200 Subject: [PATCH 04/13] models are downloaded from https://github.com/vietanhdev/anylabeling-assets/releases/download/v0.0.1/ --- anylabeling/services/auto_labeling/model.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/anylabeling/services/auto_labeling/model.py b/anylabeling/services/auto_labeling/model.py index d4f1f15..58fd44b 100644 --- a/anylabeling/services/auto_labeling/model.py +++ b/anylabeling/services/auto_labeling/model.py @@ -11,7 +11,7 @@ class Model: BASE_DOWNLOAD_URL = ( - "https://github.com/hdnh2006/anylabeling-assets/releases/download/v0.0.0/" + "https://github.com/vietanhdev/anylabeling-assets/releases/download/v0.0.1/" ) class Meta: @@ -58,7 +58,7 @@ def get_model_abs_path(self, model_path): ) relative_path = model_path.replace("anylabeling_assets/", "") download_url = self.BASE_DOWNLOAD_URL + relative_path.replace("models/yolov5/","").replace("models/segment_anything/","") - home_dir = os.getcwd() + home_dir = os.path.expanduser("~") model_abs_path = os.path.abspath( os.path.join(home_dir, "anylabeling_data", relative_path) ) From 294b090bd7332ce74397c0968152badd4e56bcad Mon Sep 17 00:00:00 2001 From: hdnh2006 Date: Thu, 13 Apr 2023 11:15:31 +0200 Subject: [PATCH 05/13] requirements change so SAM can be run in GPU --- requirements-dev.txt | 1 + requirements.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/requirements-dev.txt b/requirements-dev.txt index 15e5816..40b2fb3 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -5,6 +5,7 @@ github2pypi==1.0.0 pre-commit==2.20.0 onnx==1.13.1 onnxruntime==1.14.1 +onnxruntime-gpu==1.14.1 qimage2ndarray==1.10.0 build twine diff --git a/requirements.txt b/requirements.txt index b7a1d9a..e0ea96c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -18,4 +18,5 @@ PyYAML==6.0 colorama==0.4.5 onnx==1.13.1 onnxruntime==1.14.1 +onnxruntime-gpu==1.14.1 qimage2ndarray==1.10.0 From 894db66c2d78275c5026e9fe6b2a2b4b53d1c1cf Mon Sep 17 00:00:00 2001 From: hdnh2006 Date: Thu, 13 Apr 2023 12:25:50 +0200 Subject: [PATCH 06/13] .yaml files added --- anylabeling/configs/autolabel_yolov8l.yaml | 90 ++++++++++ anylabeling/configs/autolabel_yolov8m.yaml | 90 ++++++++++ anylabeling/configs/autolabel_yolov8n.yaml | 90 ++++++++++ anylabeling/configs/autolabel_yolov8s.yaml | 90 ++++++++++ anylabeling/configs/autolabel_yolov8x.yaml | 90 ++++++++++ anylabeling/services/auto_labeling/yolov8.py | 176 +++++++++++++++++++ borrador.py | 101 +++++++++++ 7 files changed, 727 insertions(+) create mode 100644 anylabeling/configs/autolabel_yolov8l.yaml create mode 100644 anylabeling/configs/autolabel_yolov8m.yaml create mode 100644 anylabeling/configs/autolabel_yolov8n.yaml create mode 100644 anylabeling/configs/autolabel_yolov8s.yaml create mode 100644 anylabeling/configs/autolabel_yolov8x.yaml create mode 100644 anylabeling/services/auto_labeling/yolov8.py create mode 100644 borrador.py diff --git a/anylabeling/configs/autolabel_yolov8l.yaml b/anylabeling/configs/autolabel_yolov8l.yaml new file mode 100644 index 0000000..2ad8977 --- /dev/null +++ b/anylabeling/configs/autolabel_yolov8l.yaml @@ -0,0 +1,90 @@ +type: yolov8 +name: yolov8l +display_name: YOLOv8l Ultralytics +model_path: anylabeling_assets/models/yolov8/yolov8l.onnx +input_width: 640 +input_height: 640 +score_threshold: 0.5 +nms_threshold: 0.45 +confidence_threshold: 0.45 +classes: + - person + - bicycle + - car + - motorcycle + - airplane + - bus + - train + - truck + - boat + - traffic light + - fire hydrant + - stop sign + - parking meter + - bench + - bird + - cat + - dog + - horse + - sheep + - cow + - elephant + - bear + - zebra + - giraffe + - backpack + - umbrella + - handbag + - tie + - suitcase + - frisbee + - skis + - snowboard + - sports ball + - kite + - baseball bat + - baseball glove + - skateboard + - surfboard + - tennis racket + - bottle + - wine glass + - cup + - fork + - knife + - spoon + - bowl + - banana + - apple + - sandwich + - orange + - broccoli + - carrot + - hot dog + - pizza + - donut + - cake + - chair + - couch + - potted plant + - bed + - dining table + - toilet + - tv + - laptop + - mouse + - remote + - keyboard + - cell phone + - microwave + - oven + - toaster + - sink + - refrigerator + - book + - clock + - vase + - scissors + - teddy bear + - hair drier + - toothbrush diff --git a/anylabeling/configs/autolabel_yolov8m.yaml b/anylabeling/configs/autolabel_yolov8m.yaml new file mode 100644 index 0000000..a62081e --- /dev/null +++ b/anylabeling/configs/autolabel_yolov8m.yaml @@ -0,0 +1,90 @@ +type: yolov8 +name: yolov8m +display_name: YOLOv8m Ultralytics +model_path: anylabeling_assets/models/yolov8/yolov8m.onnx +input_width: 640 +input_height: 640 +score_threshold: 0.5 +nms_threshold: 0.45 +confidence_threshold: 0.45 +classes: + - person + - bicycle + - car + - motorcycle + - airplane + - bus + - train + - truck + - boat + - traffic light + - fire hydrant + - stop sign + - parking meter + - bench + - bird + - cat + - dog + - horse + - sheep + - cow + - elephant + - bear + - zebra + - giraffe + - backpack + - umbrella + - handbag + - tie + - suitcase + - frisbee + - skis + - snowboard + - sports ball + - kite + - baseball bat + - baseball glove + - skateboard + - surfboard + - tennis racket + - bottle + - wine glass + - cup + - fork + - knife + - spoon + - bowl + - banana + - apple + - sandwich + - orange + - broccoli + - carrot + - hot dog + - pizza + - donut + - cake + - chair + - couch + - potted plant + - bed + - dining table + - toilet + - tv + - laptop + - mouse + - remote + - keyboard + - cell phone + - microwave + - oven + - toaster + - sink + - refrigerator + - book + - clock + - vase + - scissors + - teddy bear + - hair drier + - toothbrush diff --git a/anylabeling/configs/autolabel_yolov8n.yaml b/anylabeling/configs/autolabel_yolov8n.yaml new file mode 100644 index 0000000..becef1e --- /dev/null +++ b/anylabeling/configs/autolabel_yolov8n.yaml @@ -0,0 +1,90 @@ +type: yolov8 +name: yolov8n +display_name: yolov8n Ultralytics +model_path: anylabeling_assets/models/yolov8/yolov8n.onnx +input_width: 640 +input_height: 640 +score_threshold: 0.5 +nms_threshold: 0.45 +confidence_threshold: 0.45 +classes: + - person + - bicycle + - car + - motorcycle + - airplane + - bus + - train + - truck + - boat + - traffic light + - fire hydrant + - stop sign + - parking meter + - bench + - bird + - cat + - dog + - horse + - sheep + - cow + - elephant + - bear + - zebra + - giraffe + - backpack + - umbrella + - handbag + - tie + - suitcase + - frisbee + - skis + - snowboard + - sports ball + - kite + - baseball bat + - baseball glove + - skateboard + - surfboard + - tennis racket + - bottle + - wine glass + - cup + - fork + - knife + - spoon + - bowl + - banana + - apple + - sandwich + - orange + - broccoli + - carrot + - hot dog + - pizza + - donut + - cake + - chair + - couch + - potted plant + - bed + - dining table + - toilet + - tv + - laptop + - mouse + - remote + - keyboard + - cell phone + - microwave + - oven + - toaster + - sink + - refrigerator + - book + - clock + - vase + - scissors + - teddy bear + - hair drier + - toothbrush diff --git a/anylabeling/configs/autolabel_yolov8s.yaml b/anylabeling/configs/autolabel_yolov8s.yaml new file mode 100644 index 0000000..e11a4e5 --- /dev/null +++ b/anylabeling/configs/autolabel_yolov8s.yaml @@ -0,0 +1,90 @@ +type: yolov8 +name: yolov8s +display_name: YOLOv8s Ultralytics +model_path: anylabeling_assets/models/yolov8/yolov8s.onnx +input_width: 640 +input_height: 640 +score_threshold: 0.5 +nms_threshold: 0.45 +confidence_threshold: 0.45 +classes: + - person + - bicycle + - car + - motorcycle + - airplane + - bus + - train + - truck + - boat + - traffic light + - fire hydrant + - stop sign + - parking meter + - bench + - bird + - cat + - dog + - horse + - sheep + - cow + - elephant + - bear + - zebra + - giraffe + - backpack + - umbrella + - handbag + - tie + - suitcase + - frisbee + - skis + - snowboard + - sports ball + - kite + - baseball bat + - baseball glove + - skateboard + - surfboard + - tennis racket + - bottle + - wine glass + - cup + - fork + - knife + - spoon + - bowl + - banana + - apple + - sandwich + - orange + - broccoli + - carrot + - hot dog + - pizza + - donut + - cake + - chair + - couch + - potted plant + - bed + - dining table + - toilet + - tv + - laptop + - mouse + - remote + - keyboard + - cell phone + - microwave + - oven + - toaster + - sink + - refrigerator + - book + - clock + - vase + - scissors + - teddy bear + - hair drier + - toothbrush diff --git a/anylabeling/configs/autolabel_yolov8x.yaml b/anylabeling/configs/autolabel_yolov8x.yaml new file mode 100644 index 0000000..251d96a --- /dev/null +++ b/anylabeling/configs/autolabel_yolov8x.yaml @@ -0,0 +1,90 @@ +type: yolov8 +name: yolov8x +display_name: YOLOv8x Ultralytics +model_path: anylabeling_assets/models/yolov8/yolov8x.onnx +input_width: 640 +input_height: 640 +score_threshold: 0.5 +nms_threshold: 0.45 +confidence_threshold: 0.45 +classes: + - person + - bicycle + - car + - motorcycle + - airplane + - bus + - train + - truck + - boat + - traffic light + - fire hydrant + - stop sign + - parking meter + - bench + - bird + - cat + - dog + - horse + - sheep + - cow + - elephant + - bear + - zebra + - giraffe + - backpack + - umbrella + - handbag + - tie + - suitcase + - frisbee + - skis + - snowboard + - sports ball + - kite + - baseball bat + - baseball glove + - skateboard + - surfboard + - tennis racket + - bottle + - wine glass + - cup + - fork + - knife + - spoon + - bowl + - banana + - apple + - sandwich + - orange + - broccoli + - carrot + - hot dog + - pizza + - donut + - cake + - chair + - couch + - potted plant + - bed + - dining table + - toilet + - tv + - laptop + - mouse + - remote + - keyboard + - cell phone + - microwave + - oven + - toaster + - sink + - refrigerator + - book + - clock + - vase + - scissors + - teddy bear + - hair drier + - toothbrush diff --git a/anylabeling/services/auto_labeling/yolov8.py b/anylabeling/services/auto_labeling/yolov8.py new file mode 100644 index 0000000..eb5afc7 --- /dev/null +++ b/anylabeling/services/auto_labeling/yolov8.py @@ -0,0 +1,176 @@ +import logging +import os + +import cv2 +import numpy as np +from PyQt5 import QtCore + +from anylabeling.views.labeling.shape import Shape +from anylabeling.views.labeling.utils.opencv import qt_img_to_cv_img + +from .model import Model +from .types import AutoLabelingResult + + +class YOLOv5(Model): + """Object detection model using YOLOv5""" + + class Meta: + required_config_names = [ + "type", + "name", + "display_name", + "model_path", + "input_width", + "input_height", + "score_threshold", + "nms_threshold", + "confidence_threshold", + "classes", + ] + buttons = ["button_run"] + + def __init__(self, model_config, on_message) -> None: + # Run the parent class's init method + super().__init__(model_config, on_message) + + model_abs_path = self.get_model_abs_path(self.config["model_path"]) + if not os.path.isfile(model_abs_path): + raise Exception(f"Model not found: {model_abs_path}") + + self.net = cv2.dnn.readNet(model_abs_path) + self.net.setPreferableBackend(cv2.dnn.DNN_BACKEND_CUDA) + self.net.setPreferableTarget(cv2.dnn.DNN_TARGET_CUDA) + self.classes = self.config["classes"] + + def pre_process(self, input_image, net): + """ + Pre-process the input image before feeding it to the network. + """ + # Create a 4D blob from a frame. + blob = cv2.dnn.blobFromImage( + input_image, + 1 / 255, + (self.config["input_width"], self.config["input_height"]), + [0, 0, 0], + 1, + crop=False, + ) + + # Sets the input to the network. + net.setInput(blob) + + # Runs the forward pass to get output of the output layers. + output_layers = net.getUnconnectedOutLayersNames() + outputs = net.forward(output_layers) + + return outputs + + def post_process(self, input_image, outputs): + """ + Post-process the network's output, to get the bounding boxes and + their confidence scores. + """ + # Lists to hold respective values while unwrapping. + class_ids = [] + confidences = [] + boxes = [] + + # Rows. + rows = outputs[0].shape[1] + + image_height, image_width = input_image.shape[:2] + + # Resizing factor. + x_factor = image_width / self.config["input_width"] + y_factor = image_height / self.config["input_height"] + + # Iterate through 25200 detections. + for r in range(rows): + row = outputs[0][0][r] + confidence = row[4] + + # Discard bad detections and continue. + if confidence >= self.config["confidence_threshold"]: + classes_scores = row[5:] + + # Get the index of max class score. + class_id = np.argmax(classes_scores) + + # Continue if the class score is above threshold. + if classes_scores[class_id] > self.config["score_threshold"]: + confidences.append(confidence) + class_ids.append(class_id) + + cx, cy, w, h = row[0], row[1], row[2], row[3] + + left = int((cx - w / 2) * x_factor) + top = int((cy - h / 2) * y_factor) + width = int(w * x_factor) + height = int(h * y_factor) + + box = np.array([left, top, width, height]) + boxes.append(box) + + # Perform non maximum suppression to eliminate redundant + # overlapping boxes with lower confidences. + indices = cv2.dnn.NMSBoxes( + boxes, + confidences, + self.config["confidence_threshold"], + self.config["nms_threshold"], + ) + + output_boxes = [] + for i in indices: + box = boxes[i] + left = box[0] + top = box[1] + width = box[2] + height = box[3] + label = self.classes[class_ids[i]] + score = confidences[i] + + output_box = { + "x1": left, + "y1": top, + "x2": left + width, + "y2": top + height, + "label": label, + "score": score, + } + + output_boxes.append(output_box) + + return output_boxes + + def predict_shapes(self, image): + """ + Predict shapes from image + """ + + if image is None: + return [] + + try: + image = qt_img_to_cv_img(image) + except Exception as e: # noqa + logging.warning("Could not inference model") + logging.warning(e) + return [] + + detections = self.pre_process(image, self.net) + boxes = self.post_process(image, detections) + shapes = [] + + for box in boxes: + shape = Shape(label=box["label"], shape_type="rectangle", flags={}) + shape.add_point(QtCore.QPointF(box["x1"], box["y1"])) + shape.add_point(QtCore.QPointF(box["x2"], box["y2"])) + shapes.append(shape) + + result = AutoLabelingResult(shapes, replace=True) + return result + + def unload(self): + del self.net diff --git a/borrador.py b/borrador.py new file mode 100644 index 0000000..d601602 --- /dev/null +++ b/borrador.py @@ -0,0 +1,101 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on Thu Apr 13 10:16:59 2023 + +@author: henry +""" + +import cv2 +net = cv2.dnn.readNet("/home/henry/anylabeling_data/models/yolov5/yolov8x.onnx") +net.setPreferableBackend(cv2.dnn.DNN_BACKEND_DEFAULT) +net.setPreferableTarget(cv2.dnn.DNN_TARGET_CPU) +input_image = cv2.imread("coco_sample/000000000009.jpg") + +blob = cv2.dnn.blobFromImage(input_image, 1 / 255, (640, 640), swapRB=True, crop=False) + +net.setInput(blob) + + +# Runs the forward pass to get output of the output layers. +output_layers = net.getUnconnectedOutLayersNames() +outputs = net.forward() +outputs = outputs.transpose((0, 2, 1)) + + + + +# ========================================= post + + + +# Lists to hold respective values while unwrapping. +class_ids = [] +confidences = [] +boxes = [] + +# Rows. +rows = outputs[0].shape[0] + +image_height, image_width = input_image.shape[:2] + +# Resizing factor. +x_factor = image_width / config["input_width"] +y_factor = image_height / config["input_height"] + +# Iterate through 25200 detections. +for r in range(rows): + row = outputs[0][r] + confidence = row[4] + + # Discard bad detections and continue. + if confidence >= config["confidence_threshold"]: + classes_scores = row[5:] + + # Get the index of max class score. + class_id = np.argmax(classes_scores) + + # Continue if the class score is above threshold. + if classes_scores[class_id] > self.config["score_threshold"]: + confidences.append(confidence) + class_ids.append(class_id) + + cx, cy, w, h = row[0], row[1], row[2], row[3] + + left = int((cx - w / 2) * x_factor) + top = int((cy - h / 2) * y_factor) + width = int(w * x_factor) + height = int(h * y_factor) + + box = np.array([left, top, width, height]) + boxes.append(box) + +# Perform non maximum suppression to eliminate redundant +# overlapping boxes with lower confidences. +indices = cv2.dnn.NMSBoxes( + boxes, + confidences, + config["confidence_threshold"], + config["nms_threshold"], +) + +output_boxes = [] +for i in indices: + box = boxes[i] + left = box[0] + top = box[1] + width = box[2] + height = box[3] + label = classes[class_ids[i]] + score = confidences[i] + + output_box = { + "x1": left, + "y1": top, + "x2": left + width, + "y2": top + height, + "label": label, + "score": score, + } + + output_boxes.append(output_box) From 0a4293bd3c91a2148bcd6e627e386e5f32275147 Mon Sep 17 00:00:00 2001 From: hdnh2006 Date: Thu, 13 Apr 2023 18:42:58 +0200 Subject: [PATCH 07/13] borrador updated --- borrador.py | 45 +++++++++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/borrador.py b/borrador.py index d601602..9063dfb 100644 --- a/borrador.py +++ b/borrador.py @@ -7,20 +7,32 @@ """ import cv2 -net = cv2.dnn.readNet("/home/henry/anylabeling_data/models/yolov5/yolov8x.onnx") -net.setPreferableBackend(cv2.dnn.DNN_BACKEND_DEFAULT) -net.setPreferableTarget(cv2.dnn.DNN_TARGET_CPU) -input_image = cv2.imread("coco_sample/000000000009.jpg") +from PIL import Image +import numpy as np +net = cv2.dnn.readNetFromONNX("/home/henry/anylabeling_data/models/yolov5/yolov8x.onnx") +#net.setPreferableBackend(cv2.dnn.DNN_BACKEND_CUDA) +#net.setPreferableTarget(cv2.dnn.DNN_TARGET_CUDA) -blob = cv2.dnn.blobFromImage(input_image, 1 / 255, (640, 640), swapRB=True, crop=False) -net.setInput(blob) -# Runs the forward pass to get output of the output layers. -output_layers = net.getUnconnectedOutLayersNames() +config = {'type': 'yolov8', 'name': 'yolov8x', 'display_name': 'YOLOv5n Ultralytics', 'model_path': 'anylabeling_assets/models/yolov5/yolov8x.onnx', 'input_width': 640, 'input_height': 640, 'score_threshold': 0.5, 'nms_threshold': 0.45, 'confidence_threshold': 0.45, 'classes': ['person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 'train', 'truck', 'boat', 'traffic light', 'fire hydrant', 'stop sign', 'parking meter', 'bench', 'bird', 'cat', 'dog', 'horse', 'sheep', 'cow', 'elephant', 'bear', 'zebra', 'giraffe', 'backpack', 'umbrella', 'handbag', 'tie', 'suitcase', 'frisbee', 'skis', 'snowboard', 'sports ball', 'kite', 'baseball bat', 'baseball glove', 'skateboard', 'surfboard', 'tennis racket', 'bottle', 'wine glass', 'cup', 'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple', 'sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza', 'donut', 'cake', 'chair', 'couch', 'potted plant', 'bed', 'dining table', 'toilet', 'tv', 'laptop', 'mouse', 'remote', 'keyboard', 'cell phone', 'microwave', 'oven', 'toaster', 'sink', 'refrigerator', 'book', 'clock', 'vase', 'scissors', 'teddy bear', 'hair drier', 'toothbrush']} +classes = config["classes"] + + + +input_image = cv2.imread('bus.jpg') +#input_image = cv2.imread('coco_sample/000000000009.jpg') +[height, width, _] = input_image.shape +length = max((height, width)) +image = np.zeros((length, length, 3), np.uint8) +image[0:height, 0:width] = input_image + +blob = cv2.dnn.blobFromImage(image, scalefactor=1 / 255, size=(640, 640), swapRB=True) + +net.setInput(blob) outputs = net.forward() -outputs = outputs.transpose((0, 2, 1)) +outputs = np.array([cv2.transpose(outputs[0])]) @@ -35,7 +47,7 @@ boxes = [] # Rows. -rows = outputs[0].shape[0] +rows = outputs[0].shape[1] image_height, image_width = input_image.shape[:2] @@ -49,14 +61,14 @@ confidence = row[4] # Discard bad detections and continue. - if confidence >= config["confidence_threshold"]: - classes_scores = row[5:] + if confidence >= self.config["confidence_threshold"]: + classes_scores = row[4:] # Get the index of max class score. class_id = np.argmax(classes_scores) # Continue if the class score is above threshold. - if classes_scores[class_id] > self.config["score_threshold"]: + if classes_scores[class_id] > config["score_threshold"]: confidences.append(confidence) class_ids.append(class_id) @@ -75,7 +87,8 @@ indices = cv2.dnn.NMSBoxes( boxes, confidences, - config["confidence_threshold"], + 0.001, + #config["confidence_threshold"], config["nms_threshold"], ) @@ -99,3 +112,7 @@ } output_boxes.append(output_box) + cv2.rectangle(input_image, (left, top), (left + width, top + height), (0,255,0), 3) + +cv2.imwrite("test.jpg", input_image) +#Image.fromarray(cv2.cvtColor(input_image, cv2.COLOR_BGR2RGB)) From 00df5f85001d62e86c3d3b52b07f05cc64eb6adf Mon Sep 17 00:00:00 2001 From: hdnh2006 Date: Fri, 14 Apr 2023 11:24:58 +0200 Subject: [PATCH 08/13] update --- borrador.py | 64 ++++++++++++++++++++++++++++------------------------- 1 file changed, 34 insertions(+), 30 deletions(-) diff --git a/borrador.py b/borrador.py index 9063dfb..e5dd846 100644 --- a/borrador.py +++ b/borrador.py @@ -9,6 +9,7 @@ import cv2 from PIL import Image import numpy as np +from tqdm import tqdm net = cv2.dnn.readNetFromONNX("/home/henry/anylabeling_data/models/yolov5/yolov8x.onnx") #net.setPreferableBackend(cv2.dnn.DNN_BACKEND_CUDA) #net.setPreferableTarget(cv2.dnn.DNN_TARGET_CUDA) @@ -27,11 +28,12 @@ length = max((height, width)) image = np.zeros((length, length, 3), np.uint8) image[0:height, 0:width] = input_image +scale = length / 640 -blob = cv2.dnn.blobFromImage(image, scalefactor=1 / 255, size=(640, 640), swapRB=True) - +blob = cv2.dnn.blobFromImage(input_image, scalefactor=1 / 255, size=(640, 640), swapRB=True) net.setInput(blob) outputs = net.forward() + outputs = np.array([cv2.transpose(outputs[0])]) @@ -47,7 +49,7 @@ boxes = [] # Rows. -rows = outputs[0].shape[1] +rows = outputs.shape[1] image_height, image_width = input_image.shape[:2] @@ -56,40 +58,42 @@ y_factor = image_height / config["input_height"] # Iterate through 25200 detections. -for r in range(rows): +for r in tqdm(range(rows)): row = outputs[0][r] - confidence = row[4] - - # Discard bad detections and continue. - if confidence >= self.config["confidence_threshold"]: - classes_scores = row[4:] - - # Get the index of max class score. - class_id = np.argmax(classes_scores) - - # Continue if the class score is above threshold. - if classes_scores[class_id] > config["score_threshold"]: - confidences.append(confidence) - class_ids.append(class_id) - - cx, cy, w, h = row[0], row[1], row[2], row[3] - - left = int((cx - w / 2) * x_factor) - top = int((cy - h / 2) * y_factor) - width = int(w * x_factor) - height = int(h * y_factor) - - box = np.array([left, top, width, height]) - boxes.append(box) + classes_scores = row[4:] + + # Get the index of max class score and confidence. + _, confidence, _, (_, class_id) = cv2.minMaxLoc(classes_scores) + + # Discard confidence lower than threshold + if confidence >= config["confidence_threshold"]: + confidences.append(confidence) + class_ids.append(class_id) + + cx, cy, w, h = row[0], row[1], row[2], row[3] + #cx, cy, w, h = row[0] - (0.5*row[2]), row[1] - (0.5*row[3]), row[2], row[3] + + left = int((cx - w / 2) * x_factor) + top = int((cy - h / 2) * y_factor) + width = int(w * x_factor) + height = int(h * y_factor) + + # left = (cx - w / 2) + # top = (cy - h / 2) + # width = w + # height = h + + box = np.array([left, top, width, height]) + boxes.append(box) # Perform non maximum suppression to eliminate redundant # overlapping boxes with lower confidences. indices = cv2.dnn.NMSBoxes( boxes, confidences, - 0.001, - #config["confidence_threshold"], + config["confidence_threshold"], config["nms_threshold"], + 0.5 ) output_boxes = [] @@ -112,7 +116,7 @@ } output_boxes.append(output_box) - cv2.rectangle(input_image, (left, top), (left + width, top + height), (0,255,0), 3) + cv2.rectangle(input_image, (round(left), round(top)), (round((left + width)),round( (top + height))), (0,255,0), 3) cv2.imwrite("test.jpg", input_image) #Image.fromarray(cv2.cvtColor(input_image, cv2.COLOR_BGR2RGB)) From d5eb8211ef726ecacf8def7fa963182d897bbf33 Mon Sep 17 00:00:00 2001 From: hdnh2006 Date: Fri, 14 Apr 2023 11:52:05 +0200 Subject: [PATCH 09/13] yolov8 integration --- anylabeling/configs/autolabel_yolov8n.yaml | 2 +- .../services/auto_labeling/model_manager.py | 11 +++- anylabeling/services/auto_labeling/yolov8.py | 58 +++++++++---------- borrador.py | 43 ++++++++------ 4 files changed, 62 insertions(+), 52 deletions(-) diff --git a/anylabeling/configs/autolabel_yolov8n.yaml b/anylabeling/configs/autolabel_yolov8n.yaml index becef1e..1d11655 100644 --- a/anylabeling/configs/autolabel_yolov8n.yaml +++ b/anylabeling/configs/autolabel_yolov8n.yaml @@ -1,6 +1,6 @@ type: yolov8 name: yolov8n -display_name: yolov8n Ultralytics +display_name: YOLOv8n Ultralytics model_path: anylabeling_assets/models/yolov8/yolov8n.onnx input_width: 640 input_height: 640 diff --git a/anylabeling/services/auto_labeling/model_manager.py b/anylabeling/services/auto_labeling/model_manager.py index 5bcf720..0f5edde 100644 --- a/anylabeling/services/auto_labeling/model_manager.py +++ b/anylabeling/services/auto_labeling/model_manager.py @@ -116,14 +116,21 @@ def _load_model(self, model_name): if model_info["type"] == "yolov5": from .yolov5 import YOLOv5 - + model_info["model"] = YOLOv5( model_info, on_message=self.new_model_status.emit ) self.auto_segmentation_model_unselected.emit() + elif model_info["type"] == "yolov8": + from .yolov8 import YOLOv8 + + model_info["model"] = YOLOv8( + model_info, on_message=self.new_model_status.emit + ) + self.auto_segmentation_model_unselected.emit() elif model_info["type"] == "segment_anything": from .segment_anything import SegmentAnything - + model_info["model"] = SegmentAnything( model_info, on_message=self.new_model_status.emit ) diff --git a/anylabeling/services/auto_labeling/yolov8.py b/anylabeling/services/auto_labeling/yolov8.py index eb5afc7..bb26e29 100644 --- a/anylabeling/services/auto_labeling/yolov8.py +++ b/anylabeling/services/auto_labeling/yolov8.py @@ -12,8 +12,8 @@ from .types import AutoLabelingResult -class YOLOv5(Model): - """Object detection model using YOLOv5""" +class YOLOv8(Model): + """Object detection model using YOLOv8""" class Meta: required_config_names = [ @@ -60,9 +60,9 @@ def pre_process(self, input_image, net): # Sets the input to the network. net.setInput(blob) - # Runs the forward pass to get output of the output layers. - output_layers = net.getUnconnectedOutLayersNames() - outputs = net.forward(output_layers) + # Runs the forward with blob. + outputs = net.forward() + outputs = np.array([cv2.transpose(outputs[0])]) return outputs @@ -77,7 +77,7 @@ def post_process(self, input_image, outputs): boxes = [] # Rows. - rows = outputs[0].shape[1] + rows = outputs.shape[1] image_height, image_width = input_image.shape[:2] @@ -85,32 +85,28 @@ def post_process(self, input_image, outputs): x_factor = image_width / self.config["input_width"] y_factor = image_height / self.config["input_height"] - # Iterate through 25200 detections. + # Iterate through 8400 rows. for r in range(rows): - row = outputs[0][0][r] - confidence = row[4] - - # Discard bad detections and continue. - if confidence >= self.config["confidence_threshold"]: - classes_scores = row[5:] - - # Get the index of max class score. - class_id = np.argmax(classes_scores) - - # Continue if the class score is above threshold. - if classes_scores[class_id] > self.config["score_threshold"]: - confidences.append(confidence) - class_ids.append(class_id) - - cx, cy, w, h = row[0], row[1], row[2], row[3] - - left = int((cx - w / 2) * x_factor) - top = int((cy - h / 2) * y_factor) - width = int(w * x_factor) - height = int(h * y_factor) - - box = np.array([left, top, width, height]) - boxes.append(box) + row = outputs[0][r] + classes_scores = row[4:] + + # Get the index of max class score and confidence. + _, confidence, _, (_, class_id) = cv2.minMaxLoc(classes_scores) + + # Discard confidence lower than threshold + if confidence >= self.config["confidence_threshold"]: + confidences.append(confidence) + class_ids.append(class_id) + + cx, cy, w, h = row[0], row[1], row[2], row[3] + + left = int((cx - w / 2) * x_factor) + top = int((cy - h / 2) * y_factor) + width = int(w * x_factor) + height = int(h * y_factor) + + box = np.array([left, top, width, height]) + boxes.append(box) # Perform non maximum suppression to eliminate redundant # overlapping boxes with lower confidences. diff --git a/borrador.py b/borrador.py index e5dd846..7f33b45 100644 --- a/borrador.py +++ b/borrador.py @@ -10,30 +10,44 @@ from PIL import Image import numpy as np from tqdm import tqdm -net = cv2.dnn.readNetFromONNX("/home/henry/anylabeling_data/models/yolov5/yolov8x.onnx") +net = cv2.dnn.readNet("/home/henry/anylabeling_data/models/yolov8/yolov8x.onnx") #net.setPreferableBackend(cv2.dnn.DNN_BACKEND_CUDA) #net.setPreferableTarget(cv2.dnn.DNN_TARGET_CUDA) -config = {'type': 'yolov8', 'name': 'yolov8x', 'display_name': 'YOLOv5n Ultralytics', 'model_path': 'anylabeling_assets/models/yolov5/yolov8x.onnx', 'input_width': 640, 'input_height': 640, 'score_threshold': 0.5, 'nms_threshold': 0.45, 'confidence_threshold': 0.45, 'classes': ['person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 'train', 'truck', 'boat', 'traffic light', 'fire hydrant', 'stop sign', 'parking meter', 'bench', 'bird', 'cat', 'dog', 'horse', 'sheep', 'cow', 'elephant', 'bear', 'zebra', 'giraffe', 'backpack', 'umbrella', 'handbag', 'tie', 'suitcase', 'frisbee', 'skis', 'snowboard', 'sports ball', 'kite', 'baseball bat', 'baseball glove', 'skateboard', 'surfboard', 'tennis racket', 'bottle', 'wine glass', 'cup', 'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple', 'sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza', 'donut', 'cake', 'chair', 'couch', 'potted plant', 'bed', 'dining table', 'toilet', 'tv', 'laptop', 'mouse', 'remote', 'keyboard', 'cell phone', 'microwave', 'oven', 'toaster', 'sink', 'refrigerator', 'book', 'clock', 'vase', 'scissors', 'teddy bear', 'hair drier', 'toothbrush']} +config = {'type': 'yolov8', + 'name': 'yolov8x', + 'display_name':'YOLOv5n Ultralytics', + 'model_path': 'anylabeling_assets/models/yolov5/yolov8x.onnx', + 'input_width': 640, + 'input_height': 640, + 'score_threshold': 0.5, + 'nms_threshold': 0.45, + 'confidence_threshold': 0.45, + 'classes': ['person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 'train', 'truck', 'boat', 'traffic light', 'fire hydrant', 'stop sign', 'parking meter', 'bench', 'bird', 'cat', 'dog', 'horse', 'sheep', 'cow', 'elephant', 'bear', 'zebra', 'giraffe', 'backpack', 'umbrella', 'handbag', 'tie', 'suitcase', 'frisbee', 'skis', 'snowboard', 'sports ball', 'kite', 'baseball bat', 'baseball glove', 'skateboard', 'surfboard', 'tennis racket', 'bottle', 'wine glass', 'cup', 'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple', 'sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza', 'donut', 'cake', 'chair', 'couch', 'potted plant', 'bed', 'dining table', 'toilet', 'tv', 'laptop', 'mouse', 'remote', 'keyboard', 'cell phone', 'microwave', 'oven', 'toaster', 'sink', 'refrigerator', 'book', 'clock', 'vase', 'scissors', 'teddy bear', 'hair drier', 'toothbrush']} classes = config["classes"] input_image = cv2.imread('bus.jpg') -#input_image = cv2.imread('coco_sample/000000000009.jpg') +input_image = cv2.imread('coco_sample/000000000009.jpg') [height, width, _] = input_image.shape -length = max((height, width)) -image = np.zeros((length, length, 3), np.uint8) -image[0:height, 0:width] = input_image -scale = length / 640 -blob = cv2.dnn.blobFromImage(input_image, scalefactor=1 / 255, size=(640, 640), swapRB=True) + +# Create a 4D blob from a frame. +blob = cv2.dnn.blobFromImage( + input_image, + 1 / 255, + (config["input_width"], config["input_height"]), + [0, 0, 0], + 1, + crop=False, +) net.setInput(blob) outputs = net.forward() - +print(outputs) outputs = np.array([cv2.transpose(outputs[0])]) @@ -71,18 +85,12 @@ class_ids.append(class_id) cx, cy, w, h = row[0], row[1], row[2], row[3] - #cx, cy, w, h = row[0] - (0.5*row[2]), row[1] - (0.5*row[3]), row[2], row[3] left = int((cx - w / 2) * x_factor) top = int((cy - h / 2) * y_factor) width = int(w * x_factor) height = int(h * y_factor) - # left = (cx - w / 2) - # top = (cy - h / 2) - # width = w - # height = h - box = np.array([left, top, width, height]) boxes.append(box) @@ -92,8 +100,7 @@ boxes, confidences, config["confidence_threshold"], - config["nms_threshold"], - 0.5 + config["nms_threshold"] ) output_boxes = [] @@ -116,7 +123,7 @@ } output_boxes.append(output_box) - cv2.rectangle(input_image, (round(left), round(top)), (round((left + width)),round( (top + height))), (0,255,0), 3) + cv2.rectangle(input_image, (left, top), ((left + width), (top + height)), (0,255,0), 3) cv2.imwrite("test.jpg", input_image) #Image.fromarray(cv2.cvtColor(input_image, cv2.COLOR_BGR2RGB)) From f4c660c571a9c1771869202b00910535a9904c76 Mon Sep 17 00:00:00 2001 From: hdnh2006 Date: Fri, 14 Apr 2023 11:52:58 +0200 Subject: [PATCH 10/13] YOLOv8 supported V1 --- borrador.py | 129 ---------------------------------------------------- 1 file changed, 129 deletions(-) delete mode 100644 borrador.py diff --git a/borrador.py b/borrador.py deleted file mode 100644 index 7f33b45..0000000 --- a/borrador.py +++ /dev/null @@ -1,129 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -""" -Created on Thu Apr 13 10:16:59 2023 - -@author: henry -""" - -import cv2 -from PIL import Image -import numpy as np -from tqdm import tqdm -net = cv2.dnn.readNet("/home/henry/anylabeling_data/models/yolov8/yolov8x.onnx") -#net.setPreferableBackend(cv2.dnn.DNN_BACKEND_CUDA) -#net.setPreferableTarget(cv2.dnn.DNN_TARGET_CUDA) - - - - -config = {'type': 'yolov8', - 'name': 'yolov8x', - 'display_name':'YOLOv5n Ultralytics', - 'model_path': 'anylabeling_assets/models/yolov5/yolov8x.onnx', - 'input_width': 640, - 'input_height': 640, - 'score_threshold': 0.5, - 'nms_threshold': 0.45, - 'confidence_threshold': 0.45, - 'classes': ['person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 'train', 'truck', 'boat', 'traffic light', 'fire hydrant', 'stop sign', 'parking meter', 'bench', 'bird', 'cat', 'dog', 'horse', 'sheep', 'cow', 'elephant', 'bear', 'zebra', 'giraffe', 'backpack', 'umbrella', 'handbag', 'tie', 'suitcase', 'frisbee', 'skis', 'snowboard', 'sports ball', 'kite', 'baseball bat', 'baseball glove', 'skateboard', 'surfboard', 'tennis racket', 'bottle', 'wine glass', 'cup', 'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple', 'sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza', 'donut', 'cake', 'chair', 'couch', 'potted plant', 'bed', 'dining table', 'toilet', 'tv', 'laptop', 'mouse', 'remote', 'keyboard', 'cell phone', 'microwave', 'oven', 'toaster', 'sink', 'refrigerator', 'book', 'clock', 'vase', 'scissors', 'teddy bear', 'hair drier', 'toothbrush']} -classes = config["classes"] - - - -input_image = cv2.imread('bus.jpg') -input_image = cv2.imread('coco_sample/000000000009.jpg') -[height, width, _] = input_image.shape - - -# Create a 4D blob from a frame. -blob = cv2.dnn.blobFromImage( - input_image, - 1 / 255, - (config["input_width"], config["input_height"]), - [0, 0, 0], - 1, - crop=False, -) -net.setInput(blob) -outputs = net.forward() -print(outputs) -outputs = np.array([cv2.transpose(outputs[0])]) - - - - -# ========================================= post - - - -# Lists to hold respective values while unwrapping. -class_ids = [] -confidences = [] -boxes = [] - -# Rows. -rows = outputs.shape[1] - -image_height, image_width = input_image.shape[:2] - -# Resizing factor. -x_factor = image_width / config["input_width"] -y_factor = image_height / config["input_height"] - -# Iterate through 25200 detections. -for r in tqdm(range(rows)): - row = outputs[0][r] - classes_scores = row[4:] - - # Get the index of max class score and confidence. - _, confidence, _, (_, class_id) = cv2.minMaxLoc(classes_scores) - - # Discard confidence lower than threshold - if confidence >= config["confidence_threshold"]: - confidences.append(confidence) - class_ids.append(class_id) - - cx, cy, w, h = row[0], row[1], row[2], row[3] - - left = int((cx - w / 2) * x_factor) - top = int((cy - h / 2) * y_factor) - width = int(w * x_factor) - height = int(h * y_factor) - - box = np.array([left, top, width, height]) - boxes.append(box) - -# Perform non maximum suppression to eliminate redundant -# overlapping boxes with lower confidences. -indices = cv2.dnn.NMSBoxes( - boxes, - confidences, - config["confidence_threshold"], - config["nms_threshold"] -) - -output_boxes = [] -for i in indices: - box = boxes[i] - left = box[0] - top = box[1] - width = box[2] - height = box[3] - label = classes[class_ids[i]] - score = confidences[i] - - output_box = { - "x1": left, - "y1": top, - "x2": left + width, - "y2": top + height, - "label": label, - "score": score, - } - - output_boxes.append(output_box) - cv2.rectangle(input_image, (left, top), ((left + width), (top + height)), (0,255,0), 3) - -cv2.imwrite("test.jpg", input_image) -#Image.fromarray(cv2.cvtColor(input_image, cv2.COLOR_BGR2RGB)) From b26cb830bfdac20cc3495b747da5c78ffb7426d6 Mon Sep 17 00:00:00 2001 From: hdnh2006 Date: Fri, 14 Apr 2023 12:00:53 +0200 Subject: [PATCH 11/13] requirements updated for last version of opencv --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 2dd62eb..c9929da 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -opencv-contrib-python-headless==4.6.0.66 +opencv-contrib-python-headless==4.7.0.68 PyQt5==5.15.7 imgviz==1.5.0 natsort==8.1.0 From 9040b3e411798792e8d01a2fad5cffd1e51a8321 Mon Sep 17 00:00:00 2001 From: hdnh2006 Date: Fri, 14 Apr 2023 19:35:28 +0200 Subject: [PATCH 12/13] spaces deleted, onnxruntime-gpu added --- anylabeling/services/auto_labeling/model_manager.py | 4 +--- pyproject.toml | 5 +++++ requirements-macos.txt | 3 ++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/anylabeling/services/auto_labeling/model_manager.py b/anylabeling/services/auto_labeling/model_manager.py index 0f5edde..04c9df0 100644 --- a/anylabeling/services/auto_labeling/model_manager.py +++ b/anylabeling/services/auto_labeling/model_manager.py @@ -33,7 +33,6 @@ class ModelManager(QObject): "yolov8x": "autolabel_yolov8x.yaml", } - def __init__(self): super().__init__() self.model_infos = {} @@ -113,7 +112,6 @@ def _load_model(self, model_name): self.auto_segmentation_model_unselected.emit() model_info = copy.deepcopy(self.model_infos[model_name]) - if model_info["type"] == "yolov5": from .yolov5 import YOLOv5 @@ -166,4 +164,4 @@ def predict_shapes(self, image): auto_labeling_result = self.loaded_model_info["model"].predict_shapes( image ) - self.new_auto_labeling_result.emit(auto_labeling_result) + self.new_auto_labeling_result.emit(auto_labeling_result) \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index c5ba840..8d14fe4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,3 +14,8 @@ exclude = ''' | dist )/ ''' + +[build-system] +requires = ["setuptools", "wheel", "onnxruntime-gpu"] +build-backend = "setuptools.build_meta" + diff --git a/requirements-macos.txt b/requirements-macos.txt index 49b3df3..4df6ca9 100644 --- a/requirements-macos.txt +++ b/requirements-macos.txt @@ -1,4 +1,4 @@ -opencv-contrib-python-headless==4.5.5.62 +opencv-contrib-python-headless==4.7.0.68 # PyQt5==5.15.6 # Use Miniconda/Anaconda: conda install -c conda-forge pyqt imgviz==1.5.0 natsort==8.1.0 @@ -8,4 +8,5 @@ PyYAML==6.0 colorama==0.4.5 onnx==1.13.1 onnxruntime==1.14.1 +onnxruntime-gpu==1.14.1 qimage2ndarray==1.10.0 From 291ac025f950425512c99d0240367297370ba17d Mon Sep 17 00:00:00 2001 From: hdnh2006 Date: Fri, 14 Apr 2023 20:25:37 +0200 Subject: [PATCH 13/13] modify the way the models are downloaded --- anylabeling/services/auto_labeling/model.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/anylabeling/services/auto_labeling/model.py b/anylabeling/services/auto_labeling/model.py index 58fd44b..2b015ab 100644 --- a/anylabeling/services/auto_labeling/model.py +++ b/anylabeling/services/auto_labeling/model.py @@ -57,7 +57,14 @@ def get_model_abs_path(self, model_path): " while..." ) relative_path = model_path.replace("anylabeling_assets/", "") - download_url = self.BASE_DOWNLOAD_URL + relative_path.replace("models/yolov5/","").replace("models/segment_anything/","") + + if relative_path.startswith("models/segment_anything/"): + download_url = self.BASE_DOWNLOAD_URL + relative_path.replace("models/segment_anything/","") + elif relative_path.startswith("models/yolov5/"): + download_url = self.BASE_DOWNLOAD_URL + relative_path.replace("models/yolov5/","") + else: + download_url = self.BASE_DOWNLOAD_URL + relative_path.replace("models/yolov8/","") + home_dir = os.path.expanduser("~") model_abs_path = os.path.abspath( os.path.join(home_dir, "anylabeling_data", relative_path)