o
    Wh                  #   @   sl  d dl Z d dlZd dlmZ d dlmZmZmZmZm	Z	 d dl
Z
d dlmZ d dlZd dlZd dlmZmZmZ d dlmZ d dlmZmZmZmZmZmZmZ d dlm Z m!Z!m"Z" d dl#m$Z$ G d	d
 d
Z%e% Z&G dd dZ'e e deddfddZ(eddddddfddZ)eej*d ej+ddej*d ej,dej*dej+dddddddddfde	ej-ej.f de	ej-ej.f d e	ej-ej.f d!e	ej-ej.f d"ee	ej-ej.f  d#e	ej-ej.f d$e	ej-ej.f d%eee/  d&e/d'eee0e/f  d(ee d)e0d*e0d+e1d,e2d-eej. f d.d/Z3e dEd1d2Z4dFd7d8Z5dGd:d;Z6dHd=d>Z7dHd?d@Z8dAedBfdCdDZ9dS )I    N)Path)CallableDictListOptionalUnion)Image	ImageDraw	ImageFont)__version__)IS_COLAB	IS_KAGGLELOGGER	TryExceptopsplt_settingsthreaded)
check_fontcheck_versionis_ascii)increment_pathc                   @   s.   e Zd ZdZdd Zd
ddZedd Zd	S )ColorsaG  
    Ultralytics color palette https://docs.ultralytics.com/reference/utils/plotting/#ultralytics.utils.plotting.Colors.

    This class provides methods to work with the Ultralytics color palette, including converting hex color codes to
    RGB values.

    Attributes:
        palette (List[Tuple]): List of RGB color values.
        n (int): The number of colors in the palette.
        pose_palette (np.ndarray): A specific color palette array for pose estimation with dtype np.uint8.

    Examples:
        >>> from ultralytics.utils.plotting import Colors
        >>> colors = Colors()
        >>> colors(5, True)  # ff6fdd or (255, 111, 221)

    ## Ultralytics Color Palette

    | Index | Color                                                             | HEX       | RGB               |
    |-------|-------------------------------------------------------------------|-----------|-------------------|
    | 0     | <i class="fa-solid fa-square fa-2xl" style="color: #042aff;"></i> | `#042aff` | (4, 42, 255)      |
    | 1     | <i class="fa-solid fa-square fa-2xl" style="color: #0bdbeb;"></i> | `#0bdbeb` | (11, 219, 235)    |
    | 2     | <i class="fa-solid fa-square fa-2xl" style="color: #f3f3f3;"></i> | `#f3f3f3` | (243, 243, 243)   |
    | 3     | <i class="fa-solid fa-square fa-2xl" style="color: #00dfb7;"></i> | `#00dfb7` | (0, 223, 183)     |
    | 4     | <i class="fa-solid fa-square fa-2xl" style="color: #111f68;"></i> | `#111f68` | (17, 31, 104)     |
    | 5     | <i class="fa-solid fa-square fa-2xl" style="color: #ff6fdd;"></i> | `#ff6fdd` | (255, 111, 221)   |
    | 6     | <i class="fa-solid fa-square fa-2xl" style="color: #ff444f;"></i> | `#ff444f` | (255, 68, 79)     |
    | 7     | <i class="fa-solid fa-square fa-2xl" style="color: #cced00;"></i> | `#cced00` | (204, 237, 0)     |
    | 8     | <i class="fa-solid fa-square fa-2xl" style="color: #00f344;"></i> | `#00f344` | (0, 243, 68)      |
    | 9     | <i class="fa-solid fa-square fa-2xl" style="color: #bd00ff;"></i> | `#bd00ff` | (189, 0, 255)     |
    | 10    | <i class="fa-solid fa-square fa-2xl" style="color: #00b4ff;"></i> | `#00b4ff` | (0, 180, 255)     |
    | 11    | <i class="fa-solid fa-square fa-2xl" style="color: #dd00ba;"></i> | `#dd00ba` | (221, 0, 186)     |
    | 12    | <i class="fa-solid fa-square fa-2xl" style="color: #00ffff;"></i> | `#00ffff` | (0, 255, 255)     |
    | 13    | <i class="fa-solid fa-square fa-2xl" style="color: #26c000;"></i> | `#26c000` | (38, 192, 0)      |
    | 14    | <i class="fa-solid fa-square fa-2xl" style="color: #01ffb3;"></i> | `#01ffb3` | (1, 255, 179)     |
    | 15    | <i class="fa-solid fa-square fa-2xl" style="color: #7d24ff;"></i> | `#7d24ff` | (125, 36, 255)    |
    | 16    | <i class="fa-solid fa-square fa-2xl" style="color: #7b0068;"></i> | `#7b0068` | (123, 0, 104)     |
    | 17    | <i class="fa-solid fa-square fa-2xl" style="color: #ff1b6c;"></i> | `#ff1b6c` | (255, 27, 108)    |
    | 18    | <i class="fa-solid fa-square fa-2xl" style="color: #fc6d2f;"></i> | `#fc6d2f` | (252, 109, 47)    |
    | 19    | <i class="fa-solid fa-square fa-2xl" style="color: #a2ff0b;"></i> | `#a2ff0b` | (162, 255, 11)    |

    ## Pose Color Palette

    | Index | Color                                                             | HEX       | RGB               |
    |-------|-------------------------------------------------------------------|-----------|-------------------|
    | 0     | <i class="fa-solid fa-square fa-2xl" style="color: #ff8000;"></i> | `#ff8000` | (255, 128, 0)     |
    | 1     | <i class="fa-solid fa-square fa-2xl" style="color: #ff9933;"></i> | `#ff9933` | (255, 153, 51)    |
    | 2     | <i class="fa-solid fa-square fa-2xl" style="color: #ffb266;"></i> | `#ffb266` | (255, 178, 102)   |
    | 3     | <i class="fa-solid fa-square fa-2xl" style="color: #e6e600;"></i> | `#e6e600` | (230, 230, 0)     |
    | 4     | <i class="fa-solid fa-square fa-2xl" style="color: #ff99ff;"></i> | `#ff99ff` | (255, 153, 255)   |
    | 5     | <i class="fa-solid fa-square fa-2xl" style="color: #99ccff;"></i> | `#99ccff` | (153, 204, 255)   |
    | 6     | <i class="fa-solid fa-square fa-2xl" style="color: #ff66ff;"></i> | `#ff66ff` | (255, 102, 255)   |
    | 7     | <i class="fa-solid fa-square fa-2xl" style="color: #ff33ff;"></i> | `#ff33ff` | (255, 51, 255)    |
    | 8     | <i class="fa-solid fa-square fa-2xl" style="color: #66b2ff;"></i> | `#66b2ff` | (102, 178, 255)   |
    | 9     | <i class="fa-solid fa-square fa-2xl" style="color: #3399ff;"></i> | `#3399ff` | (51, 153, 255)    |
    | 10    | <i class="fa-solid fa-square fa-2xl" style="color: #ff9999;"></i> | `#ff9999` | (255, 153, 153)   |
    | 11    | <i class="fa-solid fa-square fa-2xl" style="color: #ff6666;"></i> | `#ff6666` | (255, 102, 102)   |
    | 12    | <i class="fa-solid fa-square fa-2xl" style="color: #ff3333;"></i> | `#ff3333` | (255, 51, 51)     |
    | 13    | <i class="fa-solid fa-square fa-2xl" style="color: #99ff99;"></i> | `#99ff99` | (153, 255, 153)   |
    | 14    | <i class="fa-solid fa-square fa-2xl" style="color: #66ff66;"></i> | `#66ff66` | (102, 255, 102)   |
    | 15    | <i class="fa-solid fa-square fa-2xl" style="color: #33ff33;"></i> | `#33ff33` | (51, 255, 51)     |
    | 16    | <i class="fa-solid fa-square fa-2xl" style="color: #00ff00;"></i> | `#00ff00` | (0, 255, 0)       |
    | 17    | <i class="fa-solid fa-square fa-2xl" style="color: #0000ff;"></i> | `#0000ff` | (0, 0, 255)       |
    | 18    | <i class="fa-solid fa-square fa-2xl" style="color: #ff0000;"></i> | `#ff0000` | (255, 0, 0)       |
    | 19    | <i class="fa-solid fa-square fa-2xl" style="color: #ffffff;"></i> | `#ffffff` | (255, 255, 255)   |

    !!! note "Ultralytics Brand Colors"

        For Ultralytics brand colors see [https://www.ultralytics.com/brand](https://www.ultralytics.com/brand). Please use the official Ultralytics colors for all marketing materials.
    c                    s   d} fdd|D  _ t j  _tjg dg dg dg dg dg d	g d
g dg dg dg dg dg dg dg dg dg dg dg dg dgtjd _dS )zEInitialize colors as hex = matplotlib.colors.TABLEAU_COLORS.values().)042AFF0BDBEBF3F3F300DFB7111F68FF6FDDFF444FCCED0000F344BD00FF00B4FFDD00BA00FFFF26C00001FFB37D24FF7B0068FF1B6CFC6D2FA2FF0Bc                    s   g | ]
}  d | qS )#)hex2rgb).0cself N/var/www/vscode/kcb/lib/python3.10/site-packages/ultralytics/utils/plotting.py
<listcomp>t   s    z#Colors.__init__.<locals>.<listcomp>)      r   )r5      3   )r5      f   )   r;   r   )r5   r7   r5   )r7      r5   )r5   r:   r5   )r5   r8   r5   )r:   r9   r5   )r8   r7   r5   )r5   r7   r7   )r5   r:   r:   )r5   r8   r8   )r7   r5   r7   )r:   r5   r:   )r8   r5   r8   )r   r5   r   )r   r   r5   )r5   r   r   r5   r5   r5   dtypeN)palettelennnparrayuint8pose_palette)r1   hexsr2   r0   r3   __init__\   s6   zColors.__init__Fc                 C   s2   | j t|| j  }|r|d |d |d fS |S )z&Convert hex color codes to RGB values.      r   )r@   intrB   )r1   ibgrr/   r2   r2   r3   __call__   s   zColors.__call__c                    s   t  fdddD S )z?Convert hex color codes to RGB values (i.e. default PIL order).c                 3   s.    | ]}t  d | d | d  dV  qdS )rJ   rI      NrK   r.   rL   hr2   r3   	<genexpr>   s   , z!Colors.hex2rgb.<locals>.<genexpr>)r   rI      tuplerR   r2   rR   r3   r-      s   zColors.hex2rgbN)F)__name__
__module____qualname____doc__rH   rN   staticmethodr-   r2   r2   r2   r3   r      s    G
4r   c                   @   s   e Zd Z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
dd Zd d! Zd0d"d#Zd1d%d&Zed0d'd(ZdS )2	Annotatora{  
    Ultralytics Annotator for train/val mosaics and JPGs and predictions annotations.

    Attributes:
        im (Image.Image or np.ndarray): The image to annotate.
        pil (bool): Whether to use PIL or cv2 for drawing annotations.
        font (ImageFont.truetype or ImageFont.load_default): Font used for text annotations.
        lw (float): Line width for drawing.
        skeleton (List[List[int]]): Skeleton structure for keypoints.
        limb_color (List[int]): Color palette for limbs.
        kpt_color (List[int]): Color palette for keypoints.
        dark_colors (set): Set of colors considered dark for text contrast.
        light_colors (set): Set of colors considered light for text contrast.

    Examples:
        >>> from ultralytics.utils.plotting import Annotator
        >>> im0 = cv2.imread("test.png")
        >>> annotator = Annotator(im0, line_width=10)
    N	Arial.ttfFabcc           
         s.  t | }t|tj}|p|p| _|p&ttt|r|jn|jd d d _	 jr|r/|nt
| _ jjdvrB jd _t jd _z$t|rPdn|}|pcttt jjd d d}	tt||	 _W n ty|   t  _Y nw ttd	r fd
d j_n4|jd dkrt|dddf }|jjsJ d|jj r|n|!  _t j	d d _" j	d  _#ddgddgddgddgddgddgddgddgddgddgddgddgddgddgddgddgddgddgddgg _$t%j&g d  _'t%j&g d  _(h d  _)h d! _*dS )"zjInitialize the Annotator class with image and line width along with color palette for keypoints and limbs.rI   g~jth?>   RGBRGBAr`   ra   zArial.Unicode.ttfgQ?   z9.2.0c                    s    j | dd S )NrI   rU   )fontgetbbox)xr0   r2   r3   <lambda>       z$Annotator.__init__.<locals>.<lambda>   .NzOImage not contiguous. Apply np.ascontiguousarray(im) to Annotator input images.rJ   rO                        	   
      rU      )rp   rp   rp   rp   rn   rn   rn   r   r   r   r   r   rO   rO   rO   rO   rO   rO   rO   )rO   rO   rO   rO   rO   r   r   r   r   r   r   rp   rp   rp   rp   rp   rp   >	   r      r<   rr   r5      D      r      r5   rJ         r      o   r5         rr   rz   rz   rz   r5   r5   r   >   r      &   /   m      O   ry   r5   h   r   {   l      r5      r   r   r5   r      r5   $   }   r5   *   rU   r5      r   r      rj   )+r   
isinstancer   pilmaxroundsumsizeshapelw	fromarrayimmodeconvertr	   Drawdrawr   r
   truetypestrrc   	Exceptionload_defaultr   pil_versiongetsizerC   ascontiguousarraydata
contiguousflags	writeablecopytfsfskeletoncolorsrF   
limb_color	kpt_colordark_colorslight_colors)
r1   r   
line_width	font_sizerc   r   example	non_asciiinput_is_pilr   r2   r0   r3   rH      sb   
,"

zAnnotator.__init__r6   r6   r6   r=   c                 C   s    || j v rdS || jv rdS |S )aE  
        Assign text color based on background color.

        Args:
            color (tuple, optional): The background color of the rectangle for text (B, G, R).
            txt_color (tuple, optional): The color of the text (R, G, B).

        Returns:
            (tuple): Text color for label.

        Examples:
            >>> from ultralytics.utils.plotting import Annotator
            >>> im0 = cv2.imread("test.png")
            >>> annotator = Annotator(im0, line_width=10)
            >>> annotator.get_txt_color(color=(104, 31, 17))  # return (255, 255, 255)
        r   r=   )r   r   )r1   color	txt_colorr2   r2   r3   get_txt_color   s
   

zAnnotator.get_txt_color c              
   C   s  |  ||}t|tjr| }| jst|s|r-|d }| jjdd |D | j	|d n|d |d f}| jj
|| j	|d |r| j|\}}|d |k}	|d | jjd | krg| jjd | |d f}| jj
|d |	ru|d | n|d |d | d |	r|d d n|d | d f|d | jj|d |	r|d | n|d f||| jd dS dS |rdd |d D }t| jtj|td	gd
|| j	 n't|d t|d ft|d t|d f}}
tj
| j||
|| j	tjd |rptj|d| j| jdd \}}|d7 }|d |k}	|d | jjd | kr)| jjd | |d f}|d | |	r7|d | n|d | f}
t
| j||
|dtj tj| j||d |	r[|d d n|d | d fd| j|| jtjd dS dS )a  
        Draw a bounding box on an image with a given label.

        Args:
            box (tuple): The bounding box coordinates (x1, y1, x2, y2).
            label (str, optional): The text label to be displayed.
            color (tuple, optional): The background color of the rectangle (B, G, R).
            txt_color (tuple, optional): The color of the text (R, G, B).
            rotated (bool, optional): Whether the task is oriented bounding box detection.

        Examples:
            >>> from ultralytics.utils.plotting import Annotator
            >>> im0 = cv2.imread("test.png")
            >>> annotator = Annotator(im0, line_width=10)
            >>> annotator.box_label(box=[10, 20, 30, 40], label="person")
        r   c                 S      g | ]}t |qS r2   rV   r.   br2   r2   r3   r4   /  rg   z'Annotator.box_label.<locals>.<listcomp>widthoutlinerJ   fillr   rc   c                 S   r   r2   rP   r   r2   r2   r3   r4   @  rg   r>   TrI   rh   	thicknesslineType	fontScaler   N)r   r   torchTensortolistr   r   r   polygonr   	rectanglerc   r   r   r   textcv2	polylinesrC   asarrayrK   LINE_AAgetTextSizer   r   r   putText)r1   boxlabelr   r   rotatedp1wrS   outsidep2r2   r2   r3   	box_label  sX    J6$2*(
zAnnotator.box_label      ?c                 C   sH  | j rt| j | _t|dkr&|ddd  	 d | jdd< |j
|j
kr2||j
}tj||j
tjdd }|ddddf }|d}|||  }d||  d}|jdd	j}|jdgd
}|ddd }||d  | }|d }	|	  	 }
|r|
nt|
| jj| jdd< | j r| | j dS dS )a  
        Plot masks on image.

        Args:
            masks (torch.Tensor): Predicted masks on cuda, shape: [n, h, w]
            colors (List[List[int]]): Colors for predicted masks, [[r, g, b] * n]
            im_gpu (torch.Tensor): Image is in cuda, shape: [3, h, w], range: [0, 1]
            alpha (float, optional): Mask transparency: 0.0 fully transparent, 1.0 opaque.
            retina_masks (bool, optional): Whether to use high resolution masks or not.
        r   rJ   rI   r5   N)devicer?   g     o@rh   dim)dimsr   )r   rC   r   r   r   rA   permuter   cpunumpyr   tor   tensorfloat32	unsqueezecumprodr   valuesflipbyter   scale_imager   r   )r1   masksr   im_gpualpharetina_masksmasks_colorinv_alpha_masksmcsim_mask
im_mask_npr2   r2   r3   r  X  s*   (
"zAnnotator.masks  r  T      ?c                 C   s  |dur|n| j }| jrt| j | _|j\}}|dko!|dv }	||	M }t|D ]N\}
}|p<|	r9| j|
 	 nt
|
}|d |d }}||d  dkrx||d  dkrxt|dkre|d }||k req*tj| jt|t|f||dtjd	 q*|r?|jd }t| jD ]\}
}t||d d df t||d d df f}t||d d df t||d d df f}|dkr||d d df }||d d df }||k s||k rq|d |d  dks|d |d  dks|d dk s|d dk rq|d |d  dks |d |d  dks |d dk s |d dk r!qtj| j|||p0| j|
 	 tt| j d tjd
 q| jrK| | j dS dS )a  
        Plot keypoints on the image.

        Args:
            kpts (torch.Tensor): Keypoints, shape [17, 3] (x, y, confidence).
            shape (tuple, optional): Image shape (h, w).
            radius (int, optional): Keypoint radius.
            kpt_line (bool, optional): Draw lines between keypoints.
            conf_thres (float, optional): Confidence threshold.
            kpt_color (tuple, optional): Keypoint color (B, G, R).

        Note:
            - `kpt_line=True` currently only supports human pose plotting.
            - Modifies self.im in-place.
            - If self.pil is True, converts image to numpy array and back to PIL.
        Nrj   >   rI   rh   r   rJ   rh   rI   r   )r   r   )r   r   rC   r   r   r   r   	enumerater   r   r   rA   r   circlerK   r   r   liner   ceilr   )r1   kptsr   radiuskpt_line
conf_thresr   nkptndimis_poserL   kcolor_kx_coordy_coordconfskpos1pos2conf1conf2r2   r2   r3   r  |  sR   
 &
00@HzAnnotator.kptsrJ   c                 C   s   | j |||| dS )z"Add rectangle to image (PIL-only).N)r   r   )r1   xyr   r   r   r2   r2   r3   r     s   zAnnotator.rectangletopr2   c              
   C   sT  | j r\| j|\}}|dkr|d  d| 7  < |dD ];}|rF| j|\}}| jj|d |d |d | d |d | d f|d | jj|||| jd |d  |7  < qdS |rtj|d| j	| j
dd \}}|d7 }|d |k}	|d | |	r|d | n|d | f}
t| j||
|d	tj tj| j||d| j	|| j
tjd
 dS )a  
        Add text to an image using PIL or cv2.

        Args:
            xy (List[int]): Top-left coordinates for text placement.
            text (str): Text to be drawn.
            txt_color (tuple, optional): Text color (R, G, B).
            anchor (str, optional): Text anchor position ('top' or 'bottom').
            box_color (tuple, optional): Box color (R, G, B, A) with optional alpha.
        bottomrJ   
r   r   r   r   rh   r   r   N)r   rc   r   splitr   r   r   r   r   r   r   r   r   r   )r1   r%  r   r   anchor	box_colorr   rS   r  r   r   r2   r2   r3   r     s$   8(&zAnnotator.textc                 C   s.   t |tjr|nt|| _t| j| _dS )z"Update self.im from a numpy array.N)r   r   r   r   r	   r   r   )r1   r   r2   r2   r3   r     s   zAnnotator.fromarrayc                 C   s   t | jS )z Return annotated image as array.)rC   r   r   r0   r2   r2   r3   result  s   zAnnotator.resultc              
   C   s~   t t| jddddf }tstr7zt| W dS  ty6 } zt	
d|  W Y d}~dS d}~ww |j|d dS )zShow the annotated image..Nr   z.Unable to display image in Jupyter notebooks: )title)r   r   rC   r   r   r   r   displayImportErrorr   warningshow)r1   r-  r   er2   r2   r3   r1    s    zAnnotator.show	image.jpgc                 C   s   t |t| j dS )z'Save the annotated image to 'filename'.N)r   imwriterC   r   r   )r1   filenamer2   r2   r3   save  s   zAnnotator.savec                 C   s*   | \}}}}|| }|| }|||| fS )ap  
        Calculate the dimensions and area of a bounding box.

        Args:
            bbox (tuple): Bounding box coordinates in the format (x_min, y_min, x_max, y_max).

        Returns:
            width (float): Width of the bounding box.
            height (float): Height of the bounding box.
            area (float): Area enclosed by the bounding box.

        Examples:
            >>> from ultralytics.utils.plotting import Annotator
            >>> im0 = cv2.imread("test.png")
            >>> annotator = Annotator(im0, line_width=10)
            >>> annotator.get_bbox_dimension(bbox=[10, 20, 30, 40])
        r2   )bboxx_miny_minx_maxy_maxr   heightr2   r2   r3   get_bbox_dimension  s   zAnnotator.get_bbox_dimension)NNr^   Fr_   )r   r=   )r   r   r=   F)r   F)r  NTr  N)NNrJ   )r=   r&  r2   N)r3  )rX   rY   rZ   r[   rH   r   r   r  r  r   r   r   r,  r1  r6  r\   r=  r2   r2   r2   r3   r]      s    

M

@
$
<


r]   r2   r   c              	   C   s  ddl }ddl}tjdtdd tjdtd td|d  d	 t|	 d
 }| dd } |j
| g dd}|j|dddtddtddd tj|d dd t  tjdddddd
  }	|	d j|td||d
 d dd}
t|D ]}|
d j| dd  t|D  q{|	d d! dt|  k rd"k rn n|	d tt| |	d jt| d#d$d% n|	d d& |j |d'd(|	d ddd) |j |d*d+|	d, ddd) d| ddddf< t!"| d- } t#$tj%d.tj&d/d0 }t'|dd1 | dd1 D ]\}}t()|j*|d
t|d2 q
|	d
 +| |	d
 ,d3 d4D ]}d5D ]}|	| j-| .d6 q1q-|d }tj|dd t  |rY|| dS dS )7a  
    Plot training labels including class histograms and box statistics.

    Args:
        boxes (np.ndarray): Bounding box coordinates in format [x, y, width, height].
        cls (np.ndarray): Class indices.
        names (dict, optional): Dictionary mapping class indices to class names.
        save_dir (Path, optional): Directory to save the plot.
        on_plot (Callable, optional): Function to call after plot is saved.
    r   Nignorez&The figure layout has changed to tight)categorymessage)r@  zPlotting labels to z
labels.jpgz... rJ   i@B )re   yr   r<  )columnsTautohist2   binsg?)pmax)corner	diag_kindkinddiag_kwsplot_kwszlabels_correlogram.jpg   dpirI   )ro   ro   figsizetight_layoutr   皙?)rH  rwidthc                 S   s   g | ]}|d  qS )r5   r2   r.   re   r2   r2   r3   r4   /  rg   zplot_labels.<locals>.<listcomp>	instances   Z   rq   )rotationfontsizeclassesre   rB  )re   rB  axrH  rI  r   r<  rh     )r_  r_  rh   r>   r5   i  r   off)r   rJ   rI   rh   )r&  rightleftr'  F)/pandasseabornwarningsfilterwarningsUserWarningFutureWarningr   inforK   r   	DataFramepairplotdictpltsavefigclosesubplotsravelrE  rC   linspacerangepatches	set_colorr   
set_ylabelrA   
set_xticksset_xticklabelslistr   
set_xlabelhistplotr   	xywh2xyxyr   r   onesrE   zipr	   r   r   imshowaxisspinesset_visible)boxesclsnamessave_diron_plotrc  rd  ncre   r^  rB  rL   imgr   asfnamer2   r2   r3   plot_labels  sN   "&$"r  zim.jpggRQ?rq   FTc                 C   s:  t | tjst| } t| dd}|r0|ddddf dd d|ddddf< |ddddf | | |ddddf< t	|
 } t| |j} |t| d t| d t| d	 t| d
 dd|rqdndf }	|r|jjddd tt|d}
t|	ddddf j|
ddd |	S )aO  
    Save image crop as {file} with crop size multiple {gain} and {pad} pixels. Save and/or return crop.

    This function takes a bounding box and an image, and then saves a cropped portion of the image according
    to the bounding box. Optionally, the crop can be squared, and the function allows for gain and padding
    adjustments to the bounding box.

    Args:
        xyxy (torch.Tensor | list): A tensor or list representing the bounding box in xyxy format.
        im (np.ndarray): The input image.
        file (Path, optional): The path where the cropped image will be saved.
        gain (float, optional): A multiplicative factor to increase the size of the bounding box.
        pad (int, optional): The number of pixels to add to the width and height of the bounding box.
        square (bool, optional): If True, the bounding box will be transformed into a square.
        BGR (bool, optional): If True, the image will be saved in BGR format, otherwise in RGB.
        save (bool, optional): If True, the cropped image will be saved to disk.

    Returns:
        (np.ndarray): The cropped image.

    Examples:
        >>> from ultralytics.utils.plotting import save_one_box
        >>> xyxy = [50, 50, 150, 150]
        >>> im = cv2.imread("image.jpg")
        >>> cropped_im = save_one_box(xyxy, im, file="cropped.jpg", square=True)
    r   rU   NrI   rJ   r   )r   rJ   )r   rh   )r   r   )r   rI   T)parentsexist_okz.jpg._   )qualitysubsampling)r   r   r   stackr   	xyxy2xywhviewr   r   r|  long
clip_boxesr   rK   parentmkdirr   r   with_suffixr   r   r6  )xyxyr   filegainpadsquareBGRr6  r   cropfr2   r2   r3   save_one_boxM  s   
4,D$r  r>   )r   r8   z
images.jpgi  rO   r  images	batch_idxr  bboxesconfsr  r  pathsr  r  r  max_sizemax_subplotsr6  r  returnc           -   
      s4  t | tjr|    } t |tjr|  }t |tjr&|  }t |tjr5|  t}t |tjrA|  }t |tjrM|  }| jd dkr^| ddddf } | j\}}}}t	||}t
|d  t
| d dkr~| d9 } t
jt | t | dfdt
jd}t|D ]+}t||   t||   }}| | ddd|||| ||| ddf< q|  t|| }|dk rt|| }t|| }t|t fd	d
||fD }t||   d }t|d}t|t|d |dt|	d}t|D ]n}t||   t||   }}|j|||| || gdddd |rO|j|d |d gt|| jdd dd t|dkr~||k}|| d}|du }t|r"|| }|durw|| nd}t|r|ddddf  dkr|dddgf  |9  < |dddgf  |9  < n|dk r|dddf  |9  < |d  |7  < |d  |7  < |jd dk}|rt|nt|}t |t
j!" D ];\} }!||  }"t#|"}#|	r|	$|"|"n|"}"|s||  |kr|r|" n	|" d||  d}$|j%|!|$|#|d qn&t|rH|D ]}"t#|"}#|	r8|	$|"|"n|"}"|j||g|" |#d d! q)t|r|| & }%t|%r|%d  d"ksj|%d  d"kr{|%d  |9  < |%d  |9  < n	|dk r|%|9 }%|%d  |7  < |%d  |7  < tt|%D ]} |s||  |kr|j'|%|  |d# qt|r~|jd |jd kr|| }&n'||g }&|( }'t
)|'*|'ddfd }(t
j+|&|'dd$}&t
,|&|(kd%d&}&t
-|j.& })tt|&D ]}} |s||  |krwt#||  }#|&|  j\}*}+|*|ks|+|kr4|&|  t
j},t|,||f},|,t/},n|&|  t/},z0|)||| ||| ddf |, d' t
0|#d(  |)||| ||| ddf |,< W q t1yv   Y qw q|2|) q|st
-|j.S |j.3| |
r|
| dS dS ))a  
    Plot image grid with labels, bounding boxes, masks, and keypoints.

    Args:
        images: Batch of images to plot. Shape: (batch_size, channels, height, width).
        batch_idx: Batch indices for each detection. Shape: (num_detections,).
        cls: Class labels for each detection. Shape: (num_detections,).
        bboxes: Bounding boxes for each detection. Shape: (num_detections, 4) or (num_detections, 5) for rotated boxes.
        confs: Confidence scores for each detection. Shape: (num_detections,).
        masks: Instance segmentation masks. Shape: (num_detections, height, width) or (1, height, width).
        kpts: Keypoints for each detection. Shape: (num_detections, 51).
        paths: List of file paths for each image in the batch.
        fname: Output filename for the plotted image grid.
        names: Dictionary mapping class indices to class names.
        on_plot: Optional callback function to be called after saving the plot.
        max_size: Maximum size of the output image grid.
        max_subplots: Maximum number of subplots in the image grid.
        save: Whether to save the plotted image grid to a file.
        conf_thres: Confidence threshold for displaying detections.

    Returns:
        (np.ndarray): Plotted image grid as a numpy array if save is False, None otherwise.

    Note:
        This function supports both tensor and numpy array inputs. It will automatically
        convert tensor inputs to numpy arrays for processing.
    rJ   rh   Nr   r   r5   r>   rI   c                 3   s    | ]	}t |  V  qd S r>  rP   rW  nsr2   r3   rT     s    zplot_images.<locals>.<genexpr>g{Gz?   rq   T)r   r   r   r   r=   )r   rs   (   )   r  r  )r   r   rK   rU   g?.).r   ).rJ   r    z.1f)r   r   )@   r  r  r6   )r   r+  g)\(?)r  )r  g      ?g        g?g333333?)4r   r   r   r   floatr   astyperK   r   minrC   r  r   fullrE   rs  	transposemathr   resizerW   r]   r   r   r   r   r   namerA   r   xywhr2xyxyxyxyr|  r  int64r   r   getr   r   r  r   arangereshaperepeatwherer   r   boolrD   r   r   r6  )-r  r  r  r  r  r  r  r  r  r  r  r  r  r6  r  bs_rS   r   mosaicrL   re   rB  scalefs	annotatoridxr]  labelsr  r  is_obbjr   r/   r   r   kpts_image_masksnlindexr   mhmwmaskr2   r  r3   plot_imagesy  s   -
("2"
"".


 


$



6*
r  path/to/results.csvc                 C   s  ddl }ddlm} | rt| jnt|}|r'tjddddd\}	}
g d}n3|r9tjdd	d
dd\}	}
g d}n!|rKtjddddd\}	}
g d}ntjddddd\}	}
g d}|
 }
t|	d}t
|ssJ d|  d|D ]u}zV||}dd |jD }|jdddf }t|D ]9\}}|jdd|f d}|
| j||d|jdd	d |
| j|||dddddd |
| j|| dd  qW qu ty } ztd!| d"|  W Y d}~qud}~ww |
d#   |d$ }|	j|d%d& t  |r	|| dS dS )'a  
    Plot training results from a results CSV file. The function supports various types of data including segmentation,
    pose estimation, and classification. Plots are saved as 'results.png' in the directory where the CSV is located.

    Args:
        file (str, optional): Path to the CSV file containing the training results.
        dir (str, optional): Directory where the CSV file is located if 'file' is not provided.
        segment (bool, optional): Flag to indicate if the data is for segmentation.
        pose (bool, optional): Flag to indicate if the data is for pose estimation.
        classify (bool, optional): Flag to indicate if the data is for classification.
        on_plot (callable, optional): Callback function to be executed after plotting. Takes filename as an argument.

    Examples:
        >>> from ultralytics.utils.plotting import plot_results
        >>> plot_results("path/to/results.csv", segment=True)
    r   Ngaussian_filter1drI   )rm   rm   TrR  )rI   rs   rh   rU   ro   )r  rm   )rI   rh   rU   rs   rm   rn   rq   rr   ri   rk   rO   rj   ro   rp   rb   rl   rp   )   rm   )rI   rh   rU   rs   rm   rn   ro   rr   rb   rk   rO   rj   r     rp   rq   rl   ri   rs   )rb   rm   )
rI   rh   rU   rs   rm   rp   rq   rr   rn   ro   zresults*.csvzNo results.csv files found in z, nothing to plot.c                 S      g | ]}|  qS r2   striprW  r2   r2   r3   r4   L  rg   z plot_results.<locals>.<listcomp>r  .)markerr   	linewidth
markersizerh   sigma:smoothr   r  rb   )r\  zPlotting error for z: rJ   zresults.pngrO  rP  )rc  scipy.ndimager  r   r  rm  rp  rq  ry  globrA   resolveread_csvrC  r   r  r  plotstem	set_titler   r   errorlegendrn  ro  )r  dirsegmentposeclassifyr  pdr  r  figr^  r  filesr  r   r  re   rL   r  rB  r2  r  r2   r2   r3   plot_results$  sN   



 "r     viridisrU  nonec                    sR   t j |d\ fddttD }tj ||||d dS )a.  
    Plot a scatter plot with points colored based on a 2D histogram.

    Args:
        v (array-like): Values for the x-axis.
        f (array-like): Values for the y-axis.
        bins (int, optional): Number of bins for the histogram.
        cmap (str, optional): Colormap for the scatter plot.
        alpha (float, optional): Alpha for the scatter plot.
        edgecolors (str, optional): Edge colors for the scatter plot.

    Examples:
        >>> v = np.random.rand(100)
        >>> f = np.random.rand(100)
        >>> plt_color_scatter(v, f)
    rG  c              
      s`   g | ],}t tj| d dd jd d t tj | d dd jd d f qS )T)ra  rJ   r   )r  rC   digitizer   rQ   r  rE  vxedgesyedgesr2   r3   r4   s  s    &&z%plt_color_scatter.<locals>.<listcomp>)r/   cmapr  
edgecolorsN)rC   histogram2drs  rA   rm  scatter)r  r  rH  r  r  r   r   r2   r  r3   plt_color_scatter`  s
   
	r  tune_results.csvc                 C   s  ddl }ddlm} dd }t| } || }d}dd |jD |d }|j}|dddf }t|}	t	
t|d	 }
tjd
dd t|D ]P\}}|dd|| f }||	 }t|
|
|d  t||dddd tj|| ddd tj| d|dddid tjddd ||
 dkrtg  qI|| d tdt|d }tjddd tj||dddd  tj|||d!d"d#d$d%d& td' td( td) td t  || d* dS )+a  
    Plot the evolution results stored in a 'tune_results.csv' file. The function generates a scatter plot for each key
    in the CSV, color-coded based on fitness scores. The best-performing configurations are highlighted on the plots.

    Args:
        csv_file (str, optional): Path to the CSV file containing the tuning results.

    Examples:
        >>> plot_tune_results("path/to/tune_results.csv")
    r   Nr  c                 S   s*   t j| dd t   td|   dS )z#Save one matplotlib plot to 'file'.rO  rP  zSaved N)rm  rn  ro  r   ri  )r  r2   r2   r3   _save_one_file  s   z)plot_tune_results.<locals>._save_one_filerJ   c                 S   r  r2   r  rW  r2   r2   r3   r4     rg   z%plot_tune_results.<locals>.<listcomp>r   )rq   rq   TrR  r  rU  r  )r  r  r   zk+rk   )r  z = z.3gr   rp   )fontdictbothro   )r  	labelsizeztune_scatter_plots.png)rq   rm   ofitness)r  	linestyler   rh   r  r  smoothedrI   r  zFitness vs Iteration	IterationFitnessztune_fitness.png)rc  r  r  r   r  rC  r   rC   argmaxr  r  rA   rm  figurer  subplotr  r  r   r-  tick_paramsyticks	with_namers  xlabelylabelgridr  )csv_filer  r  r  r   num_metrics_columnskeysre   r
  r  rB   rL   r  r  mur2   r2   r3   plot_tune_results  sD   






r  ,  c           	   
   C   s   g }t | D ]2\}}|d|ddf  dd\}}}t|jd df|}|t||t	||fd qt|d
 }|dddf |dddf |ddddf |dddf fS )ZConvert model output to target format [batch_id, class_id, x, y, w, h, conf] for plotting.Nrm   )rU   rJ   rJ   rJ   r   rI   r   )r  r   r)  r   r  r   appendcatr   r  r   )	outputmax_dettargetsrL   r	  r   r  r  r  r2   r2   r3   output_to_target  s   &"@r$  c           
   
   C   s   g }t | D ]-\}}|d|  dd\}}}}t|jd df|}	|t|	||||fd qt|d }|dddf |dddf |ddddf |dddf fS )r  N)rU   rJ   rJ   rJ   rJ   r   rI   r   )	r  r   r)  r   r  r   r  r   r   )
r!  r"  r#  rL   r	  r   r  r  angler  r2   r2   r3   output_to_rotated_target  s    @r&      zruns/detect/expc              	   C   sR  dD ]	}||v r dS qt | tjr| j\}}}}	|dkr|	dkr|d| d|dd  d }
tj| d	  |d	d
}t||}tj	t
|d ddd\}}| }tjddd t|D ]}|| ||   || d q`td|
 d| d| d tj|
ddd t  tt|
d| d	    dS dS dS dS )ag  
    Visualize feature maps of a given model module during inference.

    Args:
        x (torch.Tensor): Features to be visualized.
        module_type (str): Module type.
        stage (int): Module stage within the model.
        n (int, optional): Maximum number of feature maps to plot.
        save_dir (Path, optional): Directory to save results.
    >   OBBPoseDetectSegmentClassifyRTDETRDecoderNrJ   stager  r  r   z_features.pngr   r   ro   T)rT  g?)wspacehspacer`  zSaving z... (/)r  tight)rQ  bbox_inchesz.npy)r   r   r   r   r)  chunkr   r  rm  rp  r  r  rq  subplots_adjustrs  r  squeezer  r   ri  rn  ro  rC   r6  r   r  r   )re   module_typer.  rB   r  mr  channelsr<  r   r  blocksr^  rL   r2   r2   r3   feature_visualization  s,    
&r<  )r  r   FFFN)r  r  rU  r  )r  )r  ):r  re  pathlibr   typingr   r   r   r   r   r   matplotlib.pyplotpyplotrm  r   rC   r   PILr   r	   r
   r   r   ultralytics.utilsr   r   r   r   r   r   r   ultralytics.utils.checksr   r   r   ultralytics.utils.filesr   r   r   r]   r  r  zerosr   rE   r   ndarrayr   rK   r  r  r  r  r  r  r$  r&  r<  r2   r2   r2   r3   <module>   s   $   p?,
	
 +
;

7
