
    jI2                    6   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 dCdDdZdEdFdZ	 	 	 	 dGdHd#ZdIdJd*Z	 dKdLd2Z	 	 	 dMdNd4Z	 dOdPd=Z	 dOdPd>Zed?k    r ed@dAB            ed@dAB           dS dS )Q    )annotationsN)glob)ceil)Path)Any)Image)	exif_sizeimg2label_paths)TQDM)check_requirementsư>polygon1
np.ndarraybbox2epsfloatreturnc           
        t          d           ddlm |                     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                              ddd          }fd| D             }fd|D             }t	          j        |	j                  }t!          t	          j        |	           D ]7}||d                                      ||d                            j        ||<   8t	          j        d |D             t          j                  }|d         }t	          j
        ||t          j                  }||z  }|j        dk    r|d         }|S )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         V  dS .N ).0ir   s     `/home/longshao/multi-rider-rag/.venv/lib/python3.11/site-packages/ultralytics/data/split_dota.py	<genexpr>zbbox_iof.<locals>.<genexpr>0   s+      @@!c1f@@@@@@    c                &    g | ]} |          S r   r   r    pr   s     r"   
<listcomp>zbbox_iof.<locals>.<listcomp>3   !    ......r$   c                &    g | ]} |          S r   r   r&   s     r"   r(   zbbox_iof.<locals>.<listcomp>4   r)   r$   c                    g | ]	}|j         
S r   )area)r    r'   s     r"   r(   zbbox_iof.<locals>.<listcomp>8   s    111!qv111r$   dtyper   r   )r   shapely.geometryr   reshapenpminmaxconcatenatemaximumminimumclipinfrangestackzerosshapezipnonzerointersectionr,   arrayfloat32ndim)r   r   r   lt_pointrb_pointbbox1ltrbwh
h_overlapslefttoprightbottompolygon2	sg_polys1	sg_polys2overlapsr'   unionsoutputsr   s    `                   @r"   bbox_iofrT      sh    '(((((((((Aq))HvhR(((HvhR(((HNHh/b999E	E!!!T2A2+&c2A2g	7	7B	E!!!T122+&c122g	7	7B	b!RV	$	$BFbj(J@@@@uQxx@@@D#ufxsE3vtVLSUVVV^^_acdfghhH....X...I....X...Ix
())H"*Z(() J J!o229QrU3CDDIX11y111DDDFIFWVS"&))FG|q)$Nr$   train	data_rootstrsplitlist[dict[str, Any]]c                   |dv sJ d| d            t          |           dz  |z  }|                                sJ d| d            t          t          t          |           dz  |z  dz                      }t	          |          }g }t          ||          D ]\  }}t          t          j        |                    \  }}	t          |d	          5 }
d
 |
	                                
                                                                D             }t          j        |t          j                  }ddd           n# 1 swxY w Y   |                    t!          |	|f||                     |S )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
    >   valrU   z$Split must be 'train' or 'val', not .imagesCan't find , please check your data root.*utf-8encodingc                T    g | ]%}t          |          |                                &S r   )lenrX   )r    xs     r"   r(   z"load_yolo_dota.<locals>.<listcomp>_   s+    MMMc!ffM!''))MMMr$   r-   N)ori_sizelabelfilepath)r   existsr   rW   r
   r=   r	   r   openreadstrip
splitlinesr1   r@   rA   appenddict)rV   rX   im_dirim_fileslb_filesannosim_filelb_filewhflbs               r"   load_yolo_dotar{   B   s   ( $$$$&UU&U&U&U$$$)__x'%/F==??PPP&PPPPP?CY(2U:S@AABBHx((HE(33 H HG,,--1'G,,, 	0MMQVVXX^^%5%5%@%@%B%BMMMB"BJ///B	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	TAq6gFFFGGGGLs   A#EE
	E
	      333333?{Gz?im_sizetuple[int, int]
crop_sizestuple[int, ...]gapsim_rate_thrc           	     n   | \  }}g }t          ||          D ]\\  }}	||	k    sJ d| d|	 d            ||	z
  ||k    rdnt          ||z
  z  dz             }
fdt          |
          D             }t          |          dk    r|d         |z   |k    r||z
  |d<   ||k    rdnt          ||z
  z  dz             }fdt          |          D             }t          |          dk    r|d         |z   |k    r||z
  |d<   t	          j        t          t          j        ||                    t          j	                  }||z   }|
                    t	          j        ||gd	                     ^t	          j        |d
	          }|                                }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  }||k                                    s-|                                }d|t!          ||z
            |k     <   |||k             S )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   c                    g | ]}|z  S r   r   r    r!   steps     r"   r(   zget_windows.<locals>.<listcomp>       ***1dQh***r$   r   c                    g | ]}|z  S r   r   r   s     r"   r(   zget_windows.<locals>.<listcomp>   r   r$   r-   r   r   Nr      )r=   r   r9   re   r1   r@   list	itertoolsproductint64ro   r4   copyr7   anyr3   abs)r   r   r   r   r   rx   rw   windows	crop_sizegapxnxsynysstartstop
im_in_winsim_areas	win_areasim_ratesmax_rater   s                        @r"   get_windowsr   e   s'   & DAqGj$// > >	33 Qy Q Q3 Q Q Q3y..QQdA	MT+AA+E&F&F****b		***r77Q;;2b6I-11]BrFy..QQdA	MT+AA+E&F&F****b		***r77Q;;2b6I-11]BrFi/B7788IIIy r~udm!<<<====nW1---GJ'*QQQ1W"5q!<<Jqqq!$Q$w'*QQQ1W"5q!<<Jqqq!$Q$w111a4 :aaad#33
111a48H:VWVWVWYZVZK[8[\HAA.7111a4=7111a4=3PQI)#H{"'')) 5<<>>34X())C/08k)**r$   ffffff?annodict[str, Any]r   iof_thrlist[np.ndarray]c                   | d         \  }}| d         t                    rt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         |          fdt          t          |                    D             S d t          t          |                    D             S )z3Get objects for each window based on IoF threshold.rg   rh   Nr   r   c                <    g | ]}d d |f         k             S )Nr   )r    r!   r   iofsrh   s     r"   r(   z"get_window_obj.<locals>.<listcomp>   s/    LLL1tAAAqDzW,-LLLr$   c                N    g | ]"}t          j        d t           j                  #S ))r   	   r-   )r1   r;   rA   )r    _s     r"   r(   z"get_window_obj.<locals>.<listcomp>   s)    PPPqrz222PPPr$   )re   rT   r9   )r   r   r   rx   rw   r   rh   s     `  @@r"   get_window_objr      s    
DAqME
5zz QaaaAg!aaaAg!aaaeg..LLLLLLc'll8K8KLLLLPPE#g,,<O<OPPPPr$   Twindow_objsrq   lb_dirallow_background_imagesboolNonec           
        t          j        | d                   }t          | d                   j        }t	          |          D ]\  }}	|	                                \  }
}}}| d||
z
   d|
 d| }||||
|f         }|j        dd         \  }}||         }t          |          s|r5t          j        t          t          |          | dz            |           t          |          r|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 ]W}d |dd         D             }|                    t          |d                    dd                    |           d           X	 ddd           n# 1 swxY w Y   dS )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
    ri   _____Nr   .jpgr   z.txtrw   ra   rb   c                    g | ]}|d S )z.6gr   )r    coords     r"   r(   z!crop_and_save.<locals>.<listcomp>   s    'K'K'K55'K'K'Kr$   r   r   
)cv2imreadr   stem	enumeratetolistr<   re   imwriterW   rk   writeintjoin)r   r   r   rq   r   r   imnamer!   windowx_starty_startx_stopy_stopnew_namepatch_imphpwrh   ry   rz   formatted_coordss                         r"   crop_and_saver      s   8 
D$	%	%BZ !!&Dw'' L L	6+1==??(&&GGfw.GG'GGgGGgfngfn45#BAu:: 	I0 	IKDLLh+<+<+<<==xHHHu:: 		L!!!QTT'NNNg%NNN!!!QTT'NNNg%NNN!!!QTT'NNNb NNN!!!QTT'NNNb NNNd6ll%6%6%66gNNN LRS L LB'K'KBqrrF'K'K'K$GGs2a5zzJJCHH5E,F,FJJJKKKKLL L L L L L L L L L L L L L LL Ls   1AGG	 G	save_dirc           
        t          |          dz  |z  }|                    dd           t          |          dz  |z  }|                    dd           t          | |          }t          |t	          |          |          D ]V}t          |d         ||          }	t          ||	          }
t          ||	|
t          |          t          |                     WdS )	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
    r]   Tparentsexist_oklabels)rX   totaldescrg   N)	r   mkdirr{   r   re   r   r   r   rW   )rV   r   rX   r   r   rq   r   rt   r   r   r   s              r"   split_images_and_labelsr      s    < (^^h&.F
LLL---(^^h&.F
LLL---9E222EU#e**5999 L Ld:.
DAA$T733dG[#f++s6{{KKKKL Lr$   r}   r   g      ?r   r   r   ratestuple[float, ...]c                    g g }}|D ]L}|                     t          ||z                       |                     t          ||z                       MdD ]}t          | ||||           dS )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
    >   r[   rU   N)ro   r   r   )	rV   r   r   r   r   r   r   rrX   s	            r"   split_trainvalr     s    < 2J " "#i!m,,---CaLL!!!!! N N	8UJMMMMN Nr$   c           	     |   g g }}|D ]L}|                     t          ||z                       |                     t          ||z                       Mt          |          dz  dz  }|                    dd           t          |           dz  dz  }|                                sJ d| d            t          t          |dz                      }	t          |	t          |	          d          D ]}
t          t          j        |
                    \  }}t          ||f||	          }t          j        |
          }t          |
          j        }|D ]a}|                                \  }}}}| d
||z
   d
| d| }|||||f         }t          j        t          || dz            |           bdS )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
    r]   testTr   r^   r_   r`   r   )r   r   r   r   r   N)ro   r   r   r   rj   r   rW   r   re   r	   r   rk   r   r   r   r   r   r   )rV   r   r   r   r   r   r   r   rq   rr   ru   rw   rx   r   r   r   r   r   r   r   r   r   r   s                          r"   
split_testr   *  s   , 2J " "#i!m,,---CaLL!!!!H~~(61HNN4$N///)__x'&0F==??PPP&PPPPP?C%%&&HHFCCC 	E 	EG,,--1q!f$GGGZ  G}}! 	E 	EF/5}},GWffKK&7"2KKgKK'KKH'&.'&.89HKH('8'8'88998DDDD		E	E 	Er$   __main__DOTAv2zDOTAv2-split)rV   r   )r   )r   r   r   r   r   r   r   r   )rU   )rV   rW   rX   rW   r   rY   )r|   r~   r   r   )r   r   r   r   r   r   r   r   r   r   r   r   )r   )r   r   r   r   r   r   r   r   )T)r   r   r   r   r   r   rq   rW   r   rW   r   r   r   r   )rU   r|   r~   )rV   rW   r   rW   rX   rW   r   r   r   r   r   r   )r}   r   r   )rV   rW   r   rW   r   r   r   r   r   r   r   r   )
__future__r   r   r   mathr   pathlibr   typingr   r   numpyr1   PILr   ultralytics.data.utilsr	   r
   ultralytics.utilsr   ultralytics.utils.checksr   rT   r{   r   r   r   r   r   r   __name__r   r$   r"   <module>r      s)   # " " " " "                             



           = = = = = = = = " " " " " " 7 7 7 7 7 7+ + + + +\         J #*"1+ 1+ 1+ 1+ 1+hQ Q Q Q Q( %)0L 0L 0L 0L 0Ll ")"'L 'L 'L 'L 'LV fl#N #N #N #N #NN fl)E )E )E )E )EX zNX????JN;;;;;; r$   