
    |h]2                        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
 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
ej.                  dej.                  dedej.                  fdZd-dedede	eeef      fdZ	 	 	 	 d.de
eef   de
edf   de
edf   dededej.                  fdZd/deeef   dej.                  dede	ej.                     fdZ	 d0deeef   dej.                  de	ej.                     dedededdfd Z 	 	 	 d1ded!edede
edf   de
edf   ddfd"Z!	 d2ded!ed#ed$ed%e
edf   ddfd&Z"	 d2ded!ed#ed$ed%e
edf   ddfd'Z#e$d(k(  r e"d)d*+        e#d)d*+       yy)3    N)glob)ceil)Path)AnyDictListTuple)Image)	exif_sizeimg2label_paths)TQDM)check_requirementspolygon1bbox2epsreturnc           
         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 (N, 4).
        eps (float, optional): Small value to prevent division by zero.

    Returns:
        (np.ndarray): IoF scores with shape (N, 1) or (N, M) if bbox2 is (M, 4).

    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ir   s     Z/var/www/html/test/engine/venv/lib/python3.12/site-packages/ultralytics/data/split_dota.py	<genexpr>zbbox_iof.<locals>.<genexpr>/   s     @!c1f@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)r   r   r   r   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_iofrL      s$     '((Aq)HvvhR(HvvhR(HNNHh/b9E	E!T2A2+&c2A2g	7B	E!T12+&c12g	7B	b!RVV	$BFbj(J@uQx@D#ufxxsE3vtVLSUV^^_acdfghH%-..I.%-..I.xx
(()H"**Z() J!o229QrU3CDIIJXXy1!qvv1DFIFWWVS"&&)FG||q)$N /. 2s   ;III	data_rootsplitc                    |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)a1  
    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   r3   r   r
   openreadstrip
splitlineslenrN   r'   r7   r8   appenddict)rM   rN   im_dirim_fileslb_filesannosim_filelb_filewhfxlbs                r!   load_yolo_dotarq   A   sJ   * $$U(LUGST&UU$)_x'%/F==?Pk&1OPP?CY(2U:S@ABHx(HE(3 HG,-1'G, 	0%&VVX^^%5%@%@%BMc!f!'')MBM"BJJ/B	0 	TAq6gFGH L N	0 	0s$   //EE/E'EEE!	im_size
crop_sizes.gapsim_rate_thrc           	         | \  }}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 )a6  
    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 of windows areas divided by image areas.
        eps (float, optional): Epsilon value for math operations.

    Returns:
        (np.ndarray): Array of window coordinates with 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      )r3   r   r/   rc   r'   r7   list	itertoolsproductint64rd   r*   copyr-   anyr)   abs)rr   rs   rt   ru   r   rm   rl   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   ( DAqGj$/ >	33Q">yk3%q QQ3y.QdA	MT+AA+E&F %b	*1dQh**r7Q;2b6I-1]BrFy.QdA	MT+AA+E&F %b	*1dQh**r7Q;2b6I-1]BrFi//B78Iy r~~udm!<=!>" nnW1-GJ''*Q1W"5q!<Jq!$Q$w''*Q1W"5q!<Jq!$Q$w1a4 :ad#33
1a48H:VWYZVZK[8[\HAA.71a4=71a4=3PQI)#H{"'')<<>34X()C/08k)**/ +
 +s   I"2I'annor   iof_thrc                    | 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.rZ   r[   Nr   r   )r   	   r#   )rc   rL   r/   r'   r1   r8   )	r   r   r   rm   rl   r[   iofsr    _s	            r!   get_window_objr      s    
DAqME
5zaAg!aAg!aeg.8=c'l8KL1tAqDzW,-LL<A#g,<OPqrzz2PP MPs   ,C
,Cwindow_objsrf   lb_dirallow_background_imagesc           
      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
    r\   _____Nr   .jpgr   z.txtrl   rW   rX   z.6gr   rw   
)cv2imreadr   stem	enumeratetolistr2   rc   imwriter^   r_   writeintjoin)r   r   r   rf   r   r   imnamer    windowx_starty_startx_stopy_stopnew_namepatch_imphpwr[   rn   rp   coordformatted_coordss                          r!   crop_and_saver      s   : 
D$	%BZ !&&Dw' L	6+1==?(&&V2fw./r'#gYGgfngfn45#BAu:0KKDLhZt+<<=xHu:!QTT'Ng%N!QTT'Ng%N!QTT'Nb N!QTT'Nb Nd6lz%66gN LRS LBDFqrF'K55+'K$'KGGs2a5zl!CHH5E,F+GrJKLL LL" (LL Ls   >FF
6FFF(	save_dirc           
      `   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
    rS   Tparentsexist_oklabels)rN   totaldescrZ   N)	r   mkdirrq   r   rc   r   r   r   r^   )rM   r   rN   rs   rt   rf   r   ri   r   r   r   s              r!   split_images_and_labelsr      s    > (^h&.F
LLL-(^h&.F
LLL-9E2EU#e*59 Ld:.
DA$T73dG[#f+s6{KL    r   r   ratesc                     g g }}|D ]<  }|j                  t        ||z               |j                  t        ||z               > dD ]  }t        | ||||        y)am  
    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
    >   rP   rQ   N)rd   r   r   )	rM   r   r   r   r   rs   rt   rrN   s	            r!   split_trainvalr     sj    > 2J "#i!m,-CaL!" " N	8UJ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
    rS   testTr   rT   rU   rV   r   )rs   rt   r   r   r   N)rd   r   r   r   r]   r   r^   r   rc   r   r
   r_   r   r   r   r   r   r   )rM   r   r   r   r   rs   rt   r   rf   rg   rj   rl   rm   r   r   r   r   r   r   r   r   r   r   s                          r!   
split_testr   .  s   . 2J "#i!m,-CaL!" H~(61HNN4$N/)_x'&0F==?Pk&1OPP?C%&HHFC 	EG,-1q!f$GZZ G}!! 	EF/5}},GWffr&7"2!32gYc'KH'&.'&.89HKKH(4'8898D		E	Er   __main__DOTAv2zDOTAv2-split)rM   r   )gư>)rQ   )      g333333?g{Gz?)gffffff?)T)rQ   r   r   )r   r   )g      ?)%r{   r   mathr   pathlibr   typingr   r   r   r	   r   numpyr'   PILr
   ultralytics.data.utilsr   r   ultralytics.utilsr   ultralytics.utils.checksr   ndarrayfloatrL   r^   rq   r   r   r   boolr   r   r   r   __name__r   r   r!   <module>r      s       ) ) 
   = " 7,rzz ,"** ,5 ,BJJ ,^!c !# !Dc3h<P !L #*"2+38_2+c3h2+ S/2+ 	2+
 
2+ ZZ2+jQc3h Q"** Qu QW[\^\f\fWg Q( %)1L
sCx.1LZZ1L bjj!1L 	1L
 1L "1L 
1Ln ")"(L(L(L (L c3h	(L
 S/(L 
(LX fl$N$N!$N.1$N?B$NQVW\^aWaQb$N	$NP fl*E*E!*E.1*E?B*EQVW\^aWaQb*E	*EZ zX?N; r   