
    jQf                    d   d dl mZ d dlZd dlZd dlZd dlZd dlZd dlZd dl	Z	d dl
mc mZ d dlmZ  G d dej                  ZdKdLdZ	 	 	 dMdNdZdOdZd Zd Zd Zd  ZdPdQd%ZdRdSd*Zd+ Zd, Zd- Zd. Zd/ Zd0 Z d1 Z!dTdUd4Z"dVd7Z#dWdXd9Z$d: Z%	 	 dYdZd=Z&d[d\d?Z'd@ Z(d]d^dFZ)d_dHZ*dI Z+dJ Z,dS )`    )annotationsN)NOT_MACOS14c                  4    e Zd ZdZdddZd	 Zd
 Zd Zd ZdS )Profilea7  Ultralytics Profile class for timing code execution.

    Use as a decorator with @Profile() or as a context manager with 'with Profile():'. Provides accurate timing
    measurements with CUDA synchronization support for GPU operations.

    Attributes:
        t (float): Accumulated time in seconds.
        device (torch.device): Device used for model inference.
        cuda (bool): Whether CUDA is being used for timing synchronization.

    Examples:
        Use as a context manager to time code execution
        >>> with Profile(device=device) as dt:
        ...     pass  # slow operation here
        >>> print(dt)  # prints "Elapsed time is 9.5367431640625e-07 s"

        Use as a decorator to time function execution
        >>> @Profile()
        ... def slow_function():
        ...     time.sleep(0.1)
            Ntfloatdevicetorch.device | Nonec                    || _         || _        t          |o!t          |                              d                    | _        dS )zInitialize the Profile class.

        Args:
            t (float): Initial accumulated time in seconds.
            device (torch.device, optional): Device used for model inference to enable CUDA synchronization.
        cudaN)r   r
   boolstr
startswithr   )selfr   r
   s      X/var/www/html/Carbon-Document/venv/lib/python3.11/site-packages/ultralytics/utils/ops.py__init__zProfile.__init__)   s>     BCKK$:$:6$B$BCC			    c                8    |                                  | _        | S )zStart timing.)timestartr   s    r   	__enter__zProfile.__enter__4   s    YY[[
r   c                r    |                                  | j        z
  | _        | xj        | j        z  c_        dS )zStop timing.N)r   r   dtr   )r   typevalue	tracebacks       r   __exit__zProfile.__exit__9   s.    ))++
*$'r   c                    d| j          dS )zIReturn a human-readable string representing the accumulated elapsed time.zElapsed time is z s)r   r   s    r   __str__zProfile.__str__>   s    ,$&,,,,r   c                ~    | j         r$t          j                             | j                   t	          j                    S )z9Get current time with CUDA synchronization if applicable.)r   torchsynchronizer
   r   perf_counterr   s    r   r   zProfile.timeB   s3    9 	0J""4;/// """r   )r   N)r   r	   r
   r   )	__name__
__module____qualname____doc__r   r   r   r!   r    r   r   r   r      sx         ,	D 	D 	D 	D 	D  
  
- - -# # # # #r   r     segment
np.ndarraywidthintheightreturnc                   | j         \  }}t          j        |                                dk     |                                dk     |                                |k    |                                |k    g                                          dk    r,|                    d|          }|                    d|          }|dk    |dk    z  ||k     z  ||k     z  }||         }||         }t          |          rgt          j        |                                |                                |                                |                                g| j                  nt          j	        d| j                  S )a$  Convert segment coordinates to bounding box coordinates.

    Converts a single segment label to a box label by finding the minimum and maximum x and y coordinates. Applies
    inside-image constraint and clips coordinates when necessary.

    Args:
        segment (np.ndarray): Segment coordinates in format (N, 2) where N is number of points.
        width (int): Width of the image in pixels.
        height (int): Height of the image in pixels.

    Returns:
        (np.ndarray): Bounding box coordinates in xyxy format [x1, y1, x2, y2].
    r      dtype   )
Tnparrayminmaxsumclipanyr5   zeros)r,   r.   r0   xyinsides         r   segment2boxrC   I   s/    9DAq	x1aeeggk15577U?AEEGGf<LMNNRRTTXYYYFF1eFF1f!eA!e),F
;F	&	A	&	A q66	.!%%''15577AEEGGQUUWW5W]KKKKXaw}---r   TF
img1_shapetuple[int, int]boxestorch.Tensor | np.ndarray
img0_shape	ratio_padtuple | Nonepaddingr   xywhc                >   |t          | d         |d         z  | d         |d         z            }t          | d         t          |d         |z            z
  dz  dz
            }t          | d         t          |d         |z            z
  dz  dz
            }n|d         d         }|d         \  }}|rB|dxx         |z  cc<   |dxx         |z  cc<   |s |dxx         |z  cc<   |d	xx         |z  cc<   |d
ddfxx         |z  cc<   |r|nt          ||          S )aV  Rescale bounding boxes from one image shape to another.

    Rescales bounding boxes from img1_shape to img0_shape, accounting for padding and aspect ratio changes. Supports
    both xyxy and xywh box formats.

    Args:
        img1_shape (tuple[int, int]): Shape of the source image (height, width).
        boxes (torch.Tensor | np.ndarray): Bounding boxes to rescale in format (N, 4).
        img0_shape (tuple[int, int]): Shape of the target image (height, width).
        ratio_pad (tuple, optional): Tuple of (ratio, pad) for scaling. If None, calculated from image shapes.
        padding (bool): Whether boxes are based on YOLO-style augmented images with padding.
        xywh (bool): Whether box format is xywh (True) or xyxy (False).

    Returns:
        (torch.Tensor | np.ndarray): Rescaled bounding boxes in the same format as input.
    Nr         皙?.r   .rN   .rO   .r3   .r6   )r:   round
clip_boxes)	rD   rF   rH   rI   rK   rL   gainpad_xpad_ys	            r   scale_boxesrZ   f   sP   0 :a=:a=0*Q-*Q-2OPPz!}uZ]T-A'B'BBaG#MNNz!}uZ]T-A'B'BBaG#MNN|A |u #ff 	#&MMMU"MMM&MMMU"MMM	#rr'NNNdNNN;55j
;;;r   r@   c                    t          |t          j                  r!t          |                                          }t          j        | |z            |z  S )zReturn the nearest number that is divisible by the given divisor.

    Args:
        x (int): The number to make divisible.
        divisor (int | torch.Tensor): The divisor.

    Returns:
        (int): The nearest number divisible by the divisor.
    )
isinstancer#   Tensorr/   r;   mathceil)r@   divisors     r   make_divisiblera      sF     '5<(( %gkkmm$$9Q[!!G++r   c                   |dd         \  }}t          | t          j                  rt          rq| d                             d|           | d                             d|           | d                             d|           | d                             d|           n| d                             d|          | d<   | d                             d|          | d<   | d                             d|          | d<   | d                             d|          | d<   nN| dddgf                             d|          | dddgf<   | dd	d
gf                             d|          | dd	d
gf<   | S )a  Clip bounding boxes to image boundaries.

    Args:
        boxes (torch.Tensor | np.ndarray): Bounding boxes to clip.
        shape (tuple): Image shape as HWC or HW (supports both).

    Returns:
        (torch.Tensor | np.ndarray): Clipped bounding boxes.
    NrO   rQ   r   rR   rS   rT   .rN   r3   r\   r#   r]   r   clamp_clampr=   )rF   shapehws       r   rV   rV      su    !9DAq%&& ; 		6&M  A&&&&M  A&&&&M  A&&&&M  A&&&&!&M//155E&M!&M//155E&M!&M//155E&M!&M//155E&MM"3A;/44Q::cAq6k"3A;/44Q::cAq6kLr   c                   |dd         \  }}t          | t          j                  rt          r9| d                             d|           | d                             d|           n}| d                             d|          | d<   | d                             d|          | d<   n>| d                             d|          | d<   | d                             d|          | d<   | S )a	  Clip line coordinates to image boundaries.

    Args:
        coords (torch.Tensor | np.ndarray): Line coordinates to clip.
        shape (tuple): Image shape as HWC or HW (supports both).

    Returns:
        (torch.Tensor | np.ndarray): Clipped coordinates.
    NrO   rQ   r   rR   rc   )coordsrf   rg   rh   s       r   clip_coordsrk      s     !9DAq&%,'' 	3 	86N!!!Q'''6N!!!Q''''#F^11!Q77F6N#F^11!Q77F6NN,,Q22v,,Q22vMr   c                    | j         d         dk    sJ d| j                      t          |           }| d         | d         | d         | d         f\  }}}}||z   dz  |d<   ||z   dz  |d<   ||z
  |d<   ||z
  |d<   |S )	a  Convert bounding box coordinates from (x1, y1, x2, y2) format to (x, y, width, height) format where (x1, y1) is
    the top-left corner and (x2, y2) is the bottom-right corner.

    Args:
        x (np.ndarray | torch.Tensor): Input bounding box coordinates in (x1, y1, x2, y2) format.

    Returns:
        (np.ndarray | torch.Tensor): Bounding box coordinates in (x, y, width, height) format.
    r6   9input shape last dimension expected 4 but input shape is rQ   rR   rS   rT   rO   rf   
empty_like)r@   rA   x1y1x2y2s         r   	xyxy2xywhru      s     72;!bYZY`bb1AvY&	1V9ai?NBBbAAfIbAAfIRAfIRAfIHr   c                    | j         d         dk    sJ d| j                      t          |           }| dddf         }| dddf         dz  }||z
  |dddf<   ||z   |dddf<   |S )a  Convert bounding box coordinates from (x, y, width, height) format to (x1, y1, x2, y2) format where (x1, y1) is
    the top-left corner and (x2, y2) is the bottom-right corner. Note: ops per 2 channels faster than per channel.

    Args:
        x (np.ndarray | torch.Tensor): Input bounding box coordinates in (x, y, width, height) format.

    Returns:
        (np.ndarray | torch.Tensor): Bounding box coordinates in (x1, y1, x2, y2) format.
    rm   r6   rn   .NrO   ro   )r@   rA   xywhs       r   	xywh2xyxyry      s     72;!bYZY`bb1A	
37B	
37aBbAc2A2gJbAc122gJHr   rh   rg   padwpadhc                4   | j         d         dk    sJ d| j                      t          |           }| d         | d         | d         | d         f\  }}}}	|dz  |	dz  }}
|||
z
  z  |z   |d<   |||z
  z  |z   |d<   |||
z   z  |z   |d<   |||z   z  |z   |d<   |S )	a  Convert normalized bounding box coordinates to pixel coordinates.

    Args:
        x (np.ndarray | torch.Tensor): Normalized bounding box coordinates in (x, y, w, h) format.
        w (int): Image width in pixels.
        h (int): Image height in pixels.
        padw (int): Padding width in pixels.
        padh (int): Padding height in pixels.

    Returns:
        (np.ndarray | torch.Tensor): Bounding box coordinates in (x1, y1, x2, y2) format.
    rm   r6   rn   rQ   rR   rS   rT   rO   ro   )r@   rh   rg   rz   r{   rA   xcycxwxhhalf_whalf_hs               r   
xywhn2xyxyr      s     72;!bYZY`bb1AvY&	1V9ai?NBB!VR!VFFR&[!D(AfIR&[!D(AfIR&[!D(AfIR&[!D(AfIHr   r   r=   epsr	   c                H   |rt          | ||z
  ||z
  f          } | j        d         dk    sJ d| j                     t          |           }| d         | d         | d         | d         f\  }}}}	||z   dz  |z  |d<   ||	z   dz  |z  |d<   ||z
  |z  |d<   |	|z
  |z  |d<   |S )	a`  Convert bounding box coordinates from (x1, y1, x2, y2) format to normalized (x, y, width, height) format. x, y,
    width and height are normalized to image dimensions.

    Args:
        x (np.ndarray | torch.Tensor): Input bounding box coordinates in (x1, y1, x2, y2) format.
        w (int): Image width in pixels.
        h (int): Image height in pixels.
        clip (bool): Whether to clip boxes to image boundaries.
        eps (float): Minimum value for box width and height.

    Returns:
        (np.ndarray | torch.Tensor): Normalized bounding box coordinates in (x, y, width, height) format.
    rm   r6   rn   rQ   rR   rS   rT   rO   )rV   rf   rp   )
r@   rh   rg   r=   r   rA   rq   rr   rs   rt   s
             r   
xyxy2xywhnr     s      .q1s7AG,--72;!bYZY`bb1AvY&	1V9ai?NBBr'Q!#AfIr'Q!#AfIbAAfIbAAfIHr   c                    t          | t          j                  r|                                 nt	          j        |           }| d         | d         dz  z
  |d<   | d         | d         dz  z
  |d<   |S )a(  Convert bounding box format from [x, y, w, h] to [x1, y1, w, h] where x1, y1 are top-left coordinates.

    Args:
        x (np.ndarray | torch.Tensor): Input bounding box coordinates in xywh format.

    Returns:
        (np.ndarray | torch.Tensor): Bounding box coordinates in ltwh format.
    rQ   rS   rO   rR   rT   r\   r#   r]   cloner8   copyr@   rA   s     r   	xywh2ltwhr   ,  g      5<00@			bgajjA&	AfIM)AfI&	AfIM)AfIHr   c                    t          | t          j                  r|                                 nt	          j        |           }| d         | d         z
  |d<   | d         | d         z
  |d<   |S )a  Convert bounding boxes from [x1, y1, x2, y2] to [x1, y1, w, h] format.

    Args:
        x (np.ndarray | torch.Tensor): Input bounding box coordinates in xyxy format.

    Returns:
        (np.ndarray | torch.Tensor): Bounding box coordinates in ltwh format.
    rS   rQ   rT   rR   r   r   s     r   	xyxy2ltwhr   ;  _      5<00@			bgajjA&	AfI%AfI&	AfI%AfIHr   c                    t          | t          j                  r|                                 nt	          j        |           }| d         | d         dz  z   |d<   | d         | d         dz  z   |d<   |S )a  Convert bounding boxes from [x1, y1, w, h] to [x, y, w, h] where xy1=top-left, xy=center.

    Args:
        x (np.ndarray | torch.Tensor): Input bounding box coordinates.

    Returns:
        (np.ndarray | torch.Tensor): Bounding box coordinates in xywh format.
    rQ   rS   rO   rR   rT   r   r   s     r   	ltwh2xywhr   J  r   r   c                   t          | t          j                  }|r&|                                                                 n| }|                    t          |           dd          }g }|D ]}t          j        |          \  \  }}\  }}}	|	dz  t          j
        z  }
||k     r||}}|
t          j
        dz  z  }
|
dt          j
        z  dz  k    r%|
t          j
        z  }
|
dt          j
        z  dz  k    %|
t          j
         dz  k     r#|
t          j
        z  }
|
t          j
         dz  k     #|                    |||||
g           |r!t          j        || j        | j                  nt          j        |          S )a  Convert batched Oriented Bounding Boxes (OBB) from [xy1, xy2, xy3, xy4] to [xywh, rotation] format.

    Args:
        x (np.ndarray | torch.Tensor): Input box corners with shape (N, 8) in [xy1, xy2, xy3, xy4] format.

    Returns:
        (np.ndarray | torch.Tensor): Converted data in [cx, cy, w, h, rotation] format with shape (N, 5). Rotation
            values are in radians from [-pi/4, 3pi/4).
    rm   rO      r3   r6   r
   r5   )r\   r#   r]   cpunumpyreshapelencv2minAreaRectr8   piappendtensorr
   r5   asarray)r@   is_torchpointsrboxesptscxcyrh   rg   anglethetas              r   xyxyxyxy2xywhrr   Y  sp    !U\**H (/QUUWW]]___aF^^CFFB**FF - - #&/#"6"6R&1a%be#q55aqARUQYEq25y1}$$RUNE q25y1}$$rufqj  RUNE rufqj  r2q!U+,,,,CKc5<qxqw????QSQ[\bQcQccr   c                P    t           t          j                  r.t          j        t          j        t          j        t          j        fn-t          j        t          j        t          j        t          j        f\  }}}} dddf         } fdt          dd          D             \  }}} ||           ||          }
}	|dz  |	z  |dz  |
z  g}| dz  |
z  |dz  |	z  g} ||d          } ||d          }||z   |z   }||z   |z
  }||z
  |z
  }||z
  |z   } |||||gd          S )a  Convert batched Oriented Bounding Boxes (OBB) from [xywh, rotation] to [xy1, xy2, xy3, xy4] format.

    Args:
        x (np.ndarray | torch.Tensor): Boxes in [cx, cy, w, h, rotation] format with shape (N, 5) or (B, N, 5). Rotation
            values should be in radians from [-pi/4, 3pi/4).

    Returns:
        (np.ndarray | torch.Tensor): Converted corner points with shape (N, 4, 2) or (B, N, 4, 2).
    .NrO   c              3  6   K   | ]}d ||dz   f         V  dS ).rN   Nr*   ).0ir@   s     r   	<genexpr>z!xywhr2xyxyxyxy.<locals>.<genexpr>  s4      ::1S!a!e)^$::::::r      rm   )
r\   r#   r]   cossincatstackr8   concatenaterange)r@   r   r   r   r   ctrrh   rg   r   	cos_value	sin_valuevec1vec2pt1pt2pt3pt4s   `                r   xywhr2xyxyxyxyr   x  sN    a&&	8EIuy%+66fbfbnbh7 Cc5 C!G*C::::eAqkk:::KAq%3u::ss5zzyIEIq1uy01DBFYA	 12D3tR==D3tR==D
*t
C
*t
C
*t
C
*t
C5#sC%r***r   c                    t          | t          j                  r|                                 nt	          j        |           }| d         | d         z   |d<   | d         | d         z   |d<   |S )a  Convert bounding box from [x1, y1, w, h] to [x1, y1, x2, y2] where xy1=top-left, xy2=bottom-right.

    Args:
        x (np.ndarray | torch.Tensor): Input bounding box coordinates.

    Returns:
        (np.ndarray | torch.Tensor): Bounding box coordinates in xyxy format.
    rS   rQ   rT   rR   r   r   s     r   	ltwh2xyxyr     r   r   c                (   g }| D ]m}|j         \  }}|                    |                                |                                |                                |                                g           nt	          t          j        |                    S )a  Convert segment coordinates to bounding box labels in xywh format.

    Args:
        segments (list): List of segments where each segment is a list of points, each point is [x, y] coordinates.

    Returns:
        (np.ndarray): Bounding box coordinates in xywh format.
    )r7   r   r:   r;   ru   r8   r9   )segmentsrF   sr@   rA   s        r   segments2boxesr     sw     E ; ;s1aeeggquuww9::::RXe__%%%r     nc           	        t          |           D ]?\  }t                    |k    rt          j        ddddf         fd          t          j        dt                    dz
  t                    |k     r|t                    z
  n|          t          j        t                              t                    |k     r)t          j        t          j                            nt          j        fdt          d          D             t          j	                  
                    dd          j        | |<   A| S )	a2  Resample segments to n points each using linear interpolation.

    Args:
        segments (list): List of (N, 2) arrays where N is the number of points in each segment.
        n (int): Number of points to resample each segment to.

    Returns:
        (list): Resampled segments with n points each.
    r   rN   N)axisc           	     P    g | ]"}t          j        d d |f                   #S )N)r8   interp)r   r   r   r@   xps     r   
<listcomp>z%resample_segments.<locals>.<listcomp>  s3    HHH!BIaQqqq!tW55HHHr   rO   r4   rm   )	enumerater   r8   r   linspacearangeinsertsearchsortedr   float32r   r7   )r   r   r   r   r@   r   s      @@@r   resample_segmentsr     s:    (## 	
 	
1q66Q;;NAq1aaay>222K3q66A:SVVaZZq3q66zzQGGYs1vv8;A

BIaB//444NHHHHHHuQxxHHHPRPZ[[[ccdegijjl 	 Or   maskstorch.Tensorc                   |j         | j         k    r|                    | j                   }| j        \  }}}|dk     r| j        s~t	          |                    d                                                                                    D ]4\  }\  }}}}	d| |d|f<   d| ||	df<   d| |ddd|f<   d| |dd|df<   5| S t          j	        |dddddf         dd          \  }}}}	t          j
        || j         |j                  ddddf         }
t          j
        || j         |j                  ddddf         }| |
|k    |
|k     z  ||k    z  ||	k     z  z  S )a  Crop masks to bounding box regions.

    Args:
        masks (torch.Tensor): Masks with shape (N, H, W).
        boxes (torch.Tensor): Bounding box coordinates with shape (N, 4) in xyxy pixel format.

    Returns:
        (torch.Tensor): Cropped masks.
    2   r   )r:   Nr6   rN   r   )r
   torf   is_cudar   re   rU   r/   r#   chunkr   r5   )r   rF   r   rg   rh   r   rq   rr   rs   rt   rcs               r   	crop_maskr     s    |u|##&&kGAq!2vvemv#,U[[Q[-?-?-E-E-G-G-K-K-M-M#N#N 	! 	!ABBE!SbS&ME!RSS&M E!QQQ) E!QQQ)U111aaa:%61==BBL5<rx@@@tQQQOL5<rx@@@qqq$ObQV,R8AFCDDr   upsamplec                   | j         \  }}}||                                                     |d          z                      d||          }||d         z  }	||d         z  }
t          j        |	|
|	|
gg|j                  }t          |||z            }|r#t          j        |d         |d          d         }|	                    d	          
                                S )
a  Apply masks to bounding boxes using mask head output.

    Args:
        protos (torch.Tensor): Mask prototypes with shape (mask_dim, mask_h, mask_w).
        masks_in (torch.Tensor): Mask coefficients with shape (N, mask_dim) where N is number of masks after NMS.
        bboxes (torch.Tensor): Bounding boxes with shape (N, 4) where N is number of masks after NMS.
        shape (tuple): Input image size as (height, width).
        upsample (bool): Whether to upsample masks to original image size.

    Returns:
        (torch.Tensor): A binary mask tensor of shape [n, h, w], where n is the number of masks after NMS, and h and w
            are the height and width of the input image. The mask is applied to the bounding boxes.
    rm   rN   r   )r
   )rF   Nbilinearmoder   )rf   r	   viewr#   r   r
   r   Finterpolategt_byte)protosmasks_inbboxesrf   r   r   mhmwr   width_ratioheight_ratioratioss               r   process_maskr     s     IAr2++Ar22288RDDEuQx-Ka=L\K{LQR[a[hiiiFe6F?333E FeDk5zBBB1E99S>>   r   c                >   | j         \  }}}||                                                     |d          z                      d||          }t          |d         |          d         }t	          ||          }|                    d                                          S )a  Apply masks to bounding boxes using mask head output with native upsampling.

    Args:
        protos (torch.Tensor): Mask prototypes with shape (mask_dim, mask_h, mask_w).
        masks_in (torch.Tensor): Mask coefficients with shape (N, mask_dim) where N is number of masks after NMS.
        bboxes (torch.Tensor): Bounding boxes with shape (N, 4) where N is number of masks after NMS.
        shape (tuple): Input image size as (height, width).

    Returns:
        (torch.Tensor): Binary mask tensor with shape (N, H, W).
    rm   Nr   r   )rf   r	   r   scale_masksr   r   r   )r   r   r   rf   r   r   r   r   s           r   process_mask_nativer     s     IAr2++Ar22288RDDEdU++A.EeV$$E99S>>   r   rf   .tuple[tuple[int, int], tuple[int, int]] | Nonec                &   | j         dd         \  }}|dd         \  }}||k    r||k    r| S |Mt          ||z  ||z            }|t          ||z            z
  |t          ||z            z
  }
}	|r
|	dz  }	|
dz  }
n|d         \  }	}
|r$t          |
dz
            t          |	dz
            fnd\  }}|t          |
dz             z
  }|t          |	dz             z
  }t          j        | d||||f                                         |d          S )	a  Rescale segment masks to target shape.

    Args:
        masks (torch.Tensor): Masks with shape (N, C, H, W).
        shape (tuple[int, int]): Target height and width as (height, width).
        ratio_pad (tuple, optional): Ratio and padding values as ((ratio_h, ratio_w), (pad_w, pad_h)).
        padding (bool): Whether masks are based on YOLO-style augmented images with padding.

    Returns:
        (torch.Tensor): Rescaled masks.
    rO   NrN   rP   )r   r   .r   r   )rf   r:   rU   r   r   r	   )r   rf   rI   rK   im1_him1_wim0_him0_wrW   pad_wpad_htopleftbottomrights                  r   r   r     sB   " ;qrr?LE5!9LE5~~%5..55=%%-00edl 3 33uuUT\?R?R7Ru 	QJEQJE |u<COus{##U53;%7%788ICU53;'''FE%#+&&&E=sCJU
:;AACCUQ[\\\\r   	normalizec                   |dd         \  }}|T| dd         \  }}	t          ||z  |	|z            }
|	t          ||
z            z
  dz  |t          ||
z            z
  dz  f}n|d         d         }
|d         }|r,|dxx         |d         z  cc<   |dxx         |d         z  cc<   |dxx         |
z  cc<   |dxx         |
z  cc<   t          ||          }|r |dxx         |z  cc<   |dxx         |z  cc<   |S )av  Rescale segment coordinates from img1_shape to img0_shape.

    Args:
        img1_shape (tuple): Source image shape as HWC or HW (supports both).
        coords (torch.Tensor): Coordinates to scale with shape (N, 2).
        img0_shape (tuple): Image 0 shape as HWC or HW (supports both).
        ratio_pad (tuple, optional): Ratio and padding values as ((ratio_h, ratio_w), (pad_w, pad_h)).
        normalize (bool): Whether to normalize coordinates to range [0, 1].
        padding (bool): Whether coordinates are based on YOLO-style augmented images with padding.

    Returns:
        (torch.Tensor): Scaled coordinates.
    NrO   r   rN   rQ   rR   )r:   rU   rk   )rD   rj   rH   rI   r  rK   img0_himg0_wimg1_himg1_wrW   pads               r   scale_coordsr  9  sB     ^NFF#BQB6F?FVO44ftm,,,1FU6D==Q=Q4QUV3VV|Al !v#a& v#a& 
6NNNdNNN
6NNNdNNN,,F !v& v& Mr   c                ,   |                      d          \  }}}}}|t          j        z  t          j        dz  k    }t          j        |||          }t          j        |||          }|t          j        dz  z  }t          j        |||||gd          S )zRegularize rotated bounding boxes to range [0, pi/2).

    Args:
        rboxes (torch.Tensor): Input rotated boxes with shape (N, 5) in xywhr format.

    Returns:
        (torch.Tensor): Regularized rotated boxes.
    rm   )dimrO   )unbindr^   r   r#   wherer   )	r   r@   rA   rh   rg   r   swapw_h_s	            r   regularize_rboxesr  \  s     MMbM))MAq!Qtw;$'A+%D	T1a	 	 B	T1a	 	 B	TWq[A;1b"a(b1111r   allnp.ndarray | torch.Tensorstrategyr   list[np.ndarray]c                r   ddl m} t          | t          j                  r|                     d          n7|                                                                                                 } g }t          j	        |           D ]1}t          j        |t          j        t          j                  d         }|r|dk    rWt          |          dk    r't          j         |d |D                                 n|d                             dd          }nw|d	k    r\t          j        |t          j        d
 |D                                                                                              dd          }nt          j        d          }|                    |                    d                     3|S )a!  Convert masks to segments using contour detection.

    Args:
        masks (np.ndarray | torch.Tensor): Binary masks with shape (N, H, W).
        strategy (str): Segmentation strategy, either 'all' or 'largest'.

    Returns:
        (list): List of segment masks as float32 arrays.
    r   )merge_multi_segmentuint8r  rN   c                :    g | ]}|                     d d          S )rm   rO   )r   r   r@   s     r   r   z"masks2segments.<locals>.<listcomp>  s&    7T7T7TQ		"a8H8H7T7T7Tr   rm   rO   largestc                ,    g | ]}t          |          S r*   )r   r  s     r   r   z"masks2segments.<locals>.<listcomp>  s    (;(;(;AQ(;(;(;r   )r   rO   r   )ultralytics.data.converterr  r\   r8   ndarrayastyper   r   r   ascontiguousarrayr   findContoursRETR_EXTERNALCHAIN_APPROX_SIMPLEr   r   r   r9   argmaxr?   r   )r   r  r  r   r@   r   s         r   masks2segmentsr$  n  s    ?>>>>>%/rz%B%BbELL!!!

HXHXHZHZH`H`HbHbEH!%(( - -Q 133JKKAN 
	!5   1vvzz N#6#67T7TRS7T7T7T#U#UVVV1b!,, 
 Y&&HQrx(;(;(;(;(;<<CCEEFGGOOPRTUVV  A++,,,,Or   batchc                    |                      dddd                                          dz                      dd                                                                                                          S )a_  Convert a batch of FP32 torch tensors to NumPy uint8 arrays, changing from BCHW to BHWC layout.

    Args:
        batch (torch.Tensor): Input tensor batch with shape (Batch, Channels, Height, Width) and dtype torch.float32.

    Returns:
        (np.ndarray): Output NumPy array batch with shape (Batch, Height, Width, Channels) and dtype uint8.
    r   rO   r3   rN      )permute
contiguousre   r   r   r   )r%  s    r   convert_torch2numpy_batchr*    sa     MM!Q1%%0022S8??3GGLLNNRRTTZZ\\\r   c                0    t          j        dd|           S )zClean a string by replacing special characters with '_' character.

    Args:
        s (str): A string needing special characters replaced.

    Returns:
        (str): A string with special characters replaced by an underscore _.
    u!   [|@#!¡·$€%&()=?¿^*;:,¨`><+]_)patternreplstring)resub)r   s    r   	clean_strr2    s     6=CPQRRRRr   c                    t          | t          j                  rt          j        | | j                  nt          j        | | j                  S )zKCreate empty torch.Tensor or np.ndarray with same shape and dtype as input.r4   )r\   r#   r]   rp   r5   r8   )r@   s    r   rp   rp     sF    1;Au|1L1Lq5AQW----RTR_`aijipRqRqRqqr   )r+   r+   )r,   r-   r.   r/   r0   r/   r1   r-   )NTF)rD   rE   rF   rG   rH   rE   rI   rJ   rK   r   rL   r   r1   rG   )r@   r/   )r+   r+   r   r   )rh   r/   rg   r/   rz   r/   r{   r/   )r+   r+   Fr   )rh   r/   rg   r/   r=   r   r   r	   )r   )r   r/   )r   r   rF   r   r1   r   )F)r   r   )NT)
r   r   rf   rE   rI   r   rK   r   r1   r   )NFT)r  r   rK   r   )r  )r   r  r  r   r1   r  )r%  r   r1   r-   )-
__future__r   
contextlibr^   r0  r   r   r   r8   r#   torch.nn.functionalnn
functionalr   ultralytics.utilsr   ContextDecoratorr   rC   rZ   ra   rV   rk   ru   ry   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r$  r*  r2  rp   r*   r   r   <module>r;     s   # " " " " "      				  



               ) ) ) ) ) )4# 4# 4# 4# 4#j) 4# 4# 4#n    B #'< '< '< '< '<T, , , ,  8  0  (  &    0    4      d d d>+ + +<  & & &     .E E E E6! ! ! ! !6! ! !, AE	!] !] !] !] !]H         F2 2 2$    >	] 	] 	] 	]	S 	S 	Sr r r r rr   