From 2653f5a090dc7d4eb814fb108dd0265044a8e0c7 Mon Sep 17 00:00:00 2001 From: Bhavay Malhotra Date: Fri, 24 May 2024 20:23:17 +0530 Subject: [PATCH 01/16] Adding support for Yolo-OBB format --- supervision/dataset/core.py | 4 ++++ supervision/dataset/formats/yolo.py | 5 +++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/supervision/dataset/core.py b/supervision/dataset/core.py index 551e96da..ab53dcd0 100644 --- a/supervision/dataset/core.py +++ b/supervision/dataset/core.py @@ -267,6 +267,7 @@ class DetectionDataset(BaseDataset): annotations_directory_path: str, data_yaml_path: str, force_masks: bool = False, + is_obb: bool = False, ) -> DetectionDataset: """ Creates a Dataset instance from YOLO formatted data. @@ -281,6 +282,8 @@ class DetectionDataset(BaseDataset): force_masks (bool, optional): If True, forces masks to be loaded for all annotations, regardless of whether they are present. + is_obb (bool, optional): If True, returns the + annotations in YOLO-OBB format. Returns: DetectionDataset: A DetectionDataset instance @@ -313,6 +316,7 @@ class DetectionDataset(BaseDataset): annotations_directory_path=annotations_directory_path, data_yaml_path=data_yaml_path, force_masks=force_masks, + is_obb=is_obb, ) return DetectionDataset(classes=classes, images=images, annotations=annotations) diff --git a/supervision/dataset/formats/yolo.py b/supervision/dataset/formats/yolo.py index c8136205..4c2893e4 100644 --- a/supervision/dataset/formats/yolo.py +++ b/supervision/dataset/formats/yolo.py @@ -86,7 +86,7 @@ def yolo_annotations_to_detections( if with_masks: relative_polygon.append(_box_to_polygon(box=box)) elif len(values) > 5: - polygon = _parse_polygon(values=values[1:]) + polygon = _parse_polygon(values=values[1:]) relative_xyxy.append(polygon_to_xyxy(polygon=polygon)) if with_masks: relative_polygon.append(polygon) @@ -110,6 +110,7 @@ def load_yolo_annotations( annotations_directory_path: str, data_yaml_path: str, force_masks: bool = False, + is_obb: bool = False, ) -> Tuple[List[str], Dict[str, np.ndarray], Dict[str, Detections]]: """ Loads YOLO annotations and returns class names, images, @@ -123,6 +124,7 @@ def load_yolo_annotations( YAML file containing class information. force_masks (bool, optional): If True, forces masks to be loaded for all annotations, regardless of whether they are present. + is_obb (bool, optional): If True, returns the annotations in YOLO-OBB format. Returns: Tuple[List[str], Dict[str, np.ndarray], Dict[str, Detections]]: @@ -158,7 +160,6 @@ def load_yolo_annotations( annotation = yolo_annotations_to_detections( lines=lines, resolution_wh=resolution_wh, with_masks=with_masks ) - images[image_path] = image annotations[image_path] = annotation return classes, images, annotations From 51c7ebdf60df844448cee07a078b9013380b69bc Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 24 May 2024 14:56:00 +0000 Subject: [PATCH 02/16] =?UTF-8?q?fix(pre=5Fcommit):=20=F0=9F=8E=A8=20auto?= =?UTF-8?q?=20format=20pre-commit=20hooks?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- supervision/dataset/core.py | 2 +- supervision/dataset/formats/yolo.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/supervision/dataset/core.py b/supervision/dataset/core.py index ab53dcd0..6ffd9086 100644 --- a/supervision/dataset/core.py +++ b/supervision/dataset/core.py @@ -282,7 +282,7 @@ class DetectionDataset(BaseDataset): force_masks (bool, optional): If True, forces masks to be loaded for all annotations, regardless of whether they are present. - is_obb (bool, optional): If True, returns the + is_obb (bool, optional): If True, returns the annotations in YOLO-OBB format. Returns: diff --git a/supervision/dataset/formats/yolo.py b/supervision/dataset/formats/yolo.py index 4c2893e4..087a7696 100644 --- a/supervision/dataset/formats/yolo.py +++ b/supervision/dataset/formats/yolo.py @@ -86,7 +86,7 @@ def yolo_annotations_to_detections( if with_masks: relative_polygon.append(_box_to_polygon(box=box)) elif len(values) > 5: - polygon = _parse_polygon(values=values[1:]) + polygon = _parse_polygon(values=values[1:]) relative_xyxy.append(polygon_to_xyxy(polygon=polygon)) if with_masks: relative_polygon.append(polygon) From 7e4fc8a4856505d7e81223429611c5b1fe9119f3 Mon Sep 17 00:00:00 2001 From: Bhavay Malhotra Date: Wed, 5 Jun 2024 17:43:58 +0530 Subject: [PATCH 03/16] Made few changes to add OBB support --- supervision/dataset/formats/yolo.py | 31 +++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/supervision/dataset/formats/yolo.py b/supervision/dataset/formats/yolo.py index 4c2893e4..5c95e86b 100644 --- a/supervision/dataset/formats/yolo.py +++ b/supervision/dataset/formats/yolo.py @@ -8,6 +8,7 @@ import numpy as np from supervision.dataset.utils import approximate_mask_with_polygons from supervision.detection.core import Detections from supervision.detection.utils import polygon_to_mask, polygon_to_xyxy +from supervision.config import ORIENTED_BOX_COORDINATES from supervision.utils.file import ( list_files_with_extensions, read_txt_file, @@ -70,12 +71,12 @@ def _image_name_to_annotation_name(image_name: str) -> str: def yolo_annotations_to_detections( - lines: List[str], resolution_wh: Tuple[int, int], with_masks: bool + lines: List[str], resolution_wh: Tuple[int, int], with_masks: bool, is_obb: bool ) -> Detections: if len(lines) == 0: return Detections.empty() - class_id, relative_xyxy, relative_polygon = [], [], [] + class_id, relative_xyxy, relative_polygon, relative_xyxyxyxy = [], [], [], [] w, h = resolution_wh for line in lines: values = line.split() @@ -86,23 +87,37 @@ def yolo_annotations_to_detections( if with_masks: relative_polygon.append(_box_to_polygon(box=box)) elif len(values) > 5: - polygon = _parse_polygon(values=values[1:]) - relative_xyxy.append(polygon_to_xyxy(polygon=polygon)) - if with_masks: - relative_polygon.append(polygon) + if is_obb: + polygon = _parse_polygon(values=values[1:]) + relative_xyxyxyxy.append(np.array(values[1:])) + if with_masks: + relative_polygon.append(polygon) + else: + polygon = _parse_polygon(values=values[1:]) + relative_xyxy.append(polygon_to_xyxy(polygon=polygon)) + if with_masks: + relative_polygon.append(polygon) class_id = np.array(class_id, dtype=int) relative_xyxy = np.array(relative_xyxy, dtype=np.float32) + relative_xyxyxyxy = np.array(relative_xyxyxyxy, dtype=np.float32) xyxy = relative_xyxy * np.array([w, h, w, h], dtype=np.float32) + xyxyxyxy = relative_xyxyxyxy * np.array([w, h, w, h], dtype=np.float32) + data = { + ORIENTED_BOX_COORDINATES: xyxyxyxy + } + if not with_masks: + if is_obb: + return Detections(class_id=class_id, data=data) return Detections(class_id=class_id, xyxy=xyxy) polygons = [ (polygon * np.array(resolution_wh)).astype(int) for polygon in relative_polygon ] mask = _polygons_to_masks(polygons=polygons, resolution_wh=resolution_wh) - return Detections(class_id=class_id, xyxy=xyxy, mask=mask) + return Detections(class_id=class_id, data=data, mask=mask) if is_obb else Detections(class_id=class_id, xyxy=xyxy, mask=mask) def load_yolo_annotations( @@ -158,7 +173,7 @@ def load_yolo_annotations( with_masks = _with_mask(lines=lines) with_masks = force_masks if force_masks else with_masks annotation = yolo_annotations_to_detections( - lines=lines, resolution_wh=resolution_wh, with_masks=with_masks + lines=lines, resolution_wh=resolution_wh, with_masks=with_masks, is_obb=is_obb ) images[image_path] = image annotations[image_path] = annotation From 46bd2670799b40651432268e580edf6935dd2a06 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 5 Jun 2024 12:17:09 +0000 Subject: [PATCH 04/16] =?UTF-8?q?fix(pre=5Fcommit):=20=F0=9F=8E=A8=20auto?= =?UTF-8?q?=20format=20pre-commit=20hooks?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- supervision/dataset/formats/yolo.py | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/supervision/dataset/formats/yolo.py b/supervision/dataset/formats/yolo.py index 5c95e86b..919e8fb4 100644 --- a/supervision/dataset/formats/yolo.py +++ b/supervision/dataset/formats/yolo.py @@ -5,10 +5,10 @@ from typing import Dict, List, Optional, Tuple import cv2 import numpy as np +from supervision.config import ORIENTED_BOX_COORDINATES from supervision.dataset.utils import approximate_mask_with_polygons from supervision.detection.core import Detections from supervision.detection.utils import polygon_to_mask, polygon_to_xyxy -from supervision.config import ORIENTED_BOX_COORDINATES from supervision.utils.file import ( list_files_with_extensions, read_txt_file, @@ -93,7 +93,7 @@ def yolo_annotations_to_detections( if with_masks: relative_polygon.append(polygon) else: - polygon = _parse_polygon(values=values[1:]) + polygon = _parse_polygon(values=values[1:]) relative_xyxy.append(polygon_to_xyxy(polygon=polygon)) if with_masks: relative_polygon.append(polygon) @@ -104,10 +104,8 @@ def yolo_annotations_to_detections( xyxy = relative_xyxy * np.array([w, h, w, h], dtype=np.float32) xyxyxyxy = relative_xyxyxyxy * np.array([w, h, w, h], dtype=np.float32) - data = { - ORIENTED_BOX_COORDINATES: xyxyxyxy - } - + data = {ORIENTED_BOX_COORDINATES: xyxyxyxy} + if not with_masks: if is_obb: return Detections(class_id=class_id, data=data) @@ -117,7 +115,11 @@ def yolo_annotations_to_detections( (polygon * np.array(resolution_wh)).astype(int) for polygon in relative_polygon ] mask = _polygons_to_masks(polygons=polygons, resolution_wh=resolution_wh) - return Detections(class_id=class_id, data=data, mask=mask) if is_obb else Detections(class_id=class_id, xyxy=xyxy, mask=mask) + return ( + Detections(class_id=class_id, data=data, mask=mask) + if is_obb + else Detections(class_id=class_id, xyxy=xyxy, mask=mask) + ) def load_yolo_annotations( @@ -173,7 +175,10 @@ def load_yolo_annotations( with_masks = _with_mask(lines=lines) with_masks = force_masks if force_masks else with_masks annotation = yolo_annotations_to_detections( - lines=lines, resolution_wh=resolution_wh, with_masks=with_masks, is_obb=is_obb + lines=lines, + resolution_wh=resolution_wh, + with_masks=with_masks, + is_obb=is_obb, ) images[image_path] = image annotations[image_path] = annotation From 523d218dd4bcb458b92d824b9606de50e46dc6a6 Mon Sep 17 00:00:00 2001 From: Bhavay Malhotra Date: Wed, 5 Jun 2024 22:59:04 +0530 Subject: [PATCH 05/16] Made few changes to add OBB support --- supervision/dataset/formats/yolo.py | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/supervision/dataset/formats/yolo.py b/supervision/dataset/formats/yolo.py index 5c95e86b..1fdd3218 100644 --- a/supervision/dataset/formats/yolo.py +++ b/supervision/dataset/formats/yolo.py @@ -87,22 +87,19 @@ def yolo_annotations_to_detections( if with_masks: relative_polygon.append(_box_to_polygon(box=box)) elif len(values) > 5: + polygon = _parse_polygon(values=values[1:]) if is_obb: - polygon = _parse_polygon(values=values[1:]) relative_xyxyxyxy.append(np.array(values[1:])) - if with_masks: - relative_polygon.append(polygon) else: - polygon = _parse_polygon(values=values[1:]) relative_xyxy.append(polygon_to_xyxy(polygon=polygon)) - if with_masks: + if with_masks: relative_polygon.append(polygon) - + class_id = np.array(class_id, dtype=int) relative_xyxy = np.array(relative_xyxy, dtype=np.float32) relative_xyxyxyxy = np.array(relative_xyxyxyxy, dtype=np.float32) xyxy = relative_xyxy * np.array([w, h, w, h], dtype=np.float32) - xyxyxyxy = relative_xyxyxyxy * np.array([w, h, w, h], dtype=np.float32) + xyxyxyxy = relative_xyxyxyxy * np.array([w, h, w, h, w, h, w, h], dtype=np.float32) data = { ORIENTED_BOX_COORDINATES: xyxyxyxy @@ -110,14 +107,14 @@ def yolo_annotations_to_detections( if not with_masks: if is_obb: - return Detections(class_id=class_id, data=data) + return Detections(class_id=class_id, xyxy=xyxy, data=data) return Detections(class_id=class_id, xyxy=xyxy) polygons = [ (polygon * np.array(resolution_wh)).astype(int) for polygon in relative_polygon ] mask = _polygons_to_masks(polygons=polygons, resolution_wh=resolution_wh) - return Detections(class_id=class_id, data=data, mask=mask) if is_obb else Detections(class_id=class_id, xyxy=xyxy, mask=mask) + return Detections(class_id=class_id, xyxy=xyxy, data=data, mask=mask) if is_obb else Detections(class_id=class_id, xyxy=xyxy, mask=mask) def load_yolo_annotations( From fc2710c9c9ef465b6489fcc617f295f102a2d875 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 5 Jun 2024 17:31:08 +0000 Subject: [PATCH 06/16] =?UTF-8?q?fix(pre=5Fcommit):=20=F0=9F=8E=A8=20auto?= =?UTF-8?q?=20format=20pre-commit=20hooks?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- supervision/dataset/formats/yolo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/supervision/dataset/formats/yolo.py b/supervision/dataset/formats/yolo.py index fad8c8ae..39fb557b 100644 --- a/supervision/dataset/formats/yolo.py +++ b/supervision/dataset/formats/yolo.py @@ -98,7 +98,7 @@ def yolo_annotations_to_detections( relative_xyxy.append(polygon_to_xyxy(polygon=polygon)) if with_masks: relative_polygon.append(polygon) - + class_id = np.array(class_id, dtype=int) relative_xyxy = np.array(relative_xyxy, dtype=np.float32) relative_xyxyxyxy = np.array(relative_xyxyxyxy, dtype=np.float32) From a82c37c7fa16c554423c669d2db51276774f9151 Mon Sep 17 00:00:00 2001 From: Bhavay Malhotra Date: Wed, 5 Jun 2024 23:03:24 +0530 Subject: [PATCH 07/16] Updated yolo.py for OBB support --- supervision/dataset/formats/yolo.py | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/supervision/dataset/formats/yolo.py b/supervision/dataset/formats/yolo.py index fad8c8ae..88b565d5 100644 --- a/supervision/dataset/formats/yolo.py +++ b/supervision/dataset/formats/yolo.py @@ -91,10 +91,6 @@ def yolo_annotations_to_detections( if is_obb: relative_xyxyxyxy.append(np.array(values[1:])) else: -<<<<<<< HEAD -======= - polygon = _parse_polygon(values=values[1:]) ->>>>>>> 46bd2670799b40651432268e580edf6935dd2a06 relative_xyxy.append(polygon_to_xyxy(polygon=polygon)) if with_masks: relative_polygon.append(polygon) @@ -116,15 +112,7 @@ def yolo_annotations_to_detections( (polygon * np.array(resolution_wh)).astype(int) for polygon in relative_polygon ] mask = _polygons_to_masks(polygons=polygons, resolution_wh=resolution_wh) -<<<<<<< HEAD return Detections(class_id=class_id, xyxy=xyxy, data=data, mask=mask) if is_obb else Detections(class_id=class_id, xyxy=xyxy, mask=mask) -======= - return ( - Detections(class_id=class_id, data=data, mask=mask) - if is_obb - else Detections(class_id=class_id, xyxy=xyxy, mask=mask) - ) ->>>>>>> 46bd2670799b40651432268e580edf6935dd2a06 def load_yolo_annotations( From 859f0258bc64728c11dac91eb70ede40ac300e6b Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 5 Jun 2024 17:34:05 +0000 Subject: [PATCH 08/16] =?UTF-8?q?fix(pre=5Fcommit):=20=F0=9F=8E=A8=20auto?= =?UTF-8?q?=20format=20pre-commit=20hooks?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- supervision/dataset/formats/yolo.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/supervision/dataset/formats/yolo.py b/supervision/dataset/formats/yolo.py index 35449fde..c135a393 100644 --- a/supervision/dataset/formats/yolo.py +++ b/supervision/dataset/formats/yolo.py @@ -93,7 +93,7 @@ def yolo_annotations_to_detections( else: relative_xyxy.append(polygon_to_xyxy(polygon=polygon)) if with_masks: - relative_polygon.append(polygon) + relative_polygon.append(polygon) class_id = np.array(class_id, dtype=int) relative_xyxy = np.array(relative_xyxy, dtype=np.float32) @@ -112,7 +112,11 @@ def yolo_annotations_to_detections( (polygon * np.array(resolution_wh)).astype(int) for polygon in relative_polygon ] mask = _polygons_to_masks(polygons=polygons, resolution_wh=resolution_wh) - return Detections(class_id=class_id, xyxy=xyxy, data=data, mask=mask) if is_obb else Detections(class_id=class_id, xyxy=xyxy, mask=mask) + return ( + Detections(class_id=class_id, xyxy=xyxy, data=data, mask=mask) + if is_obb + else Detections(class_id=class_id, xyxy=xyxy, mask=mask) + ) def load_yolo_annotations( From 6ca09ccbfc4a796d26967c860c3e0cbc6b8ad705 Mon Sep 17 00:00:00 2001 From: Bhavay Malhotra Date: Thu, 6 Jun 2024 22:14:02 +0530 Subject: [PATCH 09/16] Added default value for is_obb parameter --- supervision/dataset/formats/yolo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/supervision/dataset/formats/yolo.py b/supervision/dataset/formats/yolo.py index 35449fde..2abb8cbd 100644 --- a/supervision/dataset/formats/yolo.py +++ b/supervision/dataset/formats/yolo.py @@ -71,7 +71,7 @@ def _image_name_to_annotation_name(image_name: str) -> str: def yolo_annotations_to_detections( - lines: List[str], resolution_wh: Tuple[int, int], with_masks: bool, is_obb: bool + lines: List[str], resolution_wh: Tuple[int, int], with_masks: bool, is_obb: bool = False ) -> Detections: if len(lines) == 0: return Detections.empty() From 420543534decbcd3ea65b43967bc7b8382c9cfc4 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 6 Jun 2024 16:45:29 +0000 Subject: [PATCH 10/16] =?UTF-8?q?fix(pre=5Fcommit):=20=F0=9F=8E=A8=20auto?= =?UTF-8?q?=20format=20pre-commit=20hooks?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- supervision/dataset/formats/yolo.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/supervision/dataset/formats/yolo.py b/supervision/dataset/formats/yolo.py index 40fc826b..3a84cbeb 100644 --- a/supervision/dataset/formats/yolo.py +++ b/supervision/dataset/formats/yolo.py @@ -71,7 +71,10 @@ def _image_name_to_annotation_name(image_name: str) -> str: def yolo_annotations_to_detections( - lines: List[str], resolution_wh: Tuple[int, int], with_masks: bool, is_obb: bool = False + lines: List[str], + resolution_wh: Tuple[int, int], + with_masks: bool, + is_obb: bool = False, ) -> Detections: if len(lines) == 0: return Detections.empty() From 47f1c44e20550eae7c2949f167fa55a287ffee7f Mon Sep 17 00:00:00 2001 From: Bhavay Malhotra Date: Thu, 6 Jun 2024 22:20:41 +0530 Subject: [PATCH 11/16] Updated criteria for xyxyxyxy --- supervision/dataset/formats/yolo.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/supervision/dataset/formats/yolo.py b/supervision/dataset/formats/yolo.py index 40fc826b..d3ac870b 100644 --- a/supervision/dataset/formats/yolo.py +++ b/supervision/dataset/formats/yolo.py @@ -97,11 +97,12 @@ def yolo_annotations_to_detections( class_id = np.array(class_id, dtype=int) relative_xyxy = np.array(relative_xyxy, dtype=np.float32) - relative_xyxyxyxy = np.array(relative_xyxyxyxy, dtype=np.float32) xyxy = relative_xyxy * np.array([w, h, w, h], dtype=np.float32) - xyxyxyxy = relative_xyxyxyxy * np.array([w, h, w, h, w, h, w, h], dtype=np.float32) - - data = {ORIENTED_BOX_COORDINATES: xyxyxyxy} + + if is_obb: + relative_xyxyxyxy = np.array(relative_xyxyxyxy, dtype=np.float32) + xyxyxyxy = relative_xyxyxyxy * np.array([w, h, w, h, w, h, w, h], dtype=np.float32) + data = {ORIENTED_BOX_COORDINATES: xyxyxyxy} if not with_masks: if is_obb: From cce69d893ed18e605bcac107ac82a7fccd23699f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 6 Jun 2024 16:57:03 +0000 Subject: [PATCH 12/16] =?UTF-8?q?fix(pre=5Fcommit):=20=F0=9F=8E=A8=20auto?= =?UTF-8?q?=20format=20pre-commit=20hooks?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- supervision/dataset/formats/yolo.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/supervision/dataset/formats/yolo.py b/supervision/dataset/formats/yolo.py index f1005a56..9b10f6bf 100644 --- a/supervision/dataset/formats/yolo.py +++ b/supervision/dataset/formats/yolo.py @@ -101,10 +101,12 @@ def yolo_annotations_to_detections( class_id = np.array(class_id, dtype=int) relative_xyxy = np.array(relative_xyxy, dtype=np.float32) xyxy = relative_xyxy * np.array([w, h, w, h], dtype=np.float32) - + if is_obb: relative_xyxyxyxy = np.array(relative_xyxyxyxy, dtype=np.float32) - xyxyxyxy = relative_xyxyxyxy * np.array([w, h, w, h, w, h, w, h], dtype=np.float32) + xyxyxyxy = relative_xyxyxyxy * np.array( + [w, h, w, h, w, h, w, h], dtype=np.float32 + ) data = {ORIENTED_BOX_COORDINATES: xyxyxyxy} if not with_masks: From 6f7f728044e51ba4176d3600cfb97f1265758911 Mon Sep 17 00:00:00 2001 From: Bhavay Malhotra Date: Thu, 13 Jun 2024 20:22:26 +0530 Subject: [PATCH 13/16] Changed the position of a line --- supervision/dataset/formats/yolo.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/supervision/dataset/formats/yolo.py b/supervision/dataset/formats/yolo.py index f1005a56..9ad2ca63 100644 --- a/supervision/dataset/formats/yolo.py +++ b/supervision/dataset/formats/yolo.py @@ -91,10 +91,9 @@ def yolo_annotations_to_detections( relative_polygon.append(_box_to_polygon(box=box)) elif len(values) > 5: polygon = _parse_polygon(values=values[1:]) + relative_xyxy.append(polygon_to_xyxy(polygon=polygon)) if is_obb: relative_xyxyxyxy.append(np.array(values[1:])) - else: - relative_xyxy.append(polygon_to_xyxy(polygon=polygon)) if with_masks: relative_polygon.append(polygon) From dcfb122816bc204cc0f737261fbb67bb433a82bb Mon Sep 17 00:00:00 2001 From: LinasKo Date: Wed, 19 Jun 2024 00:33:00 +0300 Subject: [PATCH 14/16] Fix xyxyxyxy shape * Ultralytics return (-1, 4, 2), and that's waht our annotators expect --- supervision/dataset/formats/yolo.py | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/supervision/dataset/formats/yolo.py b/supervision/dataset/formats/yolo.py index 00f823ef..64ab84c9 100644 --- a/supervision/dataset/formats/yolo.py +++ b/supervision/dataset/formats/yolo.py @@ -100,28 +100,22 @@ def yolo_annotations_to_detections( class_id = np.array(class_id, dtype=int) relative_xyxy = np.array(relative_xyxy, dtype=np.float32) xyxy = relative_xyxy * np.array([w, h, w, h], dtype=np.float32) + data = {} if is_obb: relative_xyxyxyxy = np.array(relative_xyxyxyxy, dtype=np.float32) - xyxyxyxy = relative_xyxyxyxy * np.array( - [w, h, w, h, w, h, w, h], dtype=np.float32 - ) - data = {ORIENTED_BOX_COORDINATES: xyxyxyxy} + xyxyxyxy = relative_xyxyxyxy.reshape(-1, 4, 2) + xyxyxyxy *= np.array([w, h], dtype=np.float32) + data[ORIENTED_BOX_COORDINATES] = xyxyxyxy if not with_masks: - if is_obb: - return Detections(class_id=class_id, xyxy=xyxy, data=data) - return Detections(class_id=class_id, xyxy=xyxy) + return Detections(class_id=class_id, xyxy=xyxy, data=data) polygons = [ (polygon * np.array(resolution_wh)).astype(int) for polygon in relative_polygon ] mask = _polygons_to_masks(polygons=polygons, resolution_wh=resolution_wh) - return ( - Detections(class_id=class_id, xyxy=xyxy, data=data, mask=mask) - if is_obb - else Detections(class_id=class_id, xyxy=xyxy, mask=mask) - ) + return Detections(class_id=class_id, xyxy=xyxy, data=data, mask=mask) def load_yolo_annotations( From 257e73fb372a760551a744de11626a7e3ed2d048 Mon Sep 17 00:00:00 2001 From: LinasKo Date: Wed, 19 Jun 2024 00:36:27 +0300 Subject: [PATCH 15/16] Change uncommon np.int0 type to its alias np.intp --- supervision/annotators/core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/supervision/annotators/core.py b/supervision/annotators/core.py index 1c0ad8af..b13f0533 100644 --- a/supervision/annotators/core.py +++ b/supervision/annotators/core.py @@ -172,7 +172,7 @@ class OrientedBoxAnnotator(BaseAnnotator): return scene for detection_idx in range(len(detections)): - bbox = np.int0(detections.data.get(ORIENTED_BOX_COORDINATES)[detection_idx]) + bbox = np.intp(detections.data.get(ORIENTED_BOX_COORDINATES)[detection_idx]) color = resolve_color( color=self.color, detections=detections, From a81f24e08dc4da9df78e1e0aa2dd9d6cdbc20559 Mon Sep 17 00:00:00 2001 From: LinasKo Date: Wed, 19 Jun 2024 01:06:39 +0300 Subject: [PATCH 16/16] Explain OBB format in docstring --- supervision/dataset/core.py | 5 +++-- supervision/dataset/formats/yolo.py | 4 +++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/supervision/dataset/core.py b/supervision/dataset/core.py index f2ad965c..e6d69f76 100644 --- a/supervision/dataset/core.py +++ b/supervision/dataset/core.py @@ -281,8 +281,9 @@ class DetectionDataset(BaseDataset): force_masks (bool, optional): If True, forces masks to be loaded for all annotations, regardless of whether they are present. - is_obb (bool, optional): If True, returns the - annotations in YOLO-OBB format. + is_obb (bool, optional): If True, loads the annotations in OBB format. + OBB annotations are defined as `[class_id, x, y, x, y, x, y, x, y]`, + where pairs of [x, y] are box corners. Returns: DetectionDataset: A DetectionDataset instance diff --git a/supervision/dataset/formats/yolo.py b/supervision/dataset/formats/yolo.py index 64ab84c9..f634d4fa 100644 --- a/supervision/dataset/formats/yolo.py +++ b/supervision/dataset/formats/yolo.py @@ -137,7 +137,9 @@ def load_yolo_annotations( YAML file containing class information. force_masks (bool, optional): If True, forces masks to be loaded for all annotations, regardless of whether they are present. - is_obb (bool, optional): If True, returns the annotations in YOLO-OBB format. + is_obb (bool, optional): If True, loads the annotations in OBB format. + OBB annotations are defined as `[class_id, x, y, x, y, x, y, x, y]`, + where pairs of [x, y] are box corners. Returns: Tuple[List[str], Dict[str, np.ndarray], Dict[str, Detections]]: