diff --git a/CHANGELOG.md b/CHANGELOG.md index 6471d49669..2da2395a76 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -45,9 +45,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 () - Skeleton support in datumaro format () -- Support for YOLOv8 formats +- Support for Ultralytics YOLO formats () -- Support for YOLOv8 Classification format +- Support for Ultralytics YOLO Classification format () ### Changed diff --git a/datumaro/plugins/yolo_format/converter.py b/datumaro/plugins/yolo_format/converter.py index ab24980e5e..0883bbb0ab 100644 --- a/datumaro/plugins/yolo_format/converter.py +++ b/datumaro/plugins/yolo_format/converter.py @@ -32,7 +32,7 @@ from datumaro.util import dump_json_file, str_to_bool from datumaro.util.os_util import split_path -from .format import YoloPath, YOLOv8ClassificationFormat, YOLOv8Path +from .format import YoloPath, YoloUltralyticsClassificationFormat, YoloUltralyticsPath def _make_yolo_bbox(img_size, box): @@ -278,8 +278,8 @@ def patch(cls, dataset: IExtractor, patch: DatasetPatch, save_dir: str, **kwargs os.remove(ann_path) -class YOLOv8DetectionConverter(YoloConverter): - RESERVED_CONFIG_KEYS = YOLOv8Path.RESERVED_CONFIG_KEYS +class YoloUltralyticsDetectionConverter(YoloConverter): + RESERVED_CONFIG_KEYS = YoloUltralyticsPath.RESERVED_CONFIG_KEYS def __init__( self, @@ -291,7 +291,7 @@ def __init__( **kwargs, ) -> None: super().__init__(extractor, save_dir, add_path_prefix=add_path_prefix, **kwargs) - self._config_filename = config_file or YOLOv8Path.DEFAULT_CONFIG_FILE + self._config_filename = config_file or YoloUltralyticsPath.DEFAULT_CONFIG_FILE def _save_annotation_file(self, annotation_path, yolo_annotation): if yolo_annotation: @@ -302,7 +302,7 @@ def build_cmdline_parser(cls, **kwargs): parser = super().build_cmdline_parser(**kwargs) parser.add_argument( "--config-file", - default=YOLOv8Path.DEFAULT_CONFIG_FILE, + default=YoloUltralyticsPath.DEFAULT_CONFIG_FILE, type=str, help="config file name (default: %(default)s)", ) @@ -326,14 +326,14 @@ def _save_config_files(self, subset_lists: Dict[str, str], **extra_config_fields @staticmethod def _make_image_subset_folder(save_dir: str, subset: str) -> str: - return osp.join(save_dir, YOLOv8Path.IMAGES_FOLDER_NAME, subset) + return osp.join(save_dir, YoloUltralyticsPath.IMAGES_FOLDER_NAME, subset) @staticmethod def _make_annotation_subset_folder(save_dir: str, subset: str) -> str: - return osp.join(save_dir, YOLOv8Path.LABELS_FOLDER_NAME, subset) + return osp.join(save_dir, YoloUltralyticsPath.LABELS_FOLDER_NAME, subset) -class YOLOv8SegmentationConverter(YOLOv8DetectionConverter): +class YoloUltralyticsSegmentationConverter(YoloUltralyticsDetectionConverter): def _make_annotation_line(self, width: int, height: int, anno: Annotation) -> Optional[str]: if anno.label is None or not isinstance(anno, Polygon): return @@ -342,7 +342,7 @@ def _make_annotation_line(self, width: int, height: int, anno: Annotation) -> Op return "%s %s\n" % (self._map_labels_for_save[anno.label], string_values) -class YOLOv8OrientedBoxesConverter(YOLOv8DetectionConverter): +class YoloUltralyticsOrientedBoxesConverter(YoloUltralyticsDetectionConverter): def _make_annotation_line(self, width: int, height: int, anno: Annotation) -> Optional[str]: if anno.label is None or not isinstance(anno, Bbox): return @@ -352,7 +352,7 @@ def _make_annotation_line(self, width: int, height: int, anno: Annotation) -> Op return "%s %s\n" % (self._map_labels_for_save[anno.label], string_values) -class YOLOv8PoseConverter(YOLOv8DetectionConverter): +class YoloUltralyticsPoseConverter(YoloUltralyticsDetectionConverter): @cached_property def _labels_to_save(self) -> List[int]: point_categories = self._extractor.categories().get( @@ -403,7 +403,7 @@ def _make_annotation_line(self, width: int, height: int, skeleton: Annotation) - return f"{self._map_labels_for_save[skeleton.label]} {bbox_string_values} {' '.join(points_values)}\n" -class YOLOv8ClassificationConverter(Converter): +class YoloUltralyticsClassificationConverter(Converter): DEFAULT_IMAGE_EXT = ".jpg" def apply(self): @@ -438,7 +438,7 @@ def apply(self): if anno.type == AnnotationType.label ] for label_name in items_info[item.id]["labels"] or [ - YOLOv8ClassificationFormat.IMAGE_DIR_NO_LABEL + YoloUltralyticsClassificationFormat.IMAGE_DIR_NO_LABEL ]: items_info[item.id]["path"] = self._export_media_for_label( item, subset_name, label_name @@ -450,7 +450,7 @@ def apply(self): labels_path = osp.join( self._save_dir, subset_name, - YOLOv8ClassificationFormat.LABELS_FILE, + YoloUltralyticsClassificationFormat.LABELS_FILE, ) dump_json_file(labels_path, items_info) diff --git a/datumaro/plugins/yolo_format/extractor.py b/datumaro/plugins/yolo_format/extractor.py index b56e4bd228..1d7d7ef2e0 100644 --- a/datumaro/plugins/yolo_format/extractor.py +++ b/datumaro/plugins/yolo_format/extractor.py @@ -45,7 +45,12 @@ from datumaro.util.meta_file_util import get_meta_file, has_meta_file, parse_meta_file from datumaro.util.os_util import split_path -from .format import YoloPath, YOLOv8ClassificationFormat, YOLOv8Path, YOLOv8PoseFormat +from .format import ( + YoloPath, + YoloUltralyticsClassificationFormat, + YoloUltralyticsPath, + YoloUltralyticsPoseFormat, +) T = TypeVar("T") @@ -345,8 +350,8 @@ def _load_categories(self) -> CategoriesInfo: return {AnnotationType.label: label_categories} -class YOLOv8DetectionExtractor(YoloExtractor): - RESERVED_CONFIG_KEYS = YOLOv8Path.RESERVED_CONFIG_KEYS +class YoloUltralyticsDetectionExtractor(YoloExtractor): + RESERVED_CONFIG_KEYS = YoloUltralyticsPath.RESERVED_CONFIG_KEYS def __init__( self, @@ -417,17 +422,20 @@ def _load_categories(self) -> CategoriesInfo: def _get_labels_path_from_image_path(self, image_path: str) -> str: rel_image_path = osp.relpath(image_path, self._path) split_rel_path = rel_image_path.split(osp.sep, 2) - if len(split_rel_path) < 3 or YOLOv8Path.IMAGES_FOLDER_NAME not in split_rel_path[:2]: + if ( + len(split_rel_path) < 3 + or YoloUltralyticsPath.IMAGES_FOLDER_NAME not in split_rel_path[:2] + ): raise InvalidAnnotationError(f"Malformed folder structure for image {rel_image_path}") split_rel_path[ next( index for index in range(len(split_rel_path) - 1, -1, -1) - if split_rel_path[index] == YOLOv8Path.IMAGES_FOLDER_NAME + if split_rel_path[index] == YoloUltralyticsPath.IMAGES_FOLDER_NAME ) - ] = YOLOv8Path.LABELS_FOLDER_NAME - split_rel_path[2] = osp.splitext(split_rel_path[2])[0] + YOLOv8Path.LABELS_EXT + ] = YoloUltralyticsPath.LABELS_FOLDER_NAME + split_rel_path[2] = osp.splitext(split_rel_path[2])[0] + YoloUltralyticsPath.LABELS_EXT return osp.join(self._path, *split_rel_path) @@ -465,7 +473,7 @@ def _get_subset_image_paths(self, subset_name: str): yield from subset_images_source -class YOLOv8SegmentationExtractor(YOLOv8DetectionExtractor): +class YoloUltralyticsSegmentationExtractor(YoloUltralyticsDetectionExtractor): def _load_segmentation_annotation( self, parts: List[str], image_height: int, image_width: int ) -> Polygon: @@ -492,7 +500,7 @@ def _load_one_annotation( ) -class YOLOv8OrientedBoxesExtractor(YOLOv8DetectionExtractor): +class YoloUltralyticsOrientedBoxesExtractor(YoloUltralyticsDetectionExtractor): def _load_one_annotation( self, parts: List[str], image_height: int, image_width: int ) -> Annotation: @@ -525,7 +533,7 @@ def _load_one_annotation( ) -class YOLOv8PoseExtractor(YOLOv8DetectionExtractor): +class YoloUltralyticsPoseExtractor(YoloUltralyticsDetectionExtractor): def __init__( self, *args, @@ -537,24 +545,24 @@ def __init__( @cached_property def _kpt_shape(self) -> list[int]: - if YOLOv8PoseFormat.KPT_SHAPE_FIELD_NAME not in self._config: + if YoloUltralyticsPoseFormat.KPT_SHAPE_FIELD_NAME not in self._config: raise InvalidAnnotationError( - f"Failed to parse {YOLOv8PoseFormat.KPT_SHAPE_FIELD_NAME} from config" + f"Failed to parse {YoloUltralyticsPoseFormat.KPT_SHAPE_FIELD_NAME} from config" ) - kpt_shape = self._config[YOLOv8PoseFormat.KPT_SHAPE_FIELD_NAME] + kpt_shape = self._config[YoloUltralyticsPoseFormat.KPT_SHAPE_FIELD_NAME] if not isinstance(kpt_shape, list) or len(kpt_shape) != 2: raise InvalidAnnotationError( - f"Failed to parse {YOLOv8PoseFormat.KPT_SHAPE_FIELD_NAME} from config" + f"Failed to parse {YoloUltralyticsPoseFormat.KPT_SHAPE_FIELD_NAME} from config" ) if kpt_shape[1] not in [2, 3]: raise InvalidAnnotationError( f"Unexpected values per point {kpt_shape[1]} in field" - f"{YOLOv8PoseFormat.KPT_SHAPE_FIELD_NAME}. Expected 2 or 3." + f"{YoloUltralyticsPoseFormat.KPT_SHAPE_FIELD_NAME}. Expected 2 or 3." ) if not isinstance(kpt_shape[0], int) or kpt_shape[0] < 0: raise InvalidAnnotationError( f"Unexpected number of points {kpt_shape[0]} in field " - f"{YOLOv8PoseFormat.KPT_SHAPE_FIELD_NAME}. Expected non-negative integer." + f"{YoloUltralyticsPoseFormat.KPT_SHAPE_FIELD_NAME}. Expected non-negative integer." ) return kpt_shape @@ -689,7 +697,7 @@ def _load_one_annotation( return Skeleton(points, label=label_id) -class YOLOv8ClassificationExtractor(YoloBaseExtractor): +class YoloUltralyticsClassificationExtractor(YoloBaseExtractor): def _get_subset_names(self): return [ subset_name @@ -699,7 +707,7 @@ def _get_subset_names(self): def _get_image_paths_for_subset_and_label(self, subset_name: str, label_name: str) -> list[str]: category_folder = osp.join(self._path, subset_name, label_name) - image_list_path = osp.join(category_folder, YOLOv8ClassificationFormat.LABELS_FILE) + image_list_path = osp.join(category_folder, YoloUltralyticsClassificationFormat.LABELS_FILE) if osp.isfile(image_list_path): with open(image_list_path, "r", encoding="utf-8") as f: yield from (osp.join(subset_name, label_name, line.strip()) for line in f) @@ -711,7 +719,7 @@ def _get_image_paths_for_subset_and_label(self, subset_name: str, label_name: st def _get_item_info_from_labels_file(self, subset_name: str) -> Optional[Dict]: subset_path = osp.join(self._path, subset_name) - labels_file_path = osp.join(subset_path, YOLOv8ClassificationFormat.LABELS_FILE) + labels_file_path = osp.join(subset_path, YoloUltralyticsClassificationFormat.LABELS_FILE) if osp.isfile(labels_file_path): return parse_json_file(labels_file_path) @@ -740,7 +748,7 @@ def _parse_annotations(self, image: Image, *, item_id: Tuple[str, str]) -> List[ return [ Label(label=self._categories[AnnotationType.label].find(label)[0]) for label in label_names - if label != YOLOv8ClassificationFormat.IMAGE_DIR_NO_LABEL + if label != YoloUltralyticsClassificationFormat.IMAGE_DIR_NO_LABEL ] def _load_categories(self) -> CategoriesInfo: @@ -756,7 +764,7 @@ def _load_categories(self) -> CategoriesInfo: for label_dir_name in os.listdir(subset_path): if not osp.isdir(osp.join(subset_path, label_dir_name)): continue - if label_dir_name == YOLOv8ClassificationFormat.IMAGE_DIR_NO_LABEL: + if label_dir_name == YoloUltralyticsClassificationFormat.IMAGE_DIR_NO_LABEL: continue categories.add(label_dir_name) return {AnnotationType.label: LabelCategories.from_iterable(sorted(categories))} diff --git a/datumaro/plugins/yolo_format/format.py b/datumaro/plugins/yolo_format/format.py index a266c5c540..38c3704d89 100644 --- a/datumaro/plugins/yolo_format/format.py +++ b/datumaro/plugins/yolo_format/format.py @@ -12,7 +12,7 @@ class YoloPath: SUBSET_LIST_EXT = ".txt" -class YOLOv8Path(YoloPath): +class YoloUltralyticsPath(YoloPath): CONFIG_FILE_EXT = ".yaml" DEFAULT_CONFIG_FILE = "data.yaml" RESERVED_CONFIG_KEYS = YoloPath.RESERVED_CONFIG_KEYS + [ @@ -24,10 +24,10 @@ class YOLOv8Path(YoloPath): LABELS_FOLDER_NAME = "labels" -class YOLOv8PoseFormat: +class YoloUltralyticsPoseFormat: KPT_SHAPE_FIELD_NAME = "kpt_shape" -class YOLOv8ClassificationFormat: +class YoloUltralyticsClassificationFormat: IMAGE_DIR_NO_LABEL = "no_label" LABELS_FILE = "labels.json" diff --git a/datumaro/plugins/yolo_format/importer.py b/datumaro/plugins/yolo_format/importer.py index 0ba4238b76..d83b0eecff 100644 --- a/datumaro/plugins/yolo_format/importer.py +++ b/datumaro/plugins/yolo_format/importer.py @@ -14,13 +14,13 @@ from datumaro import Importer from datumaro.components.format_detection import FormatDetectionContext from datumaro.plugins.yolo_format.extractor import ( - YOLOv8ClassificationExtractor, - YOLOv8DetectionExtractor, - YOLOv8OrientedBoxesExtractor, - YOLOv8PoseExtractor, - YOLOv8SegmentationExtractor, + YoloUltralyticsClassificationExtractor, + YoloUltralyticsDetectionExtractor, + YoloUltralyticsOrientedBoxesExtractor, + YoloUltralyticsPoseExtractor, + YoloUltralyticsSegmentationExtractor, ) -from datumaro.plugins.yolo_format.format import YOLOv8Path, YOLOv8PoseFormat +from datumaro.plugins.yolo_format.format import YoloUltralyticsPath, YoloUltralyticsPoseFormat class YoloImporter(Importer): @@ -33,8 +33,8 @@ def find_sources(cls, path) -> List[Dict[str, Any]]: return cls._find_sources_recursive(path, ".data", "yolo") -class YOLOv8DetectionImporter(Importer): - EXTRACTOR = YOLOv8DetectionExtractor +class YoloUltralyticsDetectionImporter(Importer): + EXTRACTOR = YoloUltralyticsDetectionExtractor @classmethod def build_cmdline_parser(cls, **kwargs): @@ -49,18 +49,18 @@ def build_cmdline_parser(cls, **kwargs): def _check_config_file(cls, context, config_file): with context.probe_text_file( config_file, - f"must not have '{YOLOv8PoseFormat.KPT_SHAPE_FIELD_NAME}' field", + f"must not have '{YoloUltralyticsPoseFormat.KPT_SHAPE_FIELD_NAME}' field", ) as f: try: config = yaml.safe_load(f) - if YOLOv8PoseFormat.KPT_SHAPE_FIELD_NAME in config: + if YoloUltralyticsPoseFormat.KPT_SHAPE_FIELD_NAME in config: raise Exception except yaml.YAMLError: raise Exception @classmethod def detect(cls, context: FormatDetectionContext) -> None: - context.require_file(f"*{YOLOv8Path.CONFIG_FILE_EXT}") + context.require_file(f"*{YoloUltralyticsPath.CONFIG_FILE_EXT}") sources = cls.find_sources_with_params(context.root_path) if not sources or len(sources) > 1: context.fail("Cannot choose config file") @@ -72,7 +72,7 @@ def find_sources_with_params( cls, path, config_file=None, **extra_params ) -> List[Dict[str, Any]]: sources = cls._find_sources_recursive( - path, YOLOv8Path.CONFIG_FILE_EXT, cls.EXTRACTOR.NAME, max_depth=1 + path, YoloUltralyticsPath.CONFIG_FILE_EXT, cls.EXTRACTOR.NAME, max_depth=1 ) if config_file: @@ -82,36 +82,36 @@ def find_sources_with_params( return [ source for source in sources - if source["url"] == osp.join(path, YOLOv8Path.DEFAULT_CONFIG_FILE) + if source["url"] == osp.join(path, YoloUltralyticsPath.DEFAULT_CONFIG_FILE) ] -class YOLOv8SegmentationImporter(YOLOv8DetectionImporter): - EXTRACTOR = YOLOv8SegmentationExtractor +class YoloUltralyticsSegmentationImporter(YoloUltralyticsDetectionImporter): + EXTRACTOR = YoloUltralyticsSegmentationExtractor -class YOLOv8OrientedBoxesImporter(YOLOv8DetectionImporter): - EXTRACTOR = YOLOv8OrientedBoxesExtractor +class YoloUltralyticsOrientedBoxesImporter(YoloUltralyticsDetectionImporter): + EXTRACTOR = YoloUltralyticsOrientedBoxesExtractor -class YOLOv8PoseImporter(YOLOv8DetectionImporter): - EXTRACTOR = YOLOv8PoseExtractor +class YoloUltralyticsPoseImporter(YoloUltralyticsDetectionImporter): + EXTRACTOR = YoloUltralyticsPoseExtractor @classmethod def _check_config_file(cls, context, config_file): with context.probe_text_file( config_file, - f"must have '{YOLOv8PoseFormat.KPT_SHAPE_FIELD_NAME}' field", + f"must have '{YoloUltralyticsPoseFormat.KPT_SHAPE_FIELD_NAME}' field", ) as f: try: config = yaml.safe_load(f) - if YOLOv8PoseFormat.KPT_SHAPE_FIELD_NAME not in config: + if YoloUltralyticsPoseFormat.KPT_SHAPE_FIELD_NAME not in config: raise Exception except yaml.YAMLError: raise Exception -class YOLOv8ClassificationImporter(Importer): +class YoloUltralyticsClassificationImporter(Importer): @classmethod def find_sources(cls, path): if not osp.isdir(path): @@ -120,4 +120,4 @@ def find_sources(cls, path): subfolder for name in os.listdir(path) if osp.isdir(subfolder := osp.join(path, name)) ]: return [] - return [{"url": path, "format": YOLOv8ClassificationExtractor.NAME}] + return [{"url": path, "format": YoloUltralyticsClassificationExtractor.NAME}] diff --git a/site/content/en/docs/formats/yolo_v8.md b/site/content/en/docs/formats/yolo_ultralytics.md similarity index 79% rename from site/content/en/docs/formats/yolo_v8.md rename to site/content/en/docs/formats/yolo_ultralytics.md index f3977a83f6..d3a67c273f 100644 --- a/site/content/en/docs/formats/yolo_v8.md +++ b/site/content/en/docs/formats/yolo_ultralytics.md @@ -1,13 +1,13 @@ --- -title: 'YOLOv8' -linkTitle: 'YOLOv8' +title: 'Ultralytics YOLO' +linkTitle: 'Ultralytics YOLO' description: '' --- ## Format specification -The YOLOv8 format family allows you to define the dataset root directory, the relative paths -to training/validation/testing image directories or *.txt files containing image paths, +The Ultralytics YOLO format family allows you to define the dataset root directory, the relative +paths to training/validation/testing image directories or *.txt files containing image paths, and a dictionary of class names. Family consists of four formats: @@ -32,18 +32,18 @@ The format supports arbitrary subset names, except `classes`, `names`, `backup`, If there is no subset separation in a project, the data will be saved in the `train` subset. -## Import YOLOv8 dataset -To create a Datumaro project with a YOLOv8 source, use the following commands: +## Import Ultralytics YOLO dataset +To create a Datumaro project with a Ultralytics YOLO source, use the following commands: ```bash datum create -datum import --format yolov8_detection # for Detection dataset -datum import --format yolov8_oriented_boxes # for Oriented Bounding Box dataset -datum import --format yolov8_segmentation # for Segmentation dataset -datum import --format yolov8_pose # for Pose dataset +datum import --format yolo_ultralytics_detection # for Detection dataset +datum import --format yolo_ultralytics_oriented_boxes # for Oriented Bounding Box dataset +datum import --format yolo_ultralytics_segmentation # for Segmentation dataset +datum import --format yolo_ultralytics_pose # for Pose dataset ``` -The YOLOv8 dataset directory should have the following structure: +The Ultralytics YOLO dataset directory should have the following structure: ```bash └─ yolo_dataset/ @@ -83,7 +83,7 @@ path: ./ # dataset root dir train: train.txt # train images (relative to 'path') 4 images val: val.txt # val images (relative to 'path') 4 images -# YOLOv8 Pose specific field +# Ultralytics YOLO Pose specific field # First number is a number of points in skeleton # Second number defines a format of point info in an annotation txt files kpt_shape: [17, 3] @@ -98,7 +98,7 @@ names: 78: hair drier 79: toothbrush ``` -> Note, that though by default YOLOv8 framework expects `data.yaml`, +> Note, that though by default Ultralytics YOLO framework expects `data.yaml`, Datumaro allows this file to have arbitrary name. `data.yaml` can specify what images a subset contains in 3 ways: @@ -182,21 +182,21 @@ and y coordinates and heights by image height. ## Export to other formats -Datumaro can convert a YOLOv8 dataset into any other format Datumaro supports. +Datumaro can convert a Ultralytics YOLO dataset into any other format Datumaro supports. To get the expected result, convert the dataset to formats -that support the same annotations as YOLOv8 format you have. +that support the same annotations as Ultralytics YOLO format you have. ```bash datum create -datum add -f yolov8_detection +datum add -f yolo_ultralytics_detection datum export -f coco_instances -o ``` or ```bash -datum convert -if yolov8_detection -i -f coco_instances -o +datum convert -if yolo_ultralytics_detection -i -f coco_instances -o ``` -Extra options for importing YOLOv8 format: +Extra options for importing Ultralytics YOLO format: - `--config-file` allows to specify config file name to use instead of default `data.yaml` Alternatively, using the Python API: @@ -205,14 +205,14 @@ Alternatively, using the Python API: from datumaro.components.dataset import Dataset data_path = 'path/to/dataset' -data_format = 'yolov8_detection' +data_format = 'yolo_ultralytics_detection' dataset = Dataset.import_from(data_path, data_format) dataset.export('save_dir', 'coco_instances') ``` -## Export to YOLOv8 format -Datumaro can convert an existing dataset to YOLOv8 format +## Export to Ultralytics YOLO format +Datumaro can convert an existing dataset to Ultralytics YOLO format if it supports annotations from source format. Example: @@ -220,10 +220,10 @@ Example: ```bash datum create datum import -f coco_instances -datum export -f yolov8_detection -o +datum export -f yolo_ultralytics_detection -o ``` -Extra options for exporting to YOLOv8 format: +Extra options for exporting to Ultralytics YOLO format: - `--save-media` allow to export dataset with saving media files (default: `False`) - `--image-ext ` allow to specify image extension @@ -234,7 +234,7 @@ Extra options for exporting to YOLOv8 format: ## Examples -### Example 1. Create a custom dataset in YOLOv8 Detection format +### Example 1. Create a custom dataset in Ultralytics YOLO Detection format ```python import numpy as np @@ -254,10 +254,10 @@ dataset = dm.Dataset.from_iterable( ], categories=["label_" + str(i) for i in range(10)], ) -dataset.export('../yolov8_dataset', format='yolov8_detection') +dataset.export('../yolo_ultralytics_dataset', format='yolo_ultralytics_detection') ``` -### Example 2. Create a custom dataset in YOLOv8 Oriented Bounding Box format +### Example 2. Create a custom dataset in Ultralytics YOLO Oriented Bounding Box format Orientation of bounding boxes is controlled through `rotation` attribute of `Bbox` annotation. Its value is a counter-clockwise angle in degrees. @@ -280,10 +280,10 @@ dataset = dm.Dataset.from_iterable( ], categories=["label_" + str(i) for i in range(10)], ) -dataset.export('../yolov8_dataset', format='yolov8_oriented_boxes') +dataset.export('../yolo_ultralytics_dataset', format='yolo_ultralytics_oriented_boxes') ``` -### Example 3. Create a custom dataset in YOLOv8 Segmentation format +### Example 3. Create a custom dataset in Ultralytics YOLO Segmentation format ```python import numpy as np @@ -302,10 +302,10 @@ dataset = dm.Dataset.from_iterable( ], categories=["label_" + str(i) for i in range(10)], ) -dataset.export('../yolov8_dataset', format='yolov8_segmentation') +dataset.export('../yolo_ultralytics_dataset', format='yolo_ultralytics_segmentation') ``` -### Example 4. Create a custom dataset in YOLOv8 Pose format +### Example 4. Create a custom dataset in Ultralytics YOLO Pose format ```python import numpy as np @@ -341,5 +341,5 @@ dataset = dm.Dataset.from_iterable( ]), }, ) -dataset.export('../yolov8_dataset', format='yolov8_pose') +dataset.export('../yolo_ultralytics_dataset', format='yolo_ultralytics_pose') ``` diff --git a/site/content/en/docs/formats/yolo_v8_classification.md b/site/content/en/docs/formats/yolo_ultralytics_classification.md similarity index 66% rename from site/content/en/docs/formats/yolo_v8_classification.md rename to site/content/en/docs/formats/yolo_ultralytics_classification.md index 6dc3a3f20f..c6e4f945d2 100644 --- a/site/content/en/docs/formats/yolo_v8_classification.md +++ b/site/content/en/docs/formats/yolo_ultralytics_classification.md @@ -1,6 +1,6 @@ --- -title: 'YOLOv8Classification' -linkTitle: 'YOLOv8Classification' +title: 'Ultralytics YOLO Classification' +linkTitle: 'Ultralytics YOLO Classification' description: '' --- @@ -14,25 +14,25 @@ Supported types of annotations: Format doesn't support any attributes for annotations objects. -## Import YOLOv8 classification dataset +## Import Ultralytics YOLO classification dataset A Datumaro project with a ImageNet dataset can be created in the following way: ``` datum create -datum import -f yolov8_classification +datum import -f yolo_ultralytics_classification ``` -Load YOLOOv8 Classification dataset through the Python API: +Load Ultralytics YOLO Classification dataset through the Python API: ```python import datumaro as dm -dataset = dm.Dataset.import_from('', format='yolov8_classification') +dataset = dm.Dataset.import_from('', format='yolo_ultralytics_classification') ``` -For successful importing of YOLOv8 Classification dataset the input directory with dataset +For successful importing of Ultralytics YOLO Classification dataset the input directory with dataset should has the following structure: ```bash @@ -52,7 +52,7 @@ dataset/ ├── ... ``` -## Export YOLOv8 Classification dataset +## Export Ultralytics YOLO Classification dataset Datumaro can convert the dataset into any other format [Datumaro supports](/docs/user-manual/supported_formats). @@ -61,21 +61,21 @@ that supports `Label` annotation objects. ``` # Using `convert` command -datum convert -if yolov8_classification -i \ +datum convert -if yolo_ultralytics_classification -i \ -f voc -o -- --save-media # Using Datumaro project datum create -datum import -f yolov8_classification +datum import -f yolo_ultralytics_classification datum export -f open_images -o ``` -And also you can convert your YOLOv8 Classification dataset using Python API +And also you can convert your Ultralytics YOLO Classification dataset using Python API ```python import datumaro as dm -dataset = dm.Dataset.import_from('', format='vgg_face2', save_media=True) ``` @@ -83,23 +83,23 @@ dataset.export('', format='vgg_face2', save_media=True) > Note: some formats have extra export options. For particular format see the > [docs](/docs/formats/) to get information about it. -## Export dataset to the YOLOv8 Classification format +## Export dataset to the Ultralytics YOLO Classification format If your dataset contains `Label` for images and you want to convert this -dataset into the YOLOv8 Classification format, you can use Datumaro for it: +dataset into the YOLO Ultralytics Classification format, you can use Datumaro for it: ``` # Using convert command datum convert -if open_images -i \ - -f yolov8_classification -o -- --save-media --save-dataset-meta + -f yolo_ultralytics_classification -o -- --save-media --save-dataset-meta # Using Datumaro project datum create datum import -f open_images -datum export -f yolov8_classification -o +datum export -f yolo_ultralytics_classification -o ``` -Extra options for exporting to YOLOv8 Classification formats: +Extra options for exporting to Ultralytics YOLO Classification formats: - `--save-media` allow to export dataset with saving media files (by default `False`) - `--save-dataset-meta` - allow to export dataset with saving dataset meta diff --git a/site/content/en/docs/user-manual/supported_formats.md b/site/content/en/docs/user-manual/supported_formats.md index ab0e7ab3a9..ce2b26d4c6 100644 --- a/site/content/en/docs/user-manual/supported_formats.md +++ b/site/content/en/docs/user-manual/supported_formats.md @@ -161,27 +161,27 @@ List of supported formats: - [Format specification](https://github.com/AlexeyAB/darknet#how-to-train-pascal-voc-data) - [Dataset example](https://github.com/cvat-ai/datumaro/tree/develop/tests/assets/yolo_dataset) - [Format documentation](/docs/formats/yolo) -- YOLOv8 (`detection`, `segmentation`, `pose`, `oriented_box`) +- YOLO Ultralytics (`detection`, `segmentation`, `pose`, `oriented_box`, `classification`) - Detection - [Format specification](https://docs.ultralytics.com/datasets/detect/) - [Dataset example](https://docs.ultralytics.com/datasets/detect/coco8/) - - [Format documentation](/docs/formats/yolo_v8) + - [Format documentation](/docs/formats/yolo_ultralytics) - Segmentation - [Format specification](https://docs.ultralytics.com/datasets/segment/) - [Dataset example](https://docs.ultralytics.com/datasets/segment/coco8-seg/) - - [Format documentation](/docs/formats/yolo_v8) + - [Format documentation](/docs/formats/yolo_ultralytics) - Pose - [Format specification](https://docs.ultralytics.com/datasets/pose/) - [Dataset example](https://docs.ultralytics.com/datasets/pose/coco8-pose/) - - [Format documentation](/docs/formats/yolo_v8) + - [Format documentation](/docs/formats/yolo_ultralytics) - Oriented box - [Format specification](https://docs.ultralytics.com/datasets/obb/) - [Dataset example](https://docs.ultralytics.com/datasets/obb/dota8/) - - [Format documentation](/docs/formats/yolo_v8) + - [Format documentation](/docs/formats/yolo_ultralytics) - Classification - [Format specification](https://docs.ultralytics.com/datasets/classify/) - - [Dataset example](https://github.com/cvat-ai/datumaro/tree/develop/tests/assets/yolo_dataset/yolov8_classification) - - [Format documentation](/docs/formats/yolo_v8_classification) + - [Dataset example](https://github.com/cvat-ai/datumaro/tree/develop/tests/assets/yolo_dataset/yolo_ultralytics_classification) + - [Format documentation](/docs/formats/yolo_ultralytics_classification) ### Supported annotation types diff --git a/tests/assets/yolo_dataset/yolov8_classification/train/label_0/1.jpg b/tests/assets/yolo_dataset/yolo_ultralytics_classification/train/label_0/1.jpg similarity index 100% rename from tests/assets/yolo_dataset/yolov8_classification/train/label_0/1.jpg rename to tests/assets/yolo_dataset/yolo_ultralytics_classification/train/label_0/1.jpg diff --git a/tests/assets/yolo_dataset/yolov8_classification/train/label_0/2.jpg b/tests/assets/yolo_dataset/yolo_ultralytics_classification/train/label_0/2.jpg similarity index 100% rename from tests/assets/yolo_dataset/yolov8_classification/train/label_0/2.jpg rename to tests/assets/yolo_dataset/yolo_ultralytics_classification/train/label_0/2.jpg diff --git a/tests/assets/yolo_dataset/yolov8_classification/train/label_1/3.jpg b/tests/assets/yolo_dataset/yolo_ultralytics_classification/train/label_1/3.jpg similarity index 100% rename from tests/assets/yolo_dataset/yolov8_classification/train/label_1/3.jpg rename to tests/assets/yolo_dataset/yolo_ultralytics_classification/train/label_1/3.jpg diff --git a/tests/assets/yolo_dataset/yolov8_detection/data.yaml b/tests/assets/yolo_dataset/yolo_ultralytics_detection/data.yaml similarity index 100% rename from tests/assets/yolo_dataset/yolov8_detection/data.yaml rename to tests/assets/yolo_dataset/yolo_ultralytics_detection/data.yaml diff --git a/tests/assets/yolo_dataset/yolov8_detection/images/train/1.jpg b/tests/assets/yolo_dataset/yolo_ultralytics_detection/images/train/1.jpg similarity index 100% rename from tests/assets/yolo_dataset/yolov8_detection/images/train/1.jpg rename to tests/assets/yolo_dataset/yolo_ultralytics_detection/images/train/1.jpg diff --git a/tests/assets/yolo_dataset/yolov8_detection/labels/train/1.txt b/tests/assets/yolo_dataset/yolo_ultralytics_detection/labels/train/1.txt similarity index 100% rename from tests/assets/yolo_dataset/yolov8_detection/labels/train/1.txt rename to tests/assets/yolo_dataset/yolo_ultralytics_detection/labels/train/1.txt diff --git a/tests/assets/yolo_dataset/yolov8_detection_reversed_folders/data.yaml b/tests/assets/yolo_dataset/yolo_ultralytics_detection_reversed_folders/data.yaml similarity index 100% rename from tests/assets/yolo_dataset/yolov8_detection_reversed_folders/data.yaml rename to tests/assets/yolo_dataset/yolo_ultralytics_detection_reversed_folders/data.yaml diff --git a/tests/assets/yolo_dataset/yolov8_detection_reversed_folders/train/images/1.jpg b/tests/assets/yolo_dataset/yolo_ultralytics_detection_reversed_folders/train/images/1.jpg similarity index 100% rename from tests/assets/yolo_dataset/yolov8_detection_reversed_folders/train/images/1.jpg rename to tests/assets/yolo_dataset/yolo_ultralytics_detection_reversed_folders/train/images/1.jpg diff --git a/tests/assets/yolo_dataset/yolov8_detection_reversed_folders/train/labels/1.txt b/tests/assets/yolo_dataset/yolo_ultralytics_detection_reversed_folders/train/labels/1.txt similarity index 100% rename from tests/assets/yolo_dataset/yolov8_detection_reversed_folders/train/labels/1.txt rename to tests/assets/yolo_dataset/yolo_ultralytics_detection_reversed_folders/train/labels/1.txt diff --git a/tests/assets/yolo_dataset/yolov8_detection_with_list_of_imgs/data.yaml b/tests/assets/yolo_dataset/yolo_ultralytics_detection_with_list_of_imgs/data.yaml similarity index 100% rename from tests/assets/yolo_dataset/yolov8_detection_with_list_of_imgs/data.yaml rename to tests/assets/yolo_dataset/yolo_ultralytics_detection_with_list_of_imgs/data.yaml diff --git a/tests/assets/yolo_dataset/yolov8_detection_with_list_of_imgs/images/train/1.jpg b/tests/assets/yolo_dataset/yolo_ultralytics_detection_with_list_of_imgs/images/train/1.jpg similarity index 100% rename from tests/assets/yolo_dataset/yolov8_detection_with_list_of_imgs/images/train/1.jpg rename to tests/assets/yolo_dataset/yolo_ultralytics_detection_with_list_of_imgs/images/train/1.jpg diff --git a/tests/assets/yolo_dataset/yolov8_detection_with_list_of_imgs/labels/train/1.txt b/tests/assets/yolo_dataset/yolo_ultralytics_detection_with_list_of_imgs/labels/train/1.txt similarity index 100% rename from tests/assets/yolo_dataset/yolov8_detection_with_list_of_imgs/labels/train/1.txt rename to tests/assets/yolo_dataset/yolo_ultralytics_detection_with_list_of_imgs/labels/train/1.txt diff --git a/tests/assets/yolo_dataset/yolov8_detection_with_list_of_names/data.yaml b/tests/assets/yolo_dataset/yolo_ultralytics_detection_with_list_of_names/data.yaml similarity index 100% rename from tests/assets/yolo_dataset/yolov8_detection_with_list_of_names/data.yaml rename to tests/assets/yolo_dataset/yolo_ultralytics_detection_with_list_of_names/data.yaml diff --git a/tests/assets/yolo_dataset/yolov8_detection_with_list_of_names/images/train/1.jpg b/tests/assets/yolo_dataset/yolo_ultralytics_detection_with_list_of_names/images/train/1.jpg similarity index 100% rename from tests/assets/yolo_dataset/yolov8_detection_with_list_of_names/images/train/1.jpg rename to tests/assets/yolo_dataset/yolo_ultralytics_detection_with_list_of_names/images/train/1.jpg diff --git a/tests/assets/yolo_dataset/yolov8_detection_with_list_of_names/labels/train/1.txt b/tests/assets/yolo_dataset/yolo_ultralytics_detection_with_list_of_names/labels/train/1.txt similarity index 100% rename from tests/assets/yolo_dataset/yolov8_detection_with_list_of_names/labels/train/1.txt rename to tests/assets/yolo_dataset/yolo_ultralytics_detection_with_list_of_names/labels/train/1.txt diff --git a/tests/assets/yolo_dataset/yolov8_detection_with_subset_txt/data.yaml b/tests/assets/yolo_dataset/yolo_ultralytics_detection_with_subset_txt/data.yaml similarity index 100% rename from tests/assets/yolo_dataset/yolov8_detection_with_subset_txt/data.yaml rename to tests/assets/yolo_dataset/yolo_ultralytics_detection_with_subset_txt/data.yaml diff --git a/tests/assets/yolo_dataset/yolov8_detection_with_subset_txt/images/train/1.jpg b/tests/assets/yolo_dataset/yolo_ultralytics_detection_with_subset_txt/images/train/1.jpg similarity index 100% rename from tests/assets/yolo_dataset/yolov8_detection_with_subset_txt/images/train/1.jpg rename to tests/assets/yolo_dataset/yolo_ultralytics_detection_with_subset_txt/images/train/1.jpg diff --git a/tests/assets/yolo_dataset/yolov8_detection_with_subset_txt/labels/train/1.txt b/tests/assets/yolo_dataset/yolo_ultralytics_detection_with_subset_txt/labels/train/1.txt similarity index 100% rename from tests/assets/yolo_dataset/yolov8_detection_with_subset_txt/labels/train/1.txt rename to tests/assets/yolo_dataset/yolo_ultralytics_detection_with_subset_txt/labels/train/1.txt diff --git a/tests/assets/yolo_dataset/yolov8_detection_with_subset_txt/train.txt b/tests/assets/yolo_dataset/yolo_ultralytics_detection_with_subset_txt/train.txt similarity index 100% rename from tests/assets/yolo_dataset/yolov8_detection_with_subset_txt/train.txt rename to tests/assets/yolo_dataset/yolo_ultralytics_detection_with_subset_txt/train.txt diff --git a/tests/assets/yolo_dataset/yolov8_oriented_boxes/data.yaml b/tests/assets/yolo_dataset/yolo_ultralytics_oriented_boxes/data.yaml similarity index 100% rename from tests/assets/yolo_dataset/yolov8_oriented_boxes/data.yaml rename to tests/assets/yolo_dataset/yolo_ultralytics_oriented_boxes/data.yaml diff --git a/tests/assets/yolo_dataset/yolov8_oriented_boxes/images/train/1.jpg b/tests/assets/yolo_dataset/yolo_ultralytics_oriented_boxes/images/train/1.jpg similarity index 100% rename from tests/assets/yolo_dataset/yolov8_oriented_boxes/images/train/1.jpg rename to tests/assets/yolo_dataset/yolo_ultralytics_oriented_boxes/images/train/1.jpg diff --git a/tests/assets/yolo_dataset/yolov8_oriented_boxes/labels/train/1.txt b/tests/assets/yolo_dataset/yolo_ultralytics_oriented_boxes/labels/train/1.txt similarity index 100% rename from tests/assets/yolo_dataset/yolov8_oriented_boxes/labels/train/1.txt rename to tests/assets/yolo_dataset/yolo_ultralytics_oriented_boxes/labels/train/1.txt diff --git a/tests/assets/yolo_dataset/yolov8_pose/data.yaml b/tests/assets/yolo_dataset/yolo_ultralytics_pose/data.yaml similarity index 100% rename from tests/assets/yolo_dataset/yolov8_pose/data.yaml rename to tests/assets/yolo_dataset/yolo_ultralytics_pose/data.yaml diff --git a/tests/assets/yolo_dataset/yolov8_pose/images/train/1.jpg b/tests/assets/yolo_dataset/yolo_ultralytics_pose/images/train/1.jpg similarity index 100% rename from tests/assets/yolo_dataset/yolov8_pose/images/train/1.jpg rename to tests/assets/yolo_dataset/yolo_ultralytics_pose/images/train/1.jpg diff --git a/tests/assets/yolo_dataset/yolov8_pose/labels/train/1.txt b/tests/assets/yolo_dataset/yolo_ultralytics_pose/labels/train/1.txt similarity index 100% rename from tests/assets/yolo_dataset/yolov8_pose/labels/train/1.txt rename to tests/assets/yolo_dataset/yolo_ultralytics_pose/labels/train/1.txt diff --git a/tests/assets/yolo_dataset/yolov8_pose_two_values_per_point/data.yaml b/tests/assets/yolo_dataset/yolo_ultralytics_pose_two_values_per_point/data.yaml similarity index 100% rename from tests/assets/yolo_dataset/yolov8_pose_two_values_per_point/data.yaml rename to tests/assets/yolo_dataset/yolo_ultralytics_pose_two_values_per_point/data.yaml diff --git a/tests/assets/yolo_dataset/yolov8_pose_two_values_per_point/images/train/1.jpg b/tests/assets/yolo_dataset/yolo_ultralytics_pose_two_values_per_point/images/train/1.jpg similarity index 100% rename from tests/assets/yolo_dataset/yolov8_pose_two_values_per_point/images/train/1.jpg rename to tests/assets/yolo_dataset/yolo_ultralytics_pose_two_values_per_point/images/train/1.jpg diff --git a/tests/assets/yolo_dataset/yolov8_pose_two_values_per_point/labels/train/1.txt b/tests/assets/yolo_dataset/yolo_ultralytics_pose_two_values_per_point/labels/train/1.txt similarity index 100% rename from tests/assets/yolo_dataset/yolov8_pose_two_values_per_point/labels/train/1.txt rename to tests/assets/yolo_dataset/yolo_ultralytics_pose_two_values_per_point/labels/train/1.txt diff --git a/tests/assets/yolo_dataset/yolov8_segmentation/data.yaml b/tests/assets/yolo_dataset/yolo_ultralytics_segmentation/data.yaml similarity index 100% rename from tests/assets/yolo_dataset/yolov8_segmentation/data.yaml rename to tests/assets/yolo_dataset/yolo_ultralytics_segmentation/data.yaml diff --git a/tests/assets/yolo_dataset/yolov8_segmentation/images/train/1.jpg b/tests/assets/yolo_dataset/yolo_ultralytics_segmentation/images/train/1.jpg similarity index 100% rename from tests/assets/yolo_dataset/yolov8_segmentation/images/train/1.jpg rename to tests/assets/yolo_dataset/yolo_ultralytics_segmentation/images/train/1.jpg diff --git a/tests/assets/yolo_dataset/yolov8_segmentation/labels/train/1.txt b/tests/assets/yolo_dataset/yolo_ultralytics_segmentation/labels/train/1.txt similarity index 100% rename from tests/assets/yolo_dataset/yolov8_segmentation/labels/train/1.txt rename to tests/assets/yolo_dataset/yolo_ultralytics_segmentation/labels/train/1.txt diff --git a/tests/integration/cli/test_yolo_format.py b/tests/integration/cli/test_yolo_format.py index c80ca1ed34..751b7a8593 100644 --- a/tests/integration/cli/test_yolo_format.py +++ b/tests/integration/cli/test_yolo_format.py @@ -220,6 +220,6 @@ def test_can_delete_labels_from_yolo_dataset(self): compare_datasets(self, target_dataset, parsed_dataset) -class YOLOv8IntegrationScenarios(YoloIntegrationScenarios): - ASSET_PATH = ["yolo_dataset", "yolov8_detection"] - FORMAT_NAME = "yolov8_detection" +class YoloUltralyticsIntegrationScenarios(YoloIntegrationScenarios): + ASSET_PATH = ["yolo_dataset", "yolo_ultralytics_detection"] + FORMAT_NAME = "yolo_ultralytics_detection" diff --git a/tests/unit/data_formats/test_yolo_format.py b/tests/unit/data_formats/test_yolo_format.py index 99e1d29da0..58eb5bdeb1 100644 --- a/tests/unit/data_formats/test_yolo_format.py +++ b/tests/unit/data_formats/test_yolo_format.py @@ -41,27 +41,27 @@ from datumaro.components.media import Image from datumaro.plugins.yolo_format.converter import ( YoloConverter, - YOLOv8ClassificationConverter, - YOLOv8DetectionConverter, - YOLOv8OrientedBoxesConverter, - YOLOv8PoseConverter, - YOLOv8SegmentationConverter, + YoloUltralyticsClassificationConverter, + YoloUltralyticsDetectionConverter, + YoloUltralyticsOrientedBoxesConverter, + YoloUltralyticsPoseConverter, + YoloUltralyticsSegmentationConverter, ) from datumaro.plugins.yolo_format.extractor import ( YoloExtractor, - YOLOv8ClassificationExtractor, - YOLOv8DetectionExtractor, - YOLOv8OrientedBoxesExtractor, - YOLOv8PoseExtractor, - YOLOv8SegmentationExtractor, + YoloUltralyticsClassificationExtractor, + YoloUltralyticsDetectionExtractor, + YoloUltralyticsOrientedBoxesExtractor, + YoloUltralyticsPoseExtractor, + YoloUltralyticsSegmentationExtractor, ) from datumaro.plugins.yolo_format.importer import ( YoloImporter, - YOLOv8ClassificationImporter, - YOLOv8DetectionImporter, - YOLOv8OrientedBoxesImporter, - YOLOv8PoseImporter, - YOLOv8SegmentationImporter, + YoloUltralyticsClassificationImporter, + YoloUltralyticsDetectionImporter, + YoloUltralyticsOrientedBoxesImporter, + YoloUltralyticsPoseImporter, + YoloUltralyticsSegmentationImporter, ) from datumaro.util.image import save_image @@ -420,9 +420,9 @@ def test_export_rotated_bbox(self, test_dir): self.compare_datasets(expected_dataset, parsed_dataset) -class YOLOv8DetectionConverterTest(YoloConverterTest): - CONVERTER = YOLOv8DetectionConverter - IMPORTER = YOLOv8DetectionImporter +class YoloUltralyticsDetectionConverterTest(YoloConverterTest): + CONVERTER = YoloUltralyticsDetectionConverter + IMPORTER = YoloUltralyticsDetectionImporter @staticmethod def _make_image_path(test_dir: str, subset_name: str, image_id: str): @@ -571,9 +571,9 @@ def test_saves_only_parentless_labels(self, test_dir): self.compare_datasets(expected_dataset, parsed_dataset) -class YOLOv8SegmentationConverterTest(YOLOv8DetectionConverterTest): - CONVERTER = YOLOv8SegmentationConverter - IMPORTER = YOLOv8SegmentationImporter +class YoloUltralyticsSegmentationConverterTest(YoloUltralyticsDetectionConverterTest): + CONVERTER = YoloUltralyticsSegmentationConverter + IMPORTER = YoloUltralyticsSegmentationImporter def _generate_random_annotation(self, n_of_labels=10, label=None): return Polygon( @@ -586,9 +586,11 @@ def test_export_rotated_bbox(self, test_dir): pass -class YOLOv8OrientedBoxesConverterTest(CompareDatasetsRotationMixin, YOLOv8DetectionConverterTest): - CONVERTER = YOLOv8OrientedBoxesConverter - IMPORTER = YOLOv8OrientedBoxesImporter +class YoloUltralyticsOrientedBoxesConverterTest( + CompareDatasetsRotationMixin, YoloUltralyticsDetectionConverterTest +): + CONVERTER = YoloUltralyticsOrientedBoxesConverter + IMPORTER = YoloUltralyticsOrientedBoxesImporter def _generate_random_annotation(self, n_of_labels=10, label=None): return self._generate_random_bbox( @@ -616,9 +618,9 @@ def test_export_rotated_bbox(self, test_dir): self.compare_datasets(source_dataset, parsed_dataset) -class YOLOv8PoseConverterTest(YOLOv8DetectionConverterTest): - CONVERTER = YOLOv8PoseConverter - IMPORTER = YOLOv8PoseImporter +class YoloUltralyticsPoseConverterTest(YoloUltralyticsDetectionConverterTest): + CONVERTER = YoloUltralyticsPoseConverter + IMPORTER = YoloUltralyticsPoseImporter def _generate_random_skeleton_annotation(self, skeleton_label_to_point_labels, n_of_labels=10): label_id = random.choice(list(skeleton_label_to_point_labels.keys())) # nosec B311 NOSONAR @@ -906,9 +908,9 @@ def test_saves_only_parentless_labels(self, test_dir): self.compare_datasets(expected_dataset, parsed_dataset) -class YOLOv8ClassificationConverterTest(YoloConverterTest): - CONVERTER = YOLOv8ClassificationConverter - IMPORTER = YOLOv8ClassificationImporter +class YoloUltralyticsClassificationConverterTest(YoloConverterTest): + CONVERTER = YoloUltralyticsClassificationConverter + IMPORTER = YoloUltralyticsClassificationImporter @staticmethod def _make_image_path(test_dir: str, subset_name: str, image_id: str): @@ -1142,14 +1144,14 @@ def test_can_pickle(self, helper_tc): compare_datasets_strict(helper_tc, source, parsed) -class YOLOv8DetectionImporterTest(YoloImporterTest): - IMPORTER = YOLOv8DetectionImporter +class YoloUltralyticsDetectionImporterTest(YoloImporterTest): + IMPORTER = YoloUltralyticsDetectionImporter ASSETS = [ - "yolov8_detection", - "yolov8_detection_reversed_folders", - "yolov8_detection_with_list_of_imgs", - "yolov8_detection_with_subset_txt", - "yolov8_detection_with_list_of_names", + "yolo_ultralytics_detection", + "yolo_ultralytics_detection_reversed_folders", + "yolo_ultralytics_detection_with_list_of_imgs", + "yolo_ultralytics_detection_with_subset_txt", + "yolo_ultralytics_detection_with_list_of_names", ] def test_can_detect(self): @@ -1157,9 +1159,9 @@ def test_can_detect(self): dataset_dir = get_test_asset_path("yolo_dataset", asset) detected_formats = Environment().detect_dataset(dataset_dir) assert set(detected_formats) == { - YOLOv8DetectionImporter.NAME, - YOLOv8SegmentationImporter.NAME, - YOLOv8OrientedBoxesImporter.NAME, + YoloUltralyticsDetectionImporter.NAME, + YoloUltralyticsSegmentationImporter.NAME, + YoloUltralyticsOrientedBoxesImporter.NAME, } def test_can_detect_and_import_with_any_yaml_as_config(self, test_dir): @@ -1222,7 +1224,7 @@ def test_can_import_despite_multiple_yamls_if_config_file_provided_as_argument(s self.compare_datasets(expected_dataset, dataset) def test_can_import_if_names_dict_has_non_sequential_keys(self, test_dir): - if self.IMPORTER.NAME != YOLOv8DetectionImporter.NAME: + if self.IMPORTER.NAME != YoloUltralyticsDetectionImporter.NAME: return expected_dataset = Dataset.from_iterable( [ @@ -1241,7 +1243,9 @@ def test_can_import_if_names_dict_has_non_sequential_keys(self, test_dir): ) dataset_path = osp.join(test_dir, "dataset") - shutil.copytree(get_test_asset_path("yolo_dataset", "yolov8_detection"), dataset_path) + shutil.copytree( + get_test_asset_path("yolo_dataset", "yolo_ultralytics_detection"), dataset_path + ) with open(osp.join(dataset_path, "data.yaml"), "r+") as f: config = yaml.safe_load(f) @@ -1256,10 +1260,10 @@ def test_can_import_if_names_dict_has_non_sequential_keys(self, test_dir): self.compare_datasets(expected_dataset, dataset) -class YOLOv8SegmentationImporterTest(YOLOv8DetectionImporterTest): - IMPORTER = YOLOv8SegmentationImporter +class YoloUltralyticsSegmentationImporterTest(YoloUltralyticsDetectionImporterTest): + IMPORTER = YoloUltralyticsSegmentationImporter ASSETS = [ - "yolov8_segmentation", + "yolo_ultralytics_segmentation", ] @staticmethod @@ -1280,9 +1284,11 @@ def _asset_dataset(): ) -class YOLOv8OrientedBoxesImporterTest(CompareDatasetsRotationMixin, YOLOv8DetectionImporterTest): - IMPORTER = YOLOv8OrientedBoxesImporter - ASSETS = ["yolov8_oriented_boxes"] +class YoloUltralyticsOrientedBoxesImporterTest( + CompareDatasetsRotationMixin, YoloUltralyticsDetectionImporterTest +): + IMPORTER = YoloUltralyticsOrientedBoxesImporter + ASSETS = ["yolo_ultralytics_oriented_boxes"] @staticmethod def _asset_dataset(): @@ -1302,11 +1308,11 @@ def _asset_dataset(): ) -class YOLOv8PoseImporterTest(YOLOv8DetectionImporterTest): - IMPORTER = YOLOv8PoseImporter +class YoloUltralyticsPoseImporterTest(YoloUltralyticsDetectionImporterTest): + IMPORTER = YoloUltralyticsPoseImporter ASSETS = [ - "yolov8_pose", - "yolov8_pose_two_values_per_point", + "yolo_ultralytics_pose", + "yolo_ultralytics_pose_two_values_per_point", ] def test_can_detect(self): @@ -1361,12 +1367,12 @@ def _asset_dataset(): ) -class YOLOv8ClassificationImporterTest(YoloImporterTest): - IMPORTER = YOLOv8ClassificationImporter - ASSETS = ["yolov8_classification"] +class YoloUltralyticsClassificationImporterTest(YoloImporterTest): + IMPORTER = YoloUltralyticsClassificationImporter + ASSETS = ["yolo_ultralytics_classification"] def test_can_detect(self): - dataset_dir = get_test_asset_path("yolo_dataset", "yolov8_classification") + dataset_dir = get_test_asset_path("yolo_dataset", "yolo_ultralytics_classification") detected_formats = Environment().detect_dataset(dataset_dir) assert self.IMPORTER.NAME in detected_formats @@ -1411,7 +1417,9 @@ def test_can_import_with_exif_rotated_images(self, test_dir): ) dataset_path = osp.join(test_dir, "dataset") - shutil.copytree(get_test_asset_path("yolo_dataset", "yolov8_classification"), dataset_path) + shutil.copytree( + get_test_asset_path("yolo_dataset", "yolo_ultralytics_classification"), dataset_path + ) shutil.rmtree(osp.join(dataset_path, "train", "label_0")) # Add exif rotation for image @@ -1552,9 +1560,9 @@ def test_can_report_missing_subset_info(self, test_dir): Dataset.import_from(test_dir, self.IMPORTER.NAME).init_cache() -class YOLOv8DetectionExtractorTest(YoloExtractorTest): - IMPORTER = YOLOv8DetectionImporter - EXTRACTOR = YOLOv8DetectionExtractor +class YoloUltralyticsDetectionExtractorTest(YoloExtractorTest): + IMPORTER = YoloUltralyticsDetectionImporter + EXTRACTOR = YoloUltralyticsDetectionExtractor @staticmethod def _get_annotation_dir(subset="train"): @@ -1574,7 +1582,7 @@ def test_can_report_missing_subset_folder(self, test_dir): Dataset.import_from(dataset_path, self.IMPORTER.NAME).init_cache() def test_can_report_missing_ann_file(self, test_dir): - # YOLOv8 does not require annotation files + # YoloUltralytics does not require annotation files # This empty test is needed to not run the test with the same name from the parent class pass @@ -1587,9 +1595,9 @@ def test_can_import_with_missing_ann_file(self, test_dir, helper_tc): compare_datasets(helper_tc, source_dataset, actual) -class YOLOv8SegmentationExtractorTest(YOLOv8DetectionExtractorTest): - IMPORTER = YOLOv8SegmentationImporter - EXTRACTOR = YOLOv8SegmentationExtractor +class YoloUltralyticsSegmentationExtractorTest(YoloUltralyticsDetectionExtractorTest): + IMPORTER = YoloUltralyticsSegmentationImporter + EXTRACTOR = YoloUltralyticsSegmentationExtractor def _prepare_dataset(self, path: str, anno=None) -> Dataset: return super()._prepare_dataset( @@ -1616,9 +1624,9 @@ def test_can_report_invalid_field_type(self, field, field_name, test_dir): self._check_can_report_invalid_field_type(field, field_name, test_dir) -class YOLOv8OrientedBoxesExtractorTest(YOLOv8DetectionExtractorTest): - IMPORTER = YOLOv8OrientedBoxesImporter - EXTRACTOR = YOLOv8OrientedBoxesExtractor +class YoloUltralyticsOrientedBoxesExtractorTest(YoloUltralyticsDetectionExtractorTest): + IMPORTER = YoloUltralyticsOrientedBoxesImporter + EXTRACTOR = YoloUltralyticsOrientedBoxesExtractor def _prepare_dataset(self, path: str, anno=None) -> Dataset: return super()._prepare_dataset( @@ -1652,9 +1660,9 @@ def test_can_report_invalid_field_type(self, field, field_name, test_dir): self._check_can_report_invalid_field_type(field, field_name, test_dir) -class YOLOv8PoseExtractorTest(YOLOv8DetectionExtractorTest): - IMPORTER = YOLOv8PoseImporter - EXTRACTOR = YOLOv8PoseExtractor +class YoloUltralyticsPoseExtractorTest(YoloUltralyticsDetectionExtractorTest): + IMPORTER = YoloUltralyticsPoseImporter + EXTRACTOR = YoloUltralyticsPoseExtractor def _prepare_dataset(self, path: str, anno=None) -> Dataset: dataset = Dataset.from_iterable( @@ -1848,7 +1856,7 @@ def test_can_import_if_sub_label_hint_has_extra_skeletons(self, test_dir, helper compare_datasets(helper_tc, source_dataset, parsed_dataset) -class YOLOv8ClassificationExtractorTest: +class YoloUltralyticsClassificationExtractorTest: @mark_requirement(Requirements.DATUM_GENERAL_REQ) def test_can_parse(self, helper_tc, test_dir): expected = Dataset.from_iterable( @@ -1862,6 +1870,6 @@ def test_can_parse(self, helper_tc, test_dir): ], categories=["test_label"], ) - expected.export(test_dir, YOLOv8ClassificationExtractor.NAME, save_media=True) - actual = Dataset.import_from(test_dir, YOLOv8ClassificationImporter.NAME) + expected.export(test_dir, YoloUltralyticsClassificationExtractor.NAME, save_media=True) + actual = Dataset.import_from(test_dir, YoloUltralyticsClassificationImporter.NAME) compare_datasets(helper_tc, expected, actual)