
    /jwe                    ^   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dFdGd
ZdHdIdZdJdZd Zd Zd Zd ZdKdLdZdMdNd Zd! Zd" Zd# Zd$ Zd% Zd& Z d' Z!dOdPd*Z"dQd/Z#dRdSd1Z$d2 Z%	 	 dTdUd7Z&dVdWd9Z'd: Z(dXdYd@Z)dZdCZ*dD Z+dE 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      Z/home/longshao/multi-rider-rag/.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     widthintheightc                   | 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anyr2   zeros)segmentr,   r.   xyinsides         r   segment2boxrA   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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 )a(  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): Shape of the source image (height, width).
        boxes (torch.Tensor): Bounding boxes to rescale in format (N, 4).
        img0_shape (tuple): 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): Rescaled bounding boxes in the same format as input.
    Nr         皙?.r   .rE   .rF   .r0   .r3   )r7   round
clip_boxes)	
img1_shapeboxes
img0_shape	ratio_padrB   rC   gainpad_xpad_ys	            r   scale_boxesrU   f   sP   " :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-   r8   mathceil)r>   divisors     r   make_divisibler\      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.
    NrF   rH   r   rI   rJ   rK   .rE   r0   rW   r#   rX   r   clamp_clampr:   )rO   shapehws       r   rM   rM      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.
    NrF   rH   r   rI   r^   )coordsra   rb   rc   s       r   clip_coordsrf      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.
    r3   9input shape last dimension expected 4 but input shape is rH   rI   rJ   rK   rF   ra   
empty_like)r>   r?   x1y1x2y2s         r   	xyxy2xywhrp      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.
    rh   r3   ri   .NrF   rj   )r>   r?   xywhs       r   	xywh2xyxyrt      s     72;!bYZY`bb1A	
37B	
37aBbAc2A2gJbAc122gJHr   rc   rb   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.
    rh   r3   ri   rH   rI   rJ   rK   rF   rj   )r>   rc   rb   ru   rv   r?   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.
    rh   r3   ri   rH   rI   rJ   rK   rF   )rM   ra   rk   )
r>   rc   rb   r:   r   r?   rl   rm   rn   ro   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.
    rH   rJ   rF   rI   rK   rW   r#   rX   cloner5   copyr>   r?   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.
    rJ   rH   rK   rI   r   r   s     r   	xyxy2ltwhr   4  _      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.
    rH   rJ   rF   rI   rK   r   r   s     r   	ltwh2xywhr   C  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).
    rh   rF      r0   r3   r
   r2   )rW   r#   rX   cpunumpyreshapelencv2minAreaRectr5   piappendtensorr
   r2   asarray)r>   is_torchpointsrboxesptscxcyrc   rb   anglethetas              r   xyxyxyxy2xywhrr   R  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).
    .NrF   c              3  6   K   | ]}d ||dz   f         V  dS ).rE   Nr*   ).0ir>   s     r   	<genexpr>z!xywhr2xyxyxyxy.<locals>.<genexpr>  s4      ::1S!a!e)^$::::::r      rh   )
rW   r#   rX   cossincatstackr5   concatenaterange)r>   r   r   r   r   ctrrc   rb   r   	cos_value	sin_valuevec1vec2pt1pt2pt3pt4s   `                r   xywhr2xyxyxyxyr   q  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.
    rJ   rH   rK   rI   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.
    )r4   r   r7   r8   rp   r5   r6   )segmentsrO   sr>   r?   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   rE   N)axisc           	     P    g | ]"}t          j        d d |f                   #S )N)r5   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   rF   r1   rh   )	enumerater   r5   r   linspacearangeinsertsearchsortedr   float32r   r4   )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.TensorrO   returnc                   |j         | j         k    r|                    | j                   }| j        \  }}}|dk     rq| j        sjt	          |                                                                          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   Nr3   rE   r   )r
   tora   is_cudar   rL   r-   r#   chunkr   r2   )r   rO   r   rb   rc   r   rl   rm   rn   ro   rcs               r   	crop_maskr     s    |u|##&&kGAq!2vvemv#,U[[]]->->-@-@#A#A 	! 	!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.
    rh   rE   r   )r
   )rO   Nbilinearmoder   )ra   r	   viewr#   r   r
   r   Finterpolategt_byte)protosmasks_inbboxesra   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).
    rh   Nr   r   )ra   r	   r   scale_masksr   r   r   )r   r   r   ra   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   ra   tuple[int, int]rQ   .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.
    rF   NrE   rG   )r   r   .r   r   )ra   r7   rL   r   r   r	   )r   ra   rQ   rB   im1_him1_wim0_him0_wrR   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.
    NrF   r   rE   rH   rI   )r7   rL   rf   )rN   re   rP   rQ   r   rB   img0_himg0_wimg1_himg1_wrR   pads               r   scale_coordsr  2  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.
    rh   )dimrF   )unbindrY   r   r#   wherer   )	r   r>   r?   rc   rb   r   swapw_h_s	            r   regularize_rboxesr  U  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  rE   c                :    g | ]}|                     d d          S )rh   rF   )r   r   r>   s     r   r   z"masks2segments.<locals>.<listcomp>z  s&    7T7T7TQ		"a8H8H7T7T7Tr   rh   rF   largestc                ,    g | ]}t          |          S r*   )r   r  s     r   r   z"masks2segments.<locals>.<listcomp>  s    (;(;(;AQ(;(;(;r   )r   rF   r   )ultralytics.data.converterr  rW   r5   ndarrayastyper   r   r   ascontiguousarrayr   findContoursRETR_EXTERNALCHAIN_APPROX_SIMPLEr   r   r   r6   argmaxr<   r   )r   r  r  r   r>   r   s         r   masks2segmentsr!  g  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   batch
np.ndarrayc                    |                      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   rF   r0   rE      )permute
contiguousr`   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_strr0    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.r1   )rW   r#   rX   rk   r2   r5   )r>   s    r   rk   rk     sF    1;Au|1L1Lq5AQW----RTR_`aijipRqRqRqqr   )r+   r+   )r,   r-   r.   r-   )NTF)rB   r   rC   r   )r>   r-   )r+   r+   r   r   )rc   r-   rb   r-   ru   r-   rv   r-   )r+   r+   Fr   )rc   r-   rb   r-   r:   r   r   r	   )r   )r   r-   )r   r   rO   r   r   r   )F)r   r   )NT)
r   r   ra   r   rQ   r   rB   r   r   r   )NFT)r   r   rB   r   )r  )r   r  r  r   r   r  )r"  r   r   r#  )-
__future__r   
contextlibrY   r.  r   r   r   r5   r#   torch.nn.functionalnn
functionalr   ultralytics.utilsr   ContextDecoratorr   rA   rU   r\   rM   rf   rp   rt   r~   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r!  r(  r0  rk   r*   r   r   <module>r9     s   # " " " " "      				  



               ) ) ) ) ) )4# 4# 4# 4# 4#j) 4# 4# 4#n    : <  <  <  <  <F, , , ,  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   