a
    yf)                     @   s   d dl 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mZ d dlmZ ed	 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d0d"d#Zd1d$d%Zed&k red'd(d) ed'd(d) dS )2    N)glob)ceil)Path)Image)tqdm)	exif_sizeimg2label_paths)check_requirementsZshapelyPolygonư>c              	      s  |  ddd} tj| dd}tj| dd}tj||gdd}t|dddddf  dddf }t|dddddf  dddf }t|| dtj}|d	 |d
  }	 fddt	dD \}
}}}tj
|
||||||
|gdd ddd}dd | D }dd |D }t|	j}tt|	 D ]&}||d  ||d  j||< q0tjdd |D tjd}|d }t||tj}|| }|jdkr|d }|S )a  
    Calculate Intersection over Foreground (IoF) between polygons and bounding boxes.

    Args:
        polygon1 (np.ndarray): Polygon coordinates, shape (n, 8).
        bbox2 (np.ndarray): Bounding boxes, shape (n, 4).
        eps (float, optional): Small value to prevent division by zero. Defaults to 1e-6.

    Returns:
        (np.ndarray): IoF scores, shape (n, 1) or (n, m) if bbox2 is (m, 4).

    Note:
        Polygon format: [x1, y1, x2, y2, x3, y3, x4, y4].
        Bounding box format: [x_min, y_min, x_max, y_max].
          ZaxisN.r   ).r   ).   c                 3   s   | ]} d |f V  qdS .N .0ibbox2r   W/var/www/html/django/DPS/env/lib/python3.9/site-packages/ultralytics/data/split_dota.py	<genexpr>.       zbbox_iof.<locals>.<genexpr>c                 S   s   g | ]}t |qS r   r
   r   pr   r   r   
<listcomp>1   r   zbbox_iof.<locals>.<listcomp>c                 S   s   g | ]}t |qS r   r
   r   r   r   r   r   2   r   c                 S   s   g | ]
}|j qS r   )arear   r   r   r   r   6   r   Zdtyper   r   )ZreshapenpminmaxconcatenatemaximumminimumclipinfrangestackzerosshapezipZnonzerointersectionr    arrayfloat32ndim)Zpolygon1r   epsZlt_pointZrb_pointZbbox1ltrbZwhZ
h_overlapslefttoprightbottomZpolygon2Z	sg_polys1Z	sg_polys2overlapsr   Zunionsoutputsr   r   r   bbox_iof   s,    **($r<   trainc              	   C   s   |dv sJ d| dt | d | }| s@J d| dttt | d | d }t|}g }t||D ]\}}tt|\}}	t|:}
dd	 |
	 
  D }tj|tjd
}W d   n1 s0    Y  |t|	|f||d qr|S )a  
    Load DOTA dataset.

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

    Notes:
        The directory structure assumed for the DOTA dataset:
            - data_root
                - images
                    - train
                    - val
                - labels
                    - train
                    - val
    >   valr=   z$Split must be 'train' or 'val', not .imagesCan't find , please check your data root.*c                 S   s   g | ]}t |r| qS r   )lensplit)r   xr   r   r   r   [   r   z"load_yolo_dota.<locals>.<listcomp>r!   N)ori_sizelabelfilepath)r   existsr   strr   r.   r   r   openreadstrip
splitlinesr"   r0   r1   appenddict)	data_rootrE   im_dirim_filesZlb_filesannosim_fileZlb_filewhflbr   r   r   load_yolo_dota@   s    
.r[         333333?{Gz?c                    s|  | \}}g }t ||D ]*\}}	||	ks>J d| d|	 d||	  ||krRdnt||   d }
 fddt|
D }t|dkr|d | |kr|| |d< ||krdnt||   d } fddt|D }t|dkr|d | |kr|| |d< tjtt||tj	d	}|| }|
tj||gdd
 qtj|dd
}| }t|dddddf d||dddddf< t|dddddf d||dddddf< |dddf |dddf  |dddf |dddf   }|dddf |dddf  |dddf |dddf   }|| }||k sp| }d|t|| |k < |||k S )aT  
    Get the coordinates of windows.

    Args:
        im_size (tuple): Original image size, (h, w).
        crop_sizes (List(int)): Crop size of windows.
        gaps (List(int)): Gap between crops.
        im_rate_thr (float): Threshold of windows areas divided by image ares.
        eps (float): Epsilon value for math operations.
    zinvalid crop_size gap pair [ ]r   c                    s   g | ]} | qS r   r   r   stepr   r   r   s   r   zget_windows.<locals>.<listcomp>r   c                    s   g | ]} | qS r   r   r   rd   r   r   r   x   r   r!   r   r   Nr      )r.   r   r*   rD   r"   r0   list	itertoolsproductZint64rP   r%   copyr(   anyr$   abs)Zim_size
crop_sizesgapsZim_rate_thrr3   rX   rW   windows	crop_sizegapZxnZxsZynZysstartstopZ
im_in_winsZim_areasZ	win_areasZim_ratesZmax_rater   rd   r   get_windowsa   s6       22@@rt   ffffff?c                    s   | d \}}| d t rdddddf  |9  < dddddf  |9  < tddddf | fddtt |D S dd tt |D S dS )	zGet objects for each window.rG   rH   Nr   r   c                    s$   g | ]}d d |f  k qS )Nr   r   iof_thrZiofsrH   r   r   r      r   z"get_window_obj.<locals>.<listcomp>c                 S   s   g | ]}t jd t jdqS ))r   	   r!   )r"   r,   r1   )r   _r   r   r   r      r   )rD   r<   r*   )annoro   rw   rX   rW   r   rv   r   get_window_obj   s    r{   Tc              
   C   s  t | d }t| d j}t|D ]\}}	|	 \}
}}}| d||
  d|
 d| }||||
|f }|jdd \}}|| }t|s|rt t	t|| d | t|r$|dddddf  |
8  < |dddddf  |8  < |dddddf  |  < |dddddf  |  < t
t|| d d	V}|D ]@}d
d |dd D }|t|d  dd| d qRW d   q$1 s0    Y  q$dS )a  
    Crop images and save new labels.

    Args:
        anno (dict): Annotation dict, including `filepath`, `label`, `ori_size` as its keys.
        windows (list): A list of windows coordinates.
        window_objs (list): 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): Whether to include background images without labels.

    Notes:
        The directory structure assumed for the DOTA dataset:
            - data_root
                - images
                    - train
                    - val
                - labels
                    - train
                    - val
    rI   _____Nr   .jpgr   z.txtrW   c                 S   s   g | ]}|d qS )z.6gr   )r   Zcoordr   r   r   r      r   z!crop_and_save.<locals>.<listcomp>r   rb   
)cv2imreadr   stem	enumeratetolistr-   rD   imwriterK   rL   writeintjoin)rz   ro   window_objsrS   lb_dirZallow_background_imagesimnamer   windowx_starty_startx_stopy_stopnew_namepatch_imphpwrH   rY   rZ   Zformatted_coordsr   r   r   crop_and_save   s&    r   c                 C   s   t |d | }|jddd t |d | }|jddd t| |d}t|t||dD ]6}t|d ||}	t||	}
t||	|
t|t| qZdS )	a  
    Split both images and labels.

    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
    r@   Tparentsexist_oklabels)rE   totaldescrG   N)	r   mkdirr[   r   rD   rt   r{   r   rK   )rR   save_dirrE   rm   rn   rS   r   rU   rz   ro   r   r   r   r   split_images_and_labels   s    
r   r]   r_   g      ?c           	      C   sV   g g  }}|D ](}| t||  | t||  qdD ]}t| |||| q<dS )a  
    Split train and val set of DOTA.

    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
    )r=   r>   N)rP   r   r   )	rR   r   rp   rq   ratesrm   rn   rrE   r   r   r   split_trainval   s    
r   c              	   C   sH  g g  }}|D ](}| t||  | t||  qt|d d }|jddd t| d d }| s~J d| dtt|d }	t|	t|	ddD ]}
t	t
|
\}}t||f||d	}t|
}t|
j}|D ]`}| \}}}}| d
||  d
| d| }|||||f }tt|| d | qqdS )aZ  
    Split test set of DOTA, labels are not included within this set.

    Notes:
        The directory structure assumed for the DOTA dataset:
            - data_root
                - images
                    - test
        and the output directory structure is:
            - save_dir
                - images
                    - test
    r@   testTr   rA   rB   rC   r   )rm   rn   r|   r}   r~   N)rP   r   r   r   rJ   r   rK   r   rD   r   r   rL   rt   r   r   r   r   r   )rR   r   rp   rq   r   rm   rn   r   rS   rT   rV   rW   rX   ro   r   r   r   r   r   r   r   r   r   r   r   r   
split_test  s&    


r   __main__ZDOTAv2zDOTAv2-split)rR   r   )r   )r=   )r\   r^   r`   ra   )ru   )T)r=   r\   r^   )r]   r_   r   )r]   r_   r   )rh   r   mathr   pathlibr   r   numpyr"   ZPILr   r   Zultralytics.data.utilsr   r   Zultralytics.utils.checksr	   Zshapely.geometryr   r<   r[   rt   r{   r   r   r   r   __name__r   r   r   r   <module>   s,   
,
!
,

-


$
