
    |hL                         d dl Z d dl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mZmZmZmZ d dlZd dlZd dlmZ d dlmZmZmZmZ d dlmZmZmZmZm Z  d d	l!m"Z"  G d
 de      Z#y)    N)deepcopy)
ThreadPool)Path)AnyDictListOptionalTupleUnion)Dataset)FORMATS_HELP_MSGHELP_URLIMG_FORMATScheck_file_speeds)DEFAULT_CFG
LOCAL_RANKLOGGERNUM_THREADSTQDM)imreadc                       e Zd ZdZdddeddddddd	d
dfdeeee   f   dedee	ef   de	de
eef   dede	dededede	deee      dedef fdZdeeee   f   dee   fdZdeee      dd	fdZd0ded e	deej&                  eeef   eeef   f   fd!Zd1d"Zdedd	fd#Zd2d$ede	fd%Zd2d$ede	fd&Zd1d'Zd(ede
eef   fd)Zd(ede
eef   fd*Zdefd+Zd,e
eef   de
eef   fd-Zd3dee
eef      fd.Zdee
eef      fd/Z xZ S )4BaseDataseta
  
    Base dataset class for loading and processing image data.

    This class provides core functionality for loading images, caching, and preparing data for training and inference
    in object detection tasks.

    Attributes:
        img_path (str): Path to the folder containing images.
        imgsz (int): Target image size for resizing.
        augment (bool): Whether to apply data augmentation.
        single_cls (bool): Whether to treat all objects as a single class.
        prefix (str): Prefix to print in log messages.
        fraction (float): Fraction of dataset to utilize.
        channels (int): Number of channels in the images (1 for grayscale, 3 for RGB).
        cv2_flag (int): OpenCV flag for reading images.
        im_files (List[str]): List of image file paths.
        labels (List[Dict]): List of label data dictionaries.
        ni (int): Number of images in the dataset.
        rect (bool): Whether to use rectangular training.
        batch_size (int): Size of batches.
        stride (int): Stride used in the model.
        pad (float): Padding value.
        buffer (list): Buffer for mosaic images.
        max_buffer_length (int): Maximum buffer size.
        ims (list): List of loaded images.
        im_hw0 (list): List of original image dimensions (h, w).
        im_hw (list): List of resized image dimensions (h, w).
        npy_files (List[Path]): List of numpy file paths.
        cache (str): Cache images to RAM or disk during training.
        transforms (callable): Image transformation function.
        batch_shapes (np.ndarray): Batch shapes for rectangular training.
        batch (np.ndarray): Batch index of each image.

    Methods:
        get_img_files: Read image files from the specified path.
        update_labels: Update labels to include only specified classes.
        load_image: Load an image from the dataset.
        cache_images: Cache images to memory or disk.
        cache_images_to_disk: Save an image as an *.npy file for faster loading.
        check_cache_disk: Check image caching requirements vs available disk space.
        check_cache_ram: Check image caching requirements vs available memory.
        set_rectangle: Set the shape of bounding boxes as rectangles.
        get_image_and_label: Get and return label information from the dataset.
        update_labels_info: Custom label format method to be implemented by subclasses.
        build_transforms: Build transformation pipeline to be implemented by subclasses.
        get_labels: Get labels method to be implemented by subclasses.
    i  FT              ?Ng      ?   img_pathimgszcacheaugmenthypprefixrect
batch_sizestridepad
single_clsclassesfractionchannelsc                 $   t         |           || _        || _        || _        || _        || _        || _        || _        |dk(  rt        j                  nt        j                  | _        | j                  | j                        | _        | j                         | _        | j#                  |       t%        | j                         | _        || _        || _        |	| _        |
| _        | j(                  r| j*                  J | j1                          g | _        | j                  r%t5        | j&                  | j*                  dz  df      nd| _        dg| j&                  z  dg| j&                  z  dg| j&                  z  c| _        | _        | _        | j                  D cg c]  }t?        |      jA                  d       c}| _!        tE        |tF              r|jI                         n|du rd	nd| _%        | jJ                  d	k(  rB| jM                         r2|jN                  rtQ        jR                  d
       | jU                          n/| jJ                  dk(  r | jW                         r| jU                          | jY                  |      | _-        yc c}w )a  
        Initialize BaseDataset with given configuration and options.

        Args:
            img_path (str | List[str]): Path to the folder containing images or list of image paths.
            imgsz (int): Image size for resizing.
            cache (bool | str): Cache images to RAM or disk during training.
            augment (bool): If True, data augmentation is applied.
            hyp (Dict[str, Any]): Hyperparameters to apply data augmentation.
            prefix (str): Prefix to print in log messages.
            rect (bool): If True, rectangular training is used.
            batch_size (int): Size of batches.
            stride (int): Stride used in the model.
            pad (float): Padding value.
            single_cls (bool): If True, single class training is used.
            classes (List[int], optional): List of included classes.
            fraction (float): Fraction of dataset to utilize.
            channels (int): Number of channels in the images (1 for grayscale, 3 for RGB).
           )include_classN   i  r   z.npyTramzcache='ram' may produce non-deterministic training results. Consider cache='disk' as a deterministic alternative if your disk space allows.disk)r"   ).super__init__r   r   r!   r(   r#   r*   r+   cv2IMREAD_GRAYSCALEIMREAD_COLORcv2_flagget_img_filesim_files
get_labelslabelsupdate_labelslennir$   r%   r&   r'   set_rectanglebufferminmax_buffer_lengthimsim_hw0im_hwr   with_suffix	npy_files
isinstancestrlowerr    check_cache_ramdeterministicr   warningcache_imagescheck_cache_diskbuild_transforms
transforms)selfr   r   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   f	__class__s                   T/var/www/html/test/engine/venv/lib/python3.12/site-packages/ultralytics/data/base.pyr3   zBaseDataset.__init__F   s   H 	 
$  08A,,3CSCS**4==9oo'1dkk"	$99??...  NRlldggt/BD%I!J`a .2FTWW,<tftww>NQUPVY]Y`Y`P`)$+tz?C}}M!$q'--f5M&0&<U[[]5TX=%^b
::4#7#7#9  f ZZ6!d&;&;&= //C/8 Ns   !Jreturnc           
         	 g }t        |t              r|n|gD ]  }t        |      }|j                         r*|t	        j                  t        |dz  dz        d      z  }I|j                         rt        |d      5 }|j                         j                         j                         }t        |j                        t        j                  z   }||D cg c]'  }|j                  d      r|j                  d|      n|) c}z  }ddd       t!        | j"                   | d	       t%        d
 |D              }|sJ | j"                   d| dt&                	 | j,                  dk  r$|dt/        t1        |      | j,                  z         }t3        || j"                         |S c c}w # 1 sw Y   xY w# t(        $ r'}t!        | j"                   d| dt*               |d}~ww xY w)aN  
        Read image files from the specified path.

        Args:
            img_path (str | List[str]): Path or list of paths to image directories or files.

        Returns:
            (List[str]): List of image file paths.

        Raises:
            FileNotFoundError: If no images are found or the path doesn't exist.
        z**z*.*T)	recursivezutf-8)encodingz./Nz does not existc              3      K   | ]M  }|j                  d       d   j                         t        v s,|j                  dt        j
                         O yw)./N)
rpartitionrJ   r   replaceossep).0xs     rU   	<genexpr>z,BaseDataset.get_img_files.<locals>.<genexpr>   s@     p1<<PSCTUWCXC^C^C`doCoaiiRVV4ps
   -A%AzNo images found in z. zError loading data from 
r-   )r#   )rH   listr   is_dirglobrI   is_fileopenreadstrip
splitlinesparentr`   ra   
startswithr_   FileNotFoundErrorr#   sortedr   	Exceptionr   r*   roundr=   r   )	rR   r   rS   ptrn   rc   r9   es	            rU   r8   zBaseDataset.get_img_files   s   	kA!+Hd!;X( PG88:3q4x%'7#8DIIAYY[a'2 _aFFHNN,779!$QXX!7\]^WXd9Kaiif5QRR^^_ _ ,t{{mA3o,NOOP pappH^},?zL\K]^^8 ==1 F%H(E"FGH(4;;7 __ _  	k#t{{m3KH:UWX`Wa$bcijj	ksD   A=F< ?AF/,F*
F/AF< *F//F9	4F< <	G,"G''G,r.   c                    t        j                  |      j                  dd      }t        t	        | j
                              D ]  }|| j
                  |   d   }| j
                  |   d   }| j
                  |   d   }| j
                  |   d   }||k(  j                  d      }||   | j
                  |   d<   ||   | j
                  |   d<   |r4t        |      D 	
cg c]  \  }	}
|
s	||	    c}
}	| j
                  |   d<   |||   | j
                  |   d<   | j                  sd| j
                  |   d   dddf<    yc c}
}	w )	z
        Update labels to include only specified classes.

        Args:
            include_class (List[int], optional): List of classes to include. If None, all classes are included.
        r-   r\   Nclsbboxessegments	keypointsr   )	nparrayreshaperanger=   r;   any	enumerater(   )rR   r.   include_class_arrayirx   ry   rz   r{   jsiidxs              rU   r<   zBaseDataset.update_labels   sA    !hh}5==aDs4;;'( 	0A(kk!nU+Q1;;q>*5 KKN;7	//44Q7(+AAu%+1!9Ax(NWXYl1b72s^a(2,1bDKKN:.(2;A,DKKN;/./Au%ad+	0 2cs   
E*Er   	rect_modec                 ^   | j                   |   | j                  |   | j                  |   }}}|b|j                         r	 t	        j
                  |      }nt        || j                        }|t        d|       |j                  dd \  }}|r| j                   t#        ||      z  }	|	d	k7  rt%        t'        j(                  ||	z        | j                         t%        t'        j(                  ||	z        | j                         }}
t+        j,                  ||
|ft*        j.                  
      }nS||cxk(  r| j                   k(  s>n t+        j,                  || j                   | j                   ft*        j.                  
      }|j0                  dk(  r|d   }| j2                  r|||f|j                  dd c| j                   |<   | j4                  |<   | j6                  |<   | j8                  j;                  |       d	t=        | j8                        cxk  r| j>                  k\  rZn nW| j8                  jA                  d      }| jB                  dk7  r-d\  | j                   |<   | j4                  |<   | j6                  |<   |||f|j                  dd fS | j                   |   | j4                  |   | j6                  |   fS # t        $ rd}t        j                  | j                   d| d|        t        |      j                  d       t        || j                        }Y d}~d}~ww xY w)a  
        Load an image from dataset index 'i'.

        Args:
            i (int): Index of the image to load.
            rect_mode (bool): Whether to use rectangular resizing.

        Returns:
            im (np.ndarray): Loaded image as a NumPy array.
            hw_original (Tuple[int, int]): Original image dimensions in (height, width) format.
            hw_resized (Tuple[int, int]): Resized image dimensions in (height, width) format.

        Raises:
            FileNotFoundError: If the image file is not found.
        Nz"Removing corrupt *.npy image file z	 due to: T)
missing_ok)flagszImage Not Found    r-   )interpolation).Nr   r0   )NNN)"rC   r9   rG   existsr|   loadrr   r   rM   r#   r   unlinkr   r7   rp   shaper   maxrA   mathceilr4   resizeINTER_LINEARndimr!   rD   rE   r@   appendr=   rB   popr    )rR   r   r   imrS   fnrv   h0w0rwhr   s                rU   
load_imagezBaseDataset.load_image   s     HHQKq!14>>!3DrA:yy{8B AT]]3z'*:1#(>??XXbq\FBJJR,6		"q& 14::>DIIbSTfDUW[WaWa@bqABAc>N>NOBB,$**,ZZTZZ$<CL\L\]ww!|	] ||=?"b288TVUV<:T[[^TZZ]""1%s4;;'A4+A+AA*AzzU*EUBT[[^TZZ]Bx"1--xx{DKKNDJJqM99? ! 8NNdkk]2TUWTXXabcad#efHOOtO47B8s   J? ?	L,AL''L,c                    d\  }}| j                   dk(  r| j                  dfn| j                  df\  }}t        t              5 }|j                  |t        | j                              }t        t        |      | j                  t        dkD        }|D ]  \  }}	| j                   dk(  r+|| j                  |   j                         j                  z  }nI|	\  | j                  |<   | j                  |<   | j                   |<   || j                  |   j"                  z  }| j$                   d||z  dd	| d
|_         |j)                          ddd       y# 1 sw Y   yxY w)z3Cache images to memory or disk for faster training.r   i   @r1   DiskRAMr   )totaldisablezCaching images (.1fzGB )N)r    cache_images_to_diskr   r   r   imapr   r>   r   r   r   rG   statst_sizerC   rD   rE   nbytesr#   descclose)
rR   bgbfcnstoragepoolresultspbarr   rc   s
             rU   rN   zBaseDataset.cache_images  s<   2>BjjF>R116:Y]YhYhjoXpW$ 
	iiU477^4G	'*$'':PQ>RD V1::'*//1999AAB>DHHQKQA!+++A#{{m+;AF3<s7)STU	V JJL
	 
	 
	s   D	EEc                     | j                   |   }|j                         s=t        j                  |j	                         t        | j                  |         d       yy)z2Save an image as an *.npy file for faster loading.F)allow_pickleN)rG   r   r|   saveas_posixr   r9   )rR   r   rS   s      rU   r   z BaseDataset.cache_images_to_disk  sB    NN1xxzGGAJJL&q)9":O     safety_marginc                    ddl }d\  }}t        | j                  d      }t        |      D ]  }t	        j
                  | j                        }t        |      }|0||j                  z  }t        j                  t        |      j                  t        j                        rwd| _        t        j                   | j"                   d        y || j                  z  |z  d|z   z  }	|j%                  t        | j                  d         j                        \  }
}}|	|kD  rMd| _        t        j                   | j"                   |	|z  dd	t'        |d
z         d||z  dd|
|z  dd	       yy)a  
        Check if there's enough disk space for caching images.

        Args:
            safety_margin (float): Safety margin factor for disk space calculation.

        Returns:
            (bool): True if there's enough disk space, False otherwise.
        r   Nr      z8Skipping caching images to disk, directory not writeableFr-   r   zGB disk space required, with d   % safety margin but only r]   z#GB free, not caching images to diskT)shutilrA   r>   r   randomchoicer9   r   r   r`   accessr   rn   W_OKr    r   rM   r#   
disk_usageint)rR   r   r   r   r   n_im_filer   disk_requiredr   usedfrees                rU   rO   zBaseDataset.check_cache_disk  sZ    	2q 		AmmDMM2GBzNA99T']11277;!
$++.fgh		 DGGa1}+<="--d4==3C.D.K.KLtT4DJNN;;- 237 8MC/011J"9S/52:c"22UW
 r   c                    d\  }}t        | j                  d      }t        |      D ]u  }t        t	        j
                  | j                              }|.| j                  t        |j                  d   |j                  d         z  }||j                  |dz  z  z  }w || j                  z  |z  d|z   z  }t        d      j                         }	||	j                  kD  rad| _        t        j                   | j"                   ||z  dd	t%        |d
z         d|	j                  |z  dd|	j&                  |z  dd	       yy)z
        Check if there's enough RAM for caching images.

        Args:
            safety_margin (float): Safety margin factor for RAM calculation.

        Returns:
            (bool): True if there's enough RAM, False otherwise.
        r   r   Nr   r-   r   psutilr   z%GB RAM required to cache images with r   r   r]   z GB available, not caching imagesFT)rA   r>   r   r   r   r   r9   r   r   r   r   
__import__virtual_memory	availabler    r   rM   r#   r   r   )
rR   r   r   r   r   r   r   ratiomem_requiredmems
             rU   rK   zBaseDataset.check_cache_ramB  s:    2q 	&Admm45BzJJRXXa["((1+!>>EUAX%%A	& 477{Q!m*;<"113#--'DJNN;;-r 1#6 7MC/011J==2%c*!CIIN3+??_a
 r   c                    t        j                  t        j                  | j                        | j                  z        j                  t              }|d   dz   }t        j                  | j                  D cg c]  }|j                  d       c}      }|dddf   |dddf   z  }|j                         }|D cg c]  }| j                  |    c}| _        |D cg c]  }| j                  |    c}| _        ||   }ddgg|z  }t        |      D ]G  }|||k(     }	|	j                         |	j                         }}
|dk  r|dg||<   8|
dkD  s>dd|
z  g||<   I t        j                  t        j                  |      | j                   z  | j"                  z  | j$                  z         j                  t              | j"                  z  | _        || _        yc c}w c c}w c c}w )zBSet the shape of bounding boxes for YOLO detections as rectangles.r\   r-   r   Nr   )r|   flooraranger>   r%   astyper   r}   r;   r   argsortr9   r   rA   r   r   r   r&   r'   batch_shapesbatch)rR   binbrc   sarirectr   shapesariminimaxis               rU   r?   zBaseDataset.set_rectangle`  s   XXbii(4??:;BB3GVaZHHdkk:aeeGn:;q!tWqAw

389aq)9/45!t{{1~5Y a&Br 	*AR1W+CCGGI$Dax!1Iq	DMq		* GGBHHV$4tzz$ADKK$ORVRZRZ$Z[bbcfgjnjujuu
% ; :5s   8G>G! G&indexc                 B    | j                  | j                  |            S )z5Return transformed label information for given index.)rQ   get_image_and_label)rR   r   s     rU   __getitem__zBaseDataset.__getitem__y  s    t77>??r   c                 T   t        | j                  |         }|j                  dd       | j                  |      \  |d<   |d<   |d<   |d   d   |d   d   z  |d   d   |d   d   z  f|d<   | j                  r| j
                  | j                  |      |d	<   | j                  |      S )
z
        Get and return label information from the dataset.

        Args:
            index (int): Index of the image to retrieve.

        Returns:
            (Dict[str, Any]): Label dictionary with image and metadata.
        r   Nimg	ori_shaperesized_shaper   r-   	ratio_pad
rect_shape)r   r;   r   r   r$   r   r   update_labels_info)rR   r   labels      rU   r   zBaseDataset.get_image_and_label}  s     U+,		'4 CG??SXCY@eeK(%*@/"1%k(:1(==/"1%k(:1(==
k 99"&"3"3DJJu4E"FE,&&u--r   c                 ,    t        | j                        S )z5Return the length of the labels list for the dataset.)r=   r;   rR   s    rU   __len__zBaseDataset.__len__  s    4;;r   r   c                     |S )zCustom your label format here. )rR   r   s     rU   r   zBaseDataset.update_labels_info  s    r   c                     t         )a  
        Users can customize augmentations here.

        Examples:
            >>> if self.augment:
            ...     # Training transforms
            ...     return Compose([])
            >>> else:
            ...    # Val transforms
            ...    return Compose([])
        NotImplementedError)rR   r"   s     rU   rP   zBaseDataset.build_transforms  s
     "!r   c                     t         )a)  
        Users can customize their own format here.

        Examples:
            Ensure output is a dictionary with the following keys:
            >>> dict(
            ...     im_file=im_file,
            ...     shape=shape,  # format: (height, width)
            ...     cls=cls,
            ...     bboxes=bboxes,  # xywh
            ...     segments=segments,  # xy
            ...     keypoints=keypoints,  # xy
            ...     normalized=True,  # or False
            ...     bbox_format="xyxy",  # or xywh, ltwh
            ... )
        r   r   s    rU   r:   zBaseDataset.get_labels  s
    " "!r   )T)rV   N)r   )N)!__name__
__module____qualname____doc__r   r   rI   r   r   boolr   r   floatr	   r3   r8   r<   r
   r|   ndarrayr   rN   r   rO   rK   r?   r   r   r   r   rP   r:   __classcell__)rT   s   @rU   r   r      s]   .f "') '+L9T#Y'L9 L9 T3Y	L9
 L9 #s(^L9 L9 L9 L9 L9 L9 L9 $s)$L9 L9 L9\$eCcN&; $S	 $L08DI+> 04 004:C 4:D 4:E"**eTWY\T\o_dehjmem_nBn<o 4:l Pc Pd P"e "d "HU T <2@ @c3h @. .c3h .*   S#X 4S> "HT#s(^$< ""Dc3h0 "r   r   )$rh   r   r`   r   copyr   multiprocessing.poolr   pathlibr   typingr   r   r   r	   r
   r   r4   numpyr|   torch.utils.datar   ultralytics.data.utilsr   r   r   r   ultralytics.utilsr   r   r   r   r   ultralytics.utils.patchesr   r   r   r   rU   <module>r     sH      	   +  : : 
  $ ] ] P P ,d"' d"r   