
    ^jH                    L   d dl mZ d dlZd dlmZmZ d dlmZ d dlm	Z	 d dl
mZ d dlmZ d dlZd dlZd dlmZ d dlmZ d d	lmZ d d
lmZmZ d dlmZmZ d dlmZm Z m!Z! d dl"m#Z#m$Z$m%Z%m&Z&m'Z' d dl(m)Z) d dl*m+Z+ d dl,m-Z-  G d de      Z. G d de.      Z/e	 G d de.             Z0y)    )annotationsN)ABCabstractmethod)Iterator)	dataclass)chain)Path)Classifications)CLASS_NAME_DATA_FIELD)load_coco_annotationssave_coco_annotations)detections_to_pascal_vocload_pascal_voc_annotations)load_yolo_annotationssave_data_yamlsave_yolo_annotations)build_class_index_mappingmap_detections_class_idmerge_class_listssave_dataset_imagestrain_test_split)
Detections)warn_deprecated)find_duplicatesc                  F    e Zd Zedd       Ze	 	 	 d	 	 	 	 	 	 	 dd       Zy)BaseDatasetc                     y N selfs    c/var/www/ramen.bs-engineer-server.com/venv/lib/python3.12/site-packages/supervision/dataset/core.py__len__zBaseDataset.__len__*   s        Nc                     y r   r   )r!   split_ratiorandom_stateshuffles       r"   splitzBaseDataset.split.   s     	r$   returnintg?NT)r&   floatr'   
int | Noner(   boolr+   ztuple[BaseDataset, BaseDataset])__name__
__module____qualname__r   r#   r)   r   r$   r"   r   r   )   sY       !#'	 ! 	
 
) r$   r   c                     e Zd ZdZ	 	 	 	 	 	 	 	 ddZddZddZddZddZddZ		 	 	 d	 	 	 	 	 	 	 dd	Z
edd
       Z	 	 	 	 	 d	 	 	 	 	 	 	 	 	 	 	 ddZe	 d	 	 	 	 	 	 	 dd       Ze	 	 d	 	 	 	 	 	 	 	 	 	 	 dd       Z	 	 	 	 	 	 	 d 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d!dZe	 d	 	 	 	 	 	 	 d"d       Z	 	 	 	 	 	 	 d#	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d$dZy)%DetectionDataseta  
    Contains information about a detection dataset. Handles lazy image loading
    and annotation retrieval, dataset splitting, conversions into multiple
    formats.

    Attributes:
        classes: List containing dataset class names.
        images:
            Accepts a list of image paths, or dictionaries of loaded cv2 images
            with paths as keys. If you pass a list of paths, the dataset will
            lazily load images on demand, which is much more memory-efficient.
        annotations: Dictionary mapping
            image path to annotations. The dictionary keys match
            match the keys in `images` or entries in the list of
            image paths.
    c                   || _         t        |      t        |      k7  rt        d      || _        | j                   rkt	        j
                  | j                         }| j                  j                         D ]/  }|j                  ||j                     |j                  t        <   1 t        t        j                  |            | _        i | _        y )N?The keys of the images and annotations dictionaries must match.)classesset
ValueErrorr   nparrayvaluesclass_iddatar   listdictfromkeysimage_paths_images_in_memory)r!   r8   imagesr   
np_classes
annotations         r"   __init__zDetectionDataset.__init__J   s     v;#k**Q  '<<$,,/J"..557 
&&2=G"++>JOO$9:  f 56CEr$   c                    | j                   r| j                   |   S t        j                  |      }|t        d|       |S z!Assumes that image is in dataset.z Could not read image from path: rD   cv2imreadr:   r!   
image_pathimages      r"   
_get_imagezDetectionDataset._get_imagee   G    !!))*55

:&=?
|LMMr$   c                Z    t        | j                        xs t        | j                        S r   lenrD   rC   r    s    r"   r#   zDetectionDataset.__len__n   #    4))*Cc$2B2B.CCr$   c                j    | j                   |   }| j                  |      }| j                  |   }|||fS z
        Returns:
            The image path, image data,
                and its corresponding annotation at index i.
        rC   rQ   r   r!   irO   rP   rG   s        r"   __getitem__zDetectionDataset.__getitem__q   ?     %%a(

+%%j1
5*,,r$   c              #  ^   K   t        t        |             D ]  }| |   \  }}}|||f  ywz
        Iterate over the images and annotations in the dataset.

        Yields:
            Tuples containing the image path, image data, and its annotation.
        NrangerU   rZ   s        r"   __iter__zDetectionDataset.__iter__|   s=      s4y! 	0A,0G)JzeZ//	0   +-c                   t        |t              syt        | j                        t        |j                        k7  ry| j                  |j                  k7  ry| j
                  s|j
                  rYt        j                  t        | j
                  j                               t        |j
                  j                                     sy| j                  |j                  k7  ryyNFT)
isinstancer5   r9   r8   rC   rD   r;   array_equalr@   r=   r   r!   others     r"   __eq__zDetectionDataset.__eq__   s    %!12t||EMM 22u000!!U%<%<>>T++2245U,,3356 u000r$   Nc                   t        | j                  |||      \  }}| j                  r;|D ci c]  }|| j                  |    }}|D ci c]  }|| j                  |    }}n|}|}|D ci c]  }|| j                  |    }	}|D ci c]  }|| j                  |    }
}t	        | j
                  ||	      }t	        | j
                  ||
      }||fS c c}w c c}w c c}w c c}w )a0  
        Splits the dataset into two parts (training and testing)
            using the provided split_ratio.

        Args:
            split_ratio: The ratio of the training
                set to the entire dataset.
            random_state: The seed for the random number generator.
                This is used for reproducibility.
            shuffle: Whether to shuffle the data before splitting.

        Returns:
            A tuple containing
                the training and testing datasets.

        Examples:
            ```pycon
            >>> import numpy as np
            >>> import supervision as sv
            >>> ds = sv.DetectionDataset(
            ...     classes=['dog', 'person'],
            ...     images={
            ...         'img1.jpg': np.zeros((100, 100, 3), dtype=np.uint8),
            ...         'img2.jpg': np.zeros((100, 100, 3), dtype=np.uint8),
            ...     },
            ...     annotations={
            ...         'img1.jpg': sv.Detections(xyxy=np.array([[10, 10, 20, 20]])),
            ...         'img2.jpg': sv.Detections(xyxy=np.array([[30, 30, 40, 40]])),
            ...     }
            ... )
            >>> train_ds, test_ds = ds.split(split_ratio=0.5, random_state=42)
            >>> len(train_ds), len(test_ds)
            (1, 1)

            ```
        r?   train_ratior'   r(   r8   rE   r   )r   rC   rD   r   r5   r8   r!   r&   r'   r(   train_paths
test_pathspathtrain_input
test_inputtrain_annotationstest_annotationstrain_datasettest_datasets                r"   r)   zDetectionDataset.split   s   V #3!!#%	#
Z !!JUV$4!7!7!==VKVIST$ 6 6t <<TJT%K#JFQRdT4#3#3D#99RREOPTD$"2"24"88PP(LL)

 (LL(

 l**% WT SP   C
C,C 	C%c                2   dd}dd}t        |D cg c]
  } ||       c}      }t        |D cg c]
  } ||       c}      }|s|st        d      i }|D ]  }|j                  |j                          t	        t        j                  d |D                    }t	        t        j                  |            }	t        |      t        |	      k7  rt        |      }
t        d|
 d      |	}t        |D cg c]  }|j                   c}      }i }|D ]  } |j                  |j                           |D ]=  }t        |j                  |      }|j                  D ]  }t!        |||   	      ||<    ?  | ||xs ||
      S c c}w c c}w c c}w )a  
        Merge a list of `DetectionDataset` objects into a single
            `DetectionDataset` object.

        This method takes a list of `DetectionDataset` objects and combines
        their respective fields (`classes`, `images`,
        `annotations`) into a single `DetectionDataset` object.

        Args:
            dataset_list: A list of `DetectionDataset`
                objects to merge.

        Returns:
            A single `DetectionDataset` object containing
            the merged data from the input list.

        Examples:
            ```pycon
            >>> import numpy as np
            >>> import supervision as sv
            >>> ds_1 = sv.DetectionDataset(
            ...     classes=['dog', 'person'],
            ...     images={'img1.jpg': np.zeros((100, 100, 3), dtype=np.uint8)},
            ...     annotations={'img1.jpg': sv.Detections.empty()}
            ... )
            >>> len(ds_1)
            1
            >>> ds_1.classes
            ['dog', 'person']
            >>> ds_2 = sv.DetectionDataset(
            ...     classes=['cat'],
            ...     images={'img2.jpg': np.zeros((100, 100, 3), dtype=np.uint8)},
            ...     annotations={'img2.jpg': sv.Detections.empty()}
            ... )
            >>> len(ds_2)
            1
            >>> ds_2.classes
            ['cat']
            >>> ds_merged = sv.DetectionDataset.merge([ds_1, ds_2])
            >>> len(ds_merged)
            2
            >>> ds_merged.classes
            ['cat', 'dog', 'person']

            ```
        c                f    t        | j                        dkD  xs t        | j                        dk(  S Nr   rT   datasets    r"   is_in_memoryz,DetectionDataset.merge.<locals>.is_in_memory  s.    w001A5VW=P=P9QUV9VVr$   c                2    t        | j                        dk(  S r|   )rU   rD   r}   s    r"   is_lazyz'DetectionDataset.merge.<locals>.is_lazy  s    w001Q66r$   z>Merging lazy and in-memory DetectionDatasets is not supported.c              3  4   K   | ]  }|j                     y wr   )rC   ).0r~   s     r"   	<genexpr>z)DetectionDataset.merge.<locals>.<genexpr>)  s     P 3 3Ps   zImage paths z  are not unique across datasets.)class_lists)source_classestarget_classes)source_to_target_mapping
detectionsrn   )r~   r5   r+   r0   )allr:   updaterD   r@   r   from_iterablerA   rB   rU   r   r   r8   r   r   rC   r   )clsdataset_listr   r   r~   all_in_memoryall_lazyimages_in_memoryrC   image_paths_unique
duplicatesr8   r   class_index_mappingrO   s                  r"   mergezDetectionDataset.merge   s   b	W	7 ,Ow\'2OPEW(EFXP  # 	?G##G$=$=>	? P<PP
 "$--"<={s#566(5Jzl*JK  )#8DEWE
 # 	4GKw223	4# 	G";&w# &11 
*A-@*:6+J'		 #2{#
 	
O PE, Fs   F
F9Fc           
        |rt        | |       |rt        |      j                  dd       | D ]  \  }}}t        |      j                  }	t        j
                  j                  ||	 d      }
t        |      j                  }t        || j                  ||j                  |||      }t        |
d      5 }|j                  |       ddd        yy# 1 sw Y   xY w)a  
        Exports the dataset to PASCAL VOC format. This method saves the images
        and their corresponding annotations in PASCAL VOC format.

        Args:
            images_directory_path: The path to the directory
                where the images should be saved.
                If not provided, images will not be saved.
            annotations_directory_path: The path to
                the directory where the annotations in PASCAL VOC format should be
                saved. If not provided, annotations will not be saved.
            min_image_area_percentage: The minimum percentage of
                detection area relative to
                the image area for a detection to be included.
                Argument is used only for segmentation datasets.
            max_image_area_percentage: The maximum percentage
                of detection area relative to
                the image area for a detection to be included.
                Argument is used only for segmentation datasets.
            approximation_percentage: The percentage of
                polygon points to be removed from the input polygon,
                in the range [0, 1). Argument is used only for segmentation datasets.
        r~   images_directory_pathT)parentsexist_okz.xml)r   r8   filenameimage_shapemin_image_area_percentagemax_image_area_percentageapproximation_percentagewN)r   r	   mkdirstemosrr   joinnamer   r8   shapeopenwrite)r!   r   annotations_directory_pathr   r   r   rO   rP   r   annotation_nameannotations_path
image_namepascal_voc_xmlfs                 r"   as_pascal_voczDetectionDataset.as_pascal_vocJ  s    > !&; &+,224$2O26 ,.
E;"&z"2"7"7#%77<<.?2C40H$  "*-22
!9* LL' %.G.G-E" *C0 ,AGGN+, ,!, &$, ,s   6CC	c                B    t        |||      \  }}}t        |||      S )a  
        Creates a Dataset instance from PASCAL VOC formatted data.

        Args:
            images_directory_path: Path to the directory containing the images.
            annotations_directory_path: Path to the directory
                containing the PASCAL VOC XML annotations.
            force_masks: If True, forces masks to
                be loaded for all annotations, regardless of whether they are present.

        Returns:
            A DetectionDataset instance containing
                the loaded images and annotations.

        Examples:
            ```python
            import roboflow
            from roboflow import Roboflow
            import supervision as sv

            roboflow.login()

            rf = Roboflow()

            project = rf.workspace(WORKSPACE_ID).project(PROJECT_ID)
            dataset = project.version(PROJECT_VERSION).download("voc")

            ds = sv.DetectionDataset.from_pascal_voc(
                images_directory_path=f"{dataset.location}/train/images",
                annotations_directory_path=f"{dataset.location}/train/labels"
            )

            ds.classes
            # ['dog', 'person']
            ```
        )r   r   force_masksrn   )r   r5   )r   r   r   r   r8   rC   r   s          r"   from_pascal_vocz DetectionDataset.from_pascal_voc  s6    X -H"7'A#-
)k  K[
 	
r$   c                F    t        |||||      \  }}}t        |||      S )a6  
        Creates a Dataset instance from YOLO formatted data.

        Args:
            images_directory_path: The path to the
                directory containing the images.
            annotations_directory_path: The path to the directory
                containing the YOLO annotation files.
            data_yaml_path: The path to the data
                YAML file containing class information.
            force_masks: If True, forces
                masks to be loaded for all annotations,
                regardless of whether they are present.
            is_obb: 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:
            A DetectionDataset instance
                containing the loaded images and annotations.

        Examples:
            ```python
            import roboflow
            from roboflow import Roboflow
            import supervision as sv

            roboflow.login()
            rf = Roboflow()

            project = rf.workspace(WORKSPACE_ID).project(PROJECT_ID)
            dataset = project.version(PROJECT_VERSION).download("yolov5")

            ds = sv.DetectionDataset.from_yolo(
                images_directory_path=f"{dataset.location}/train/images",
                annotations_directory_path=f"{dataset.location}/train/labels",
                data_yaml_path=f"{dataset.location}/data.yaml"
            )

            ds.classes
            # ['dog', 'person']
            ```
        )r   r   data_yaml_pathr   is_obbrn   )r   r5   )	r   r   r   r   r   r   r8   rC   r   s	            r"   	from_yolozDetectionDataset.from_yolo  s<    h -B"7'A)#-
)k  K[
 	
r$   c                    |r+|dk7  s
|dk7  s|dk7  rddl }|j                  dt        d       |t        | |       |t	        | |||||	       |t        || j                  
       yy)a  
        Exports the dataset to YOLO format. This method saves the
        images and their corresponding annotations in YOLO format.

        Args:
            images_directory_path: The path to the
                directory where the images should be saved.
                If not provided, images will not be saved.
            annotations_directory_path: The path to the
                directory where the annotations in
                YOLO format should be saved. If not provided,
                annotations will not be saved.
            data_yaml_path: The path where the data.yaml
                file should be saved.
                If not provided, the file will not be saved.
            min_image_area_percentage: The minimum percentage of
                detection area relative to
                the image area for a detection to be included.
                Argument is used only for segmentation datasets.
            max_image_area_percentage: The maximum percentage
                of detection area relative to
                the image area for a detection to be included.
                Argument is used only for segmentation datasets.
            approximation_percentage: The percentage of polygon points to
                be removed from the input polygon, in the range [0, 1).
                This is useful for simplifying the annotations.
                Argument is used only for segmentation datasets.
            is_obb: If True, exports annotations in OBB format
                (`class_id x1 y1 x2 y2 x3 y3 x4 y4`) using the oriented
                corners stored in `detections.data["xyxyxyxy"]`. Mirrors
                `from_yolo(..., is_obb=True)`. Masks are ignored when
                `is_obb=True`.
                      ?r   Nz`min_image_area_percentage`, `max_image_area_percentage`, and `approximation_percentage` have no effect when `is_obb=True`; OBB annotations use corner coordinates directly.   )
stacklevelr   )r~   r   r   r   r   r   )r   r8   )warningswarnUserWarningr   r   r   r8   )	r!   r   r   r   r   r   r   r   r   s	            r"   as_yolozDetectionDataset.as_yolo  s    V %,(C/'3.MMC    !,4I &1!+E*C*C)A %.$,,O &r$   c                B    t        |||      \  }}}t        |||      S )a  
        Creates a Dataset instance from COCO formatted data.

        Args:
            images_directory_path: The path to the
                directory containing the images.
            annotations_path: The path to the json annotation files.
            force_masks: If True,
                forces masks to be loaded for all annotations,
                regardless of whether they are present.
        Returns:
            A DetectionDataset instance containing
                the loaded images and annotations.

        Examples:
            ```python
            import roboflow
            from roboflow import Roboflow
            import supervision as sv

            roboflow.login()
            rf = Roboflow()

            project = rf.workspace(WORKSPACE_ID).project(PROJECT_ID)
            dataset = project.version(PROJECT_VERSION).download("coco")

            ds = sv.DetectionDataset.from_coco(
                images_directory_path=f"{dataset.location}/train",
                annotations_path=f"{dataset.location}/train/_annotations.coco.json",
            )

            ds.classes
            # ['dog', 'person']
            ```
        )r   r   r   rn   )r   r5   )r   r   r   r   r8   rE   r   s          r"   	from_cocozDetectionDataset.from_cocoA  s0    T (="7-#(
$
  KXXr$   c           	     P    |t        | |       |t        | ||||||      S ||fS )u  
        Exports the dataset to COCO format. This method saves the
        images and their corresponding annotations in COCO format.

        !!! tip

            The format of the mask is determined automatically based on its structure:

            - If a mask contains multiple disconnected components or holes, it will be
            saved using the Run-Length Encoding (RLE) format for efficient storage and
            processing.
            - If a mask consists of a single, contiguous region without any holes, it
            will be encoded as a polygon, preserving the outline of the object.

            This automatic selection ensures that the masks are stored in the most
            appropriate and space-efficient format, complying with COCO dataset
            standards.

        Args:
            images_directory_path: The path to the directory
                where the images should be saved.
                If not provided, images will not be saved.
            annotations_path: The path to COCO annotation file.
            min_image_area_percentage: The minimum percentage of
                detection area relative to
                the image area for a detection to be included.
                Argument is used only for segmentation datasets.
            max_image_area_percentage: The maximum percentage of
                detection area relative to
                the image area for a detection to be included.
                Argument is used only for segmentation datasets.
            approximation_percentage: The percentage of polygon points
                to be removed from the input polygon,
                in the range [0, 1). This is useful for simplifying the annotations.
                Argument is used only for segmentation datasets.
            starting_image_id: First image id to assign in the exported file.
                Defaults to ``1``. Override when exporting multiple splits into
                a coordinated COCO collection so ids remain unique across the
                set (see example below).
            starting_annotation_id: First annotation id to assign in the
                exported file. Defaults to ``1``. Override for the same
                multi-split reason as ``starting_image_id``.

        Returns:
            A ``(next_image_id, next_annotation_id)`` tuple containing the
            first unused ids after this export. Feed them straight back into
            ``starting_image_id`` and ``starting_annotation_id`` on the next
            split so ids stay globally unique. When ``annotations_path`` is
            ``None`` (images-only export) the starting ids are returned
            unchanged so chaining still composes.

        Example:
            ```python
            # Exporting train, valid, and test splits with non-colliding ids
            # so the three annotation files can later be merged into one COCO.
            next_image_id, next_annotation_id = train_ds.as_coco(
                images_directory_path="out/train/images",
                annotations_path="out/train/annotations.json",
            )
            next_image_id, next_annotation_id = valid_ds.as_coco(
                images_directory_path="out/valid/images",
                annotations_path="out/valid/annotations.json",
                starting_image_id=next_image_id,
                starting_annotation_id=next_annotation_id,
            )
            _, _ = test_ds.as_coco(
                images_directory_path="out/test/images",
                annotations_path="out/test/annotations.json",
                starting_image_id=next_image_id,
                starting_annotation_id=next_annotation_id,
            )  # return value not needed — no further split
            ```
        r   )r~   annotation_pathr   r   r   starting_image_idstarting_annotation_id)r   r   )r!   r   r   r   r   r   r   r   s           r"   as_cocozDetectionDataset.as_cocor  sQ    f !,4I '( 0*C*C)A"3'=  !"888r$   )r8   	list[str]rE   ,list[str] | dict[str, npt.NDArray[np.uint8]]r   zdict[str, Detections]r+   NonerO   strr+   znpt.NDArray[np.uint8]r*   )r[   r,   r+   z-tuple[str, npt.NDArray[np.uint8], Detections])r+   z7Iterator[tuple[str, npt.NDArray[np.uint8], Detections]]ri   objectr+   r0   r-   )r&   r.   r'   r/   r(   r0   r+   z)tuple[DetectionDataset, DetectionDataset])r   zlist[DetectionDataset]r+   r5   )NNr   r   r   )r   
str | Noner   r   r   r.   r   r.   r   r.   r+   r   )F)r   r   r   r   r   r0   r+   r5   )FF)r   r   r   r   r   r   r   r0   r   r0   r+   r5   )NNNr   r   r   F)r   r   r   r   r   r   r   r.   r   r.   r   r.   r   r0   r+   r   )r   r   r   r   r   r0   r+   r5   )NNr   r   r      r   )r   r   r   r   r   r.   r   r.   r   r.   r   r,   r   r,   r+   ztuple[int, int])r1   r2   r3   __doc__rH   rQ   r#   r\   rb   rj   r)   classmethodr   r   r   r   r   r   r   r   r$   r"   r5   r5   8   s   "FF =F +	F
 
F6D	-	00 !#'	G+G+ !G+ 	G+
 
3G+R a
 a
J -115+.+.*-7,)7, %/7, $)	7,
 $)7, #(7, 
7,r 
 "	3
"3
 %(3
 	3

 
3
 3
j  "<
"<
 %(<
 	<

 <
 <
 
<
 <
@ -115%)+.+.*-GP)GP %/GP #	GP
 $)GP $)GP #(GP GP 
GPR 
 "	.Y".Y .Y 	.Y
 
.Y .Yd -1'++.+.*-!"&'a9)a9 %a9 $)	a9
 $)a9 #(a9 a9 !$a9 
a9r$   r5   c                      e Zd ZdZ	 	 	 	 	 	 	 	 ddZddZddZddZ	 	 ddZddZ		 	 	 d	 	 	 	 	 	 	 dd	Z
dd
Zedd       Zy)ClassificationDatasetag  
    Contains information about a classification dataset, handles lazy image
    loading, dataset splitting.

    Attributes:
        classes: List containing dataset class names.
        images:
            List of image paths or dictionary mapping image name to image data.
        annotations: Dictionary mapping
            image name to annotations.
    c                    || _         t        |      t        |      k7  rt        d      || _        t	        t
        j                  |            | _        i | _        t        |t
              r|| _        t        d       y y )Nr7   zPassing a `Dict[str, np.ndarray]` into `ClassificationDataset` is deprecated and will be removed in a future release. Use a list of paths `List[str]` instead.)r8   r9   r:   r   r@   rA   rB   rC   rD   rf   r   )r!   r8   rE   r   s       r"   rH   zClassificationDataset.__init__  sz     v;#k**Q  '  f 56CEfd#%+D"7 $r$   c                    | j                   r| j                   |   S t        j                  |      }|t        d|       |S rJ   rK   rN   s      r"   rQ   z ClassificationDataset._get_image  rR   r$   c                Z    t        | j                        xs t        | j                        S r   rT   r    s    r"   r#   zClassificationDataset.__len__  rV   r$   c                j    | j                   |   }| j                  |      }| j                  |   }|||fS rX   rY   rZ   s        r"   r\   z!ClassificationDataset.__getitem__
  r]   r$   c              #  ^   K   t        t        |             D ]  }| |   \  }}}|||f  ywr_   r`   rZ   s        r"   rb   zClassificationDataset.__iter__  s=      s4y! 	0A,0G)JzeZ//	0rc   c                   t        |t              syt        | j                        t        |j                        k7  ry| j                  |j                  k7  ry| j
                  s|j
                  rYt        j                  t        | j
                  j                               t        |j
                  j                                     sy| j                  |j                  k7  ryyre   )rf   r   r9   r8   rC   rD   r;   rg   r@   r=   r   rh   s     r"   rj   zClassificationDataset.__eq__"  s    %!67t||EMM 22u000!!U%<%<>>T++2245U,,3356 u000r$   Nc                   t        | j                  |||      \  }}| j                  r;|D ci c]  }|| j                  |    }}|D ci c]  }|| j                  |    }}n|}|}|D ci c]  }|| j                  |    }	}|D ci c]  }|| j                  |    }
}t	        | j
                  ||	      }t	        | j
                  ||
      }||fS c c}w c c}w c c}w c c}w )a"  
        Splits the dataset into two parts (training and testing)
            using the provided split_ratio.

        Args:
            split_ratio: The ratio of the training
                set to the entire dataset.
            random_state: The seed for the
                random number generator. This is used for reproducibility.
            shuffle: Whether to shuffle the data before splitting.

        Returns:
            A tuple containing
            the training and testing datasets.

        Examples:
            ```pycon
            >>> import numpy as np
            >>> import supervision as sv
            >>> cd = sv.ClassificationDataset(
            ...     classes=['cat', 'dog'],
            ...     images={
            ...         'img1.jpg': np.zeros((100, 100, 3), dtype=np.uint8),
            ...         'img2.jpg': np.zeros((100, 100, 3), dtype=np.uint8),
            ...     },
            ...     annotations={
            ...         'img1.jpg': sv.Classifications(class_id=np.array([0])),
            ...         'img2.jpg': sv.Classifications(class_id=np.array([1])),
            ...     }
            ... )
            >>> train_cd, test_cd = cd.split(split_ratio=0.5, random_state=42)
            >>> len(train_cd), len(test_cd)
            (1, 1)

            ```
        rl   rn   )r   rC   rD   r   r   r8   ro   s                r"   r)   zClassificationDataset.split8  s   T #3!!#%	#
Z !!JUV$4!7!7!==VKVIST$ 6 6t <<TJT%K#JFQRdT4#3#3D#99RREOPTD$"2"24"88PP-LL)

 -LL(
 l**' WT SPry   c                   t        j                  |d       | j                  D ]7  }t        j                  t         j                  j	                  ||      d       9 | D ]  \  }}}t        |      j                  }|j                  |j                  d   n|j                  d      d   d   }| j                  |   }t         j                  j	                  |||      }t        j                  ||        y)z
        Saves the dataset as a multi-class folder structure.

        Args:
            root_directory_path: The path to the directory
                where the dataset will be saved.
        T)r   Nr   r   )r   makedirsr8   rr   r   r	   r   
confidencer>   	get_top_krL   imwrite)r!   root_directory_path
class_nameimage_save_pathrP   rG   r   r>   s           r"   as_folder_structurez)ClassificationDataset.as_folder_structure  s     	'$7,, 	VJKK%8*EPTU	V 37 		0.OUJo.33J ((0 ##A&))!,Q/2 
 h/J ggll+>
JWOKK/		0r$   c           	        t        j                  |      }t        t        |            }g }i }|D ]  }|j	                  |      }t        j                  t         j
                  j                  ||            D ]`  }t        t         j
                  j                  |||            }|j                  |       t        t        j                  |g            ||<   b   | |||      S )a  
        Load data from a multiclass folder structure into a ClassificationDataset.

        Args:
            root_directory_path: The path to the dataset directory.

        Returns:
            The dataset.

        Examples:
            ```python
            import roboflow
            from roboflow import Roboflow
            import supervision as sv

            roboflow.login()
            rf = Roboflow()

            project = rf.workspace(WORKSPACE_ID).project(PROJECT_ID)
            dataset = project.version(PROJECT_VERSION).download("folder")

            cd = sv.ClassificationDataset.from_folder_structure(
                root_directory_path=f"{dataset.location}/train"
            )
            ```
        )r>   rn   )r   listdirsortedr9   indexrr   r   r   appendr
   r;   r<   )	r   r   r8   rC   r   r   r>   rP   rO   s	            r"   from_folder_structurez+ClassificationDataset.from_folder_structure  s    8 **01W&! 	J}}Z0HBGGLL1Dj$QR  .A:u!UV
"":.*9XXxj1+J'	 #
 	
r$   )r8   r   rE   r   r   zdict[str, Classifications]r+   r   r   r*   )r[   r,   r+   z2tuple[str, npt.NDArray[np.uint8], Classifications])r+   z<Iterator[tuple[str, npt.NDArray[np.uint8], Classifications]]r   r-   )r&   r.   r'   r/   r(   r0   r+   z3tuple[ClassificationDataset, ClassificationDataset])r   r   r+   r   )r   r   r+   r   )r1   r2   r3   r   rH   rQ   r#   r\   rb   rj   r)   r   r   r   r   r$   r"   r   r     s    
 = 0	
 
4D	-0	E00 !#'	G+G+ !G+ 	G+
 
=G+R00 /
 /
r$   r   )1
__future__r   r   abcr   r   collections.abcr   dataclassesr   	itertoolsr   pathlibr	   rL   numpyr;   numpy.typingtypingnptsupervision.classification.corer
   supervision.configr    supervision.dataset.formats.cocor   r   &supervision.dataset.formats.pascal_vocr   r    supervision.dataset.formats.yolor   r   r   supervision.dataset.utilsr   r   r   r   r   supervision.detection.corer   supervision.utils.internalr   supervision.utils.iterablesr   r   r5   r   r   r$   r"   <module>r      s    " 	 # $ !   
   ; 4 
  2 6 7# [
9{ [
9| r
K r
 r
r$   