Ë
    FêñiI2  ã                  ó–  — d dl m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	 d dl
Z
d dlZd dlmZ d dlmZmZ d d	lmZ d d
lmZ ddd„Zddd„Z	 	 	 	 d	 	 	 	 	 	 	 	 	 	 	 dd„Zddd„Z	 d	 	 	 	 	 	 	 	 	 	 	 	 	 d d„Z	 	 	 d!	 	 	 	 	 	 	 	 	 	 	 d"d„Z	 d#	 	 	 	 	 	 	 	 	 	 	 d$d„Z	 d#	 	 	 	 	 	 	 	 	 	 	 d$d„Zedk(  r edd¬«        edd¬«       yy)%é    )ÚannotationsN)Úglob)Úceil)ÚPath)ÚAny)ÚImage)Ú	exif_sizeÚimg2label_paths)ÚTQDM)Úcheck_requirementsc           
     ó¶  ‡— t        d«       ddlm} | j                  ddd«      } t	        j
                  | d¬«      }t	        j                  | d¬«      }t	        j                  ||gd¬«      }t	        j                  |d	d	…d	d	d…f   ‰d
d	d…f   «      }t	        j                  |d	d	…d	dd	…f   ‰d
dd	…f   «      }t	        j                  ||z
  dt        j                  «      }	|	d   |	d   z  }
ˆfd„t        d«      D «       \  }}}}t	        j                  ||||||||gd¬«      j                  ddd«      }| D �cg c]
  } ||«      ‘Œ }}|D �cg c]
  } ||«      ‘Œ }}t	        j                  |
j                  «      }t!        t	        j"                  |
«      Ž D ],  }||d      j%                  ||d      «      j&                  ||<   Œ. t	        j(                  |D �cg c]  }|j&                  ‘Œ c}t        j*                  ¬«      }|d   }t	        j                  ||t        j                  «      }||z  }|j,                  dk(  r|d   }|S c c}w c c}w c c}w )að  Calculate Intersection over Foreground (IoF) between polygons and bounding boxes.

    Args:
        polygon1 (np.ndarray): Polygon coordinates with shape (N, 8).
        bbox2 (np.ndarray): Bounding boxes with shape (M, 4).
        eps (float, optional): Small value to prevent division by zero.

    Returns:
        (np.ndarray): IoF scores with shape (N, M).

    Notes:
        Polygon format: [x1, y1, x2, y2, x3, y3, x4, y4].
        Bounding box format: [x_min, y_min, x_max, y_max].
    zshapely>=2.0.0r   )ÚPolygonéÿÿÿÿé   é   éþÿÿÿ©ÚaxisN.).r   ).é   c              3  ó,   •K  — | ]  }‰d |f   –— Œ y­w©.N© )Ú.0ÚiÚbbox2s     €ú]/var/www/pod-logistic/pod-ai/venv/lib/python3.12/site-packages/ultralytics/data/split_dota.pyú	<genexpr>zbbox_iof.<locals>.<genexpr>0   s   øè ø€ Ò@°!  c¨1 f¥Ñ@ùs   ƒ©Údtyper   r   )r   Úshapely.geometryr   ÚreshapeÚnpÚminÚmaxÚconcatenateÚmaximumÚminimumÚclipÚinfÚrangeÚstackÚzerosÚshapeÚzipÚnonzeroÚintersectionÚareaÚarrayÚfloat32Úndim)Úpolygon1r   Úepsr   Últ_pointÚrb_pointÚbbox1ÚltÚrbÚwhÚ
h_overlapsÚleftÚtopÚrightÚbottomÚpolygon2ÚpÚ	sg_polys1Ú	sg_polys2ÚoverlapsÚunionsÚoutputss    `                    r   Úbbox_iofrI      s$  ø€ ô Ð'Ô(Ý(à×Ñ  A qÓ)€HÜ�v‰v�h RÔ(€HÜ�v‰v�h RÔ(€HÜ�N‰N˜H hÐ/°bÔ9€Eä	�‰�Eš!˜T 2 A 2˜+Ñ&¨¨c°2°A°2¨g©Ó	7€BÜ	�‰�Eš!˜T 1¡2˜+Ñ&¨¨c°1±2¨g©Ó	7€BÜ	�‰��b‘˜!œRŸV™VÓ	$€BØ�F‘˜b ™jÑ(€Jã@´u¸Q³xÔ@Ñ€Dˆ#ˆu�fÜ�x‰x˜˜s E¨3°°v¸tÀVÐLÐSUÔV×^Ñ^Ð_aÐcdÐfgÓh€Hà%-Ö. ‘˜•Ð.€IÐ.Ø%-Ö. ‘˜•Ð.€IÐ.Ü�x‰x˜
×(Ñ(Ó)€HÜ”"—*‘*˜ZÓ(Ð)ò JˆØ  !¡‘o×2Ñ2°9¸Q¸r¹UÑ3CÓD×IÑIˆ�ŠðJä�X‰X yÖ1 !�q—v“vÒ1¼¿¹ÔD€FØ�IÑ€Fä�W‰W�V˜S¤"§&¡&Ó)€FØ˜Ñ€GØ‡|�|�qÒØ˜)Ñ$ˆØ€Nùò /ùÚ.ùò 2s   Ä;IÅIÇIc                óÈ  — |dv sJ d|› d�«       ‚t        | «      dz  |z  }|j                  «       sJ d|› d�«       ‚t        t        t        | «      dz  |z  dz  «      «      }t	        |«      }g }t        ||«      D ]Ó  \  }}t        t        j                  |«      «      \  }}	t        |d¬	«      5 }
|
j                  «       j                  «       j                  «       D �cg c]  }t        |«      sŒ|j                  «       ‘Œ  }}t        j                  |t        j                   ¬
«      }ddd«       |j#                  t%        |	|f|¬«      «       ŒÕ |S c c}w # 1 sw Y   Œ1xY w)a,  Load DOTA dataset annotations and image information.

    Args:
        data_root (str): Data root directory.
        split (str, optional): The split data set, could be 'train' or 'val'.

    Returns:
        (list[dict[str, Any]]): List of annotation dictionaries containing image information.

    Notes:
        The directory structure assumed for the DOTA dataset:
            - data_root
                - images
                    - train
                    - val
                - labels
                    - train
                    - val
    >   ÚvalÚtrainz$Split must be 'train' or 'val', not ú.ÚimagesúCan't find ú, please check your data root.Ú*úutf-8©Úencodingr   N)Úori_sizeÚlabelÚfilepath)r   Úexistsr   Ústrr
   r.   r	   r   ÚopenÚreadÚstripÚ
splitlinesÚlenÚsplitr"   r2   r3   ÚappendÚdict)Ú	data_rootr_   Úim_dirÚim_filesÚlb_filesÚannosÚim_fileÚlb_fileÚwÚhÚfÚxÚlbs                r   Úload_yolo_dotarn   B   sJ  € ð( Ð$Ñ$ÐUÐ(LÈUÈGÐSTÐ&UÓUÐ$Ü�)‹_˜xÑ'¨%Ñ/€FØ�=‰=Œ?ÐP˜k¨&¨Ð1OÐPÓPˆ?Ü”Cœ˜Y›¨(Ñ2°UÑ:¸SÑ@ÓAÓB€HÜ˜xÓ(€HØ€EÜ ¨(Ó3ò HÑˆ�ÜœŸ™ GÓ,Ó-‰ˆˆ1Ü�' GÔ,ð 	0°Ø%&§V¡V£X§^¡^Ó%5×%@Ñ%@Ó%BÖM ÄcÈ!Åf�!—'‘'•)ÐMˆBÐMÜ—‘˜"¤B§J¡JÔ/ˆB÷	0ð 	�‰”T A q 6°¸gÔFÕGðHð €Lùò N÷	0ð 	0ús$   Â//EÃEÃ/EÄ'EÅEÅE!	c           	     óØ  — | \  }}g }t        ||«      D �];  \  }}	||	kD  sJ d|› d|	› d�«       ‚||	z
  }
||k  rdnt        ||z
  |
z  dz   «      }t        |«      D �cg c]  }|
|z  ‘Œ	 }}t        |«      dkD  r|d   |z   |kD  r||z
  |d<   ||k  rdnt        ||z
  |
z  dz   «      }t        |«      D �cg c]  }|
|z  ‘Œ	 }}t        |«      dkD  r|d   |z   |kD  r||z
  |d<   t	        j
                  t        t        j                  ||«      «      t        j                  ¬«      }||z   }|j                  t	        j                  ||gd¬«      «       �Œ> t	        j                  |d¬«      }|j                  «       }t	        j                  |d	d	…dd	d
…f   d|«      |d	d	…dd	d
…f<   t	        j                  |d	d	…dd	d
…f   d|«      |d	d	…dd	d
…f<   |d	d	…d
f   |d	d	…df   z
  |d	d	…df   |d	d	…df   z
  z  }|d	d	…d
f   |d	d	…df   z
  |d	d	…df   |d	d	…df   z
  z  }||z  }||kD  j                  «       s$|j                  «       }d|t!        ||z
  «      |k  <   |||kD     S c c}w c c}w )aL  Get the coordinates of sliding windows for image cropping.

    Args:
        im_size (tuple[int, int]): Original image size, (H, W).
        crop_sizes (tuple[int, ...], optional): Crop size of windows.
        gaps (tuple[int, ...], optional): Gap between crops.
        im_rate_thr (float, optional): Threshold for the ratio of image area within a window to the total window area.
        eps (float, optional): Epsilon value for math operations.

    Returns:
        (np.ndarray): Array of window coordinates of shape (N, 4) where each row is [x_start, y_start, x_stop, y_stop].
    zinvalid crop_size gap pair [ú ú]r   r   r   r   r   Nr   é   )r.   r   r*   r^   r"   r2   ÚlistÚ	itertoolsÚproductÚint64r`   r%   Úcopyr(   Úanyr$   Úabs)Úim_sizeÚ
crop_sizesÚgapsÚim_rate_thrr6   rj   ri   ÚwindowsÚ	crop_sizeÚgapÚstepÚxnr   ÚxsÚynÚysÚstartÚstopÚ
im_in_winsÚim_areasÚ	win_areasÚim_ratesÚmax_rates                          r   Úget_windowsr�   e   s¬  € ð& �D€A€qØ€GÜ˜j¨$Ó/ó >‰ˆ	�3Ø˜3ŠÐQÐ">¸y¸kÈÈ3È%ÈqÐ QÓQˆØ˜3‰ˆà�y’.‰Q¤d¨A°	©M¸TÑ+AÀAÑ+EÓ&FˆÜ % b£	Ö*˜1ˆd�Q‹hÐ*ˆÐ*Üˆr‹7�QŠ;˜2˜b™6 IÑ-°Ò1Ø˜‘]ˆBˆr‰Fà�y’.‰Q¤d¨A°	©M¸TÑ+AÀAÑ+EÓ&FˆÜ % b£	Ö*˜1ˆd�Q‹hÐ*ˆÐ*Üˆr‹7�QŠ;˜2˜b™6 IÑ-°Ò1Ø˜‘]ˆBˆr‰Fä—‘œœi×/Ñ/°°BÓ7Ó8ÄÇÁÔIˆØ�yÑ ˆØ�‰”r—~‘~ u¨d m¸!Ô<Ö=ð!>ô" �n‰n˜W¨1Ô-€Gà—‘“€JÜŸ'™' *ªQ°°°1°¨WÑ"5°q¸!Ó<€JŠq�!�$�Q�$ˆwÑÜŸ'™' *ªQ°°°1°¨WÑ"5°q¸!Ó<€JŠq�!�$�Q�$ˆwÑØš1˜a˜4Ñ  :ªa°¨dÑ#3Ñ3¸
Â1ÀaÀ4Ñ8HÈ:ÒVWÐYZÐVZÑK[Ñ8[Ñ\€HØš˜A˜‘ ª¨A¨¡Ñ.°7º1¸a¸4±=À7Ê1ÈaÈ4Á=Ñ3PÑQ€IØ˜)Ñ#€HØ�{Ñ"×'Ñ'Ô)Ø—<‘<“>ˆØ34ˆ”�X Ñ(Ó)¨CÑ/Ñ0Ø�8˜kÑ)Ñ*Ð*ùò/ +ùò
 +s   ÁI"Â2I'c                ó¨  — | d   \  }}| d   }t        |«      rl|dd…ddd…fxx   |z  cc<   |dd…ddd…fxx   |z  cc<   t        |dd…dd…f   |«      }t        t        |«      «      D �cg c]  }||dd…|f   |k\     ‘Œ c}S t        t        |«      «      D �cg c]'  }t        j                  dt        j
                  ¬«      ‘Œ) c}S c c}w c c}w )z3Get objects for each window based on IoF threshold.rU   rV   Nr   r   )r   é	   r   )r^   rI   r*   r"   r,   r3   )	Úannor~   Úiof_thrrj   ri   rV   Úiofsr   Ú_s	            r   Úget_window_objr”   ™   sÄ   € à�
Ñ�D€A€qØ�‰M€EÜ
ˆ5„zØŠa���A�ˆg‹˜!Ñ‹ØŠa���A�ˆg‹˜!Ñ‹Ü˜ša ¡˜e™ gÓ.ˆä8=¼cÀ'»lÓ8KÖL°1��tšA˜q˜D‘z WÑ,Ó-ÒLÐLä<AÄ#ÀgÃ,Ó<OÖP°q”—‘˜¤r§z¡zÖ2ÒPÐPùò MùâPs   Á,C
Â,Cc           
     óV  — t        j                  | d   «      }t        | d   «      j                  }t	        |«      D �]X  \  }}	|	j                  «       \  }
}}}|› d||
z
  › d|
› d|› �}|||…|
|…f   }|j                  dd \  }}||   }t        |«      s|r.t        j                  t        t        |«      |› d�z  «      |«       t        |«      sŒ•|dd…ddd…fxx   |
z  cc<   |dd…ddd…fxx   |z  cc<   |dd…ddd…fxx   |z  cc<   |dd…ddd…fxx   |z  cc<   t        t        |«      |› d�z  d	d
¬«      5 }|D ]H  }|dd D �cg c]  }|d›‘Œ }}|j                  t        |d   «      › ddj                  |«      › d�«       ŒJ 	 ddd«       �Œ[ yc c}w # 1 sw Y   �ŒlxY w)a  Crop images and save new labels for each window.

    Args:
        anno (dict[str, Any]): Annotation dict, including 'filepath', 'label', 'ori_size' as its keys.
        windows (np.ndarray): Array of windows coordinates with shape (N, 4).
        window_objs (list[np.ndarray]): A list of labels inside each window.
        im_dir (str): The output directory path of images.
        lb_dir (str): The output directory path of labels.
        allow_background_images (bool, optional): Whether to include background images without labels.

    Notes:
        The directory structure assumed for the DOTA dataset:
            - data_root
                - images
                    - train
                    - val
                - labels
                    - train
                    - val
    rW   Ú__Ú___Nr   ú.jpgr   z.txtri   rR   rS   z.6gr   rp   ú
)Úcv2Úimreadr   ÚstemÚ	enumerateÚtolistr-   r^   ÚimwriterY   rZ   ÚwriteÚintÚjoin)r�   r~   Úwindow_objsrc   Úlb_dirÚallow_background_imagesÚimÚnamer   ÚwindowÚx_startÚy_startÚx_stopÚy_stopÚnew_nameÚpatch_imÚphÚpwrV   rk   rm   ÚcoordÚformatted_coordss                          r   Úcrop_and_saver³   §   så  € ô8 
�‰�D˜Ñ$Ó	%€BÜ��ZÑ Ó!×&Ñ&€DÜ˜wÓ'ó L‰	ˆˆ6Ø+1¯=©=«?Ñ(ˆ�˜& &Ø�V˜2˜f wÑ.Ð/¨r°'°¸#¸g¸YÐGˆØ�g˜f�n g¨f nÐ4Ñ5ˆØ—‘  Ð#‰ˆˆBà˜A‘ˆÜˆuŒ:Ñ0Ü�K‰KœœD ›L¨h¨Z°tÐ+<Ñ<Ó=¸xÔHÜˆu�:Ø’!�Q�T˜�T�'‹N˜gÑ%‹NØ’!�Q�T˜�T�'‹N˜gÑ%‹NØ’!�Q�T˜�T�'‹N˜bÑ ‹NØ’!�Q�T˜�T�'‹N˜bÑ ‹Nä”d˜6“l¨ z°Ð%6Ñ6¸ÀgÔNð LÐRSØò L�BØDFÀqÀrÀFÖ'K¸5¨5°¨+©Ð'KÐ$Ð'KØ—G‘Gœs 2 a¡5›z˜l¨!¨C¯H©HÐ5EÓ,FÐ+GÀrÐJÕKñL÷Lñ LñLùò" (L÷Lñ Lús   Ä>FÅF
Å6FÆFÆF(	c           
     ó`  — t        |«      dz  |z  }|j                  dd¬«       t        |«      dz  |z  }|j                  dd¬«       t        | |¬«      }t        |t	        |«      |¬«      D ]?  }t        |d   ||«      }	t        ||	«      }
t        ||	|
t        |«      t        |«      «       ŒA y)	a  Split both images and labels for a given dataset split.

    Args:
        data_root (str): Root directory of the dataset.
        save_dir (str): Directory to save the split dataset.
        split (str, optional): The split data set, could be 'train' or 'val'.
        crop_sizes (tuple[int, ...], optional): Tuple of crop sizes.
        gaps (tuple[int, ...], optional): Tuple of gaps between crops.

    Notes:
        The directory structure assumed for the DOTA dataset:
            - data_root
                - images
                    - split
                - labels
                    - split
        and the output directory structure is:
            - save_dir
                - images
                    - split
                - labels
                    - split
    rN   T©ÚparentsÚexist_okÚlabels)r_   ©ÚtotalÚdescrU   N)	r   Úmkdirrn   r   r^   r�   r”   r³   rY   )rb   Úsave_dirr_   r{   r|   rc   r¤   rf   r�   r~   r£   s              r   Úsplit_images_and_labelsr¾   Ú   s«   € ô< �(‹^˜hÑ&¨Ñ.€FØ
‡L�L˜¨€LÔ-Ü�(‹^˜hÑ&¨Ñ.€FØ
‡L�L˜¨€LÔ-ä˜9¨EÔ2€EÜ�U¤# e£*°5Ô9ò LˆÜ˜d :Ñ.°
¸DÓAˆÜ$ T¨7Ó3ˆÜ�d˜G [´#°f³+¼sÀ6»{ÕKñLó    c                óº   — g g }}|D ]<  }|j                  t        ||z  «      «       |j                  t        ||z  «      «       Œ> dD ]  }t        | ||||«       Œ y)ah  Split train and val sets of DOTA dataset with multiple scaling rates.

    Args:
        data_root (str): Root directory of the dataset.
        save_dir (str): Directory to save the split dataset.
        crop_size (int, optional): Base crop size.
        gap (int, optional): Base gap between crops.
        rates (tuple[float, ...], optional): Scaling rates for crop_size and gap.

    Notes:
        The directory structure assumed for the DOTA dataset:
            - data_root
                - images
                    - train
                    - val
                - labels
                    - train
                    - val
        and the output directory structure is:
            - save_dir
                - images
                    - train
                    - val
                - labels
                    - train
                    - val
    >   rK   rL   N)r`   r¡   r¾   )	rb   r½   r   r€   Úratesr{   r|   Úrr_   s	            r   Úsplit_trainvalrÃ     sj   € ð< ˜2�€JØò "ˆØ×Ñœ#˜i¨!™mÓ,Ô-Ø�‰”C˜˜a™“LÕ!ð"ð "ò NˆÜ 	¨8°U¸JÈÕMñNr¿   c           	     ó  — g g }}|D ]<  }|j                  t        ||z  «      «       |j                  t        ||z  «      «       Œ> t        |«      dz  dz  }|j                  dd¬«       t        | «      dz  dz  }|j	                  «       sJ d|› d�«       ‚t        t        |dz  «      «      }	t        |	t        |	«      d¬«      D ]¹  }
t        t        j                  |
«      «      \  }}t        ||f||¬	«      }t        j                  |
«      }t        |
«      j                  }|D ]W  }|j!                  «       \  }}}}|› d
||z
  › d
|› d|› �}|||…||…f   }t        j"                  t        ||› d�z  «      |«       ŒY Œ» y)a—  Split test set of DOTA dataset, labels are not included within this set.

    Args:
        data_root (str): Root directory of the dataset.
        save_dir (str): Directory to save the split dataset.
        crop_size (int, optional): Base crop size.
        gap (int, optional): Base gap between crops.
        rates (tuple[float, ...], optional): Scaling rates for crop_size and gap.

    Notes:
        The directory structure assumed for the DOTA dataset:
            - data_root
                - images
                    - test
        and the output directory structure is:
            - save_dir
                - images
                    - test
    rN   ÚtestTrµ   rO   rP   rQ   r¹   )r{   r|   r–   r—   r˜   N)r`   r¡   r   r¼   rX   r   rY   r   r^   r	   r   rZ   r�   rš   r›   rœ   rž   rŸ   )rb   r½   r   r€   rÁ   r{   r|   rÂ   rc   rd   rg   ri   rj   r~   r¦   r§   r¨   r©   rª   r«   r¬   r­   r®   s                          r   Ú
split_testrÆ   *  s�  € ð, ˜2�€JØò "ˆØ×Ñœ#˜i¨!™mÓ,Ô-Ø�‰”C˜˜a™“LÕ!ð"ô �H‹~ Ñ(¨6Ñ1€HØ‡N�N˜4¨$€NÔ/ä�)‹_˜xÑ'¨&Ñ0€FØ�=‰=Œ?ÐP˜k¨&¨Ð1OÐPÓPˆ?Ü”C˜ ™Ó%Ó&€HÜ˜¬¨H«¸FÔCò 	EˆÜœŸ™ GÓ,Ó-‰ˆˆ1Ü˜q !˜f°À$ÔGˆÜ�Z‰Z˜Ó ˆÜ�G‹}×!Ñ!ˆØò 	EˆFØ/5¯}©}«Ñ,ˆG�W˜f fØ˜˜r &¨7Ñ"2Ð!3°2°g°Y¸cÀ'ÀÐKˆHØ˜' &˜.¨'°&¨.Ð8Ñ9ˆHÜ�K‰Kœ˜H¨(¨°4Ð'8Ñ8Ó9¸8ÕDñ		Eñ	Er¿   Ú__main__ÚDOTAv2zDOTAv2-split)rb   r½   )g�íµ ÷Æ°>)r5   ú
np.ndarrayr   rÉ   r6   ÚfloatÚreturnrÉ   )rL   )rb   rY   r_   rY   rË   zlist[dict[str, Any]])©é   ©éÈ   g333333ã?g{®Gáz„?)rz   ztuple[int, int]r{   útuple[int, ...]r|   rÐ   r}   rÊ   r6   rÊ   rË   rÉ   )gffffffæ?)r�   údict[str, Any]r~   rÉ   r‘   rÊ   rË   úlist[np.ndarray])T)r�   rÑ   r~   rÉ   r£   rÒ   rc   rY   r¤   rY   r¥   ÚboolrË   ÚNone)rL   rÌ   rÎ   )rb   rY   r½   rY   r_   rY   r{   rÐ   r|   rÐ   rË   rÔ   )rÍ   rÏ   )g      ð?)rb   rY   r½   rY   r   r¡   r€   r¡   rÁ   ztuple[float, ...]rË   rÔ   )Ú
__future__r   rt   r   Úmathr   Úpathlibr   Útypingr   rš   Únumpyr"   ÚPILr   Úultralytics.data.utilsr	   r
   Úultralytics.utilsr   Úultralytics.utils.checksr   rI   rn   r�   r”   r³   r¾   rÃ   rÆ   Ú__name__r   r¿   r   ú<module>rß      sÙ  ðõ #ã Ý Ý Ý Ý ã 
Û Ý ç =Ý "Ý 7ô+ô\ ðJ #*Ø"ØØð1+Øð1+àð1+ð ð1+ð ð	1+ð
 
ð1+ð ó1+ôhQð( %)ð0LØ
ð0Làð0Lð "ð0Lð ð	0Lð
 ð0Lð "ð0Lð 
ó0Lðl Ø")Ø"ð'LØð'Làð'Lð ð'Lð  ð	'Lð
 ð'Lð 
ó'LðV flð#NØð#NØ!ð#NØ.1ð#NØ?Bð#NØQbð#Nà	ó#NðN flð)EØð)EØ!ð)EØ.1ð)EØ?Bð)EØQbð)Eà	ó)EðX ˆzÒÙ˜X°Õ?Ù˜¨NÖ;ð r¿   