
    ^js2                    .   d dl mZ d dlZd dlmZ d dlmZm	Z	 d dl
mZ 	 	 	 	 	 	 ddZ	 d	 	 	 	 	 	 	 ddZ e	ej                  dd	d
di      	 	 d	 	 	 	 	 	 	 	 	 dd       Z	 	 	 	 	 	 ddZ	 	 	 	 	 	 ddZddZ	 	 	 	 ddZ	 	 	 	 	 	 ddZ	 d	 	 	 	 	 ddZy)    )annotationsN)
TargetMode
deprecated)box_iou_batchxyxyc                    t        j                  |       }|\  }}|ddddgf   j                  d|      |ddddgf<   |ddddgf   j                  d|      |ddddgf<   |S )a  
    Clips bounding boxes coordinates to fit within the frame resolution.

    Args:
        xyxy: A numpy array of shape `(N, 4)` where each
            row corresponds to a bounding box in
            the format `(x_min, y_min, x_max, y_max)`.
        resolution_wh: A tuple of the form
            `(width, height)` representing the resolution of the frame.

    Returns:
        A numpy array of shape `(N, 4)` where each row
            corresponds to a bounding box with coordinates clipped to fit
            within the frame resolution.

    Examples:
        ```pycon
        >>> import numpy as np
        >>> import supervision as sv
        >>> xyxy = np.array([
        ...     [10, 20, 300, 200],
        ...     [15, 25, 350, 450],
        ...     [-10, -20, 30, 40]
        ... ])
        >>> sv.clip_boxes(xyxy=xyxy, resolution_wh=(320, 240))
        array([[ 10,  20, 300, 200],
               [ 15,  25, 320, 240],
               [  0,   0,  30,  40]])

        ```
    Nr            )npcopyclip)r   resolution_whresultwidthheights        l/var/www/ramen.bs-engineer-server.com/venv/lib/python3.12/site-packages/supervision/detection/utils/boxes.py
clip_boxesr   
   sx    F &(WWT]F!ME6q1a&y)..q%8F1q!f9q1a&y)..q&9F1q!f9M    c                    ||}| j                         }|ddddgfxx   ||gz  cc<   |ddddgfxx   ||gz  cc<   |S )a  
    Pads bounding boxes coordinates with a constant padding.

    Args:
        xyxy: A numpy array of shape `(N, 4)` where each
            row corresponds to a bounding box in the format
            `(x_min, y_min, x_max, y_max)`.
        px: The padding value to be added to both the left and right sides of
            each bounding box.
        py: The padding value to be added to both the top and bottom
            sides of each bounding box. If not provided, `px` will be used for both
            dimensions.

    Returns:
        A numpy array of shape `(N, 4)` where each row corresponds to a
            bounding box with coordinates padded according to the provided padding
            values.

    Examples:
        ```pycon
        >>> import numpy as np
        >>> import supervision as sv
        >>> xyxy = np.array([
        ...     [10, 20, 30, 40],
        ...     [15, 25, 35, 45]
        ... ])
        >>> sv.pad_boxes(xyxy=xyxy, px=5, py=10)
        array([[ 5, 10, 35, 50],
               [10, 15, 40, 55]])

        ```
    Nr   r
   r	   r   r   )r   pxpyr   s       r   	pad_boxesr   4   sW    J 
zYY[F
1q!f9"b!
1q!f9"b!Mr   z0.27.0z0.30.0normalized_xyxy)targetdeprecated_in	remove_inargs_mappingc                    |\  }}| j                         }|ddddgf   |z  |z  |ddddgf<   |ddddgf   |z  |z  |ddddgf<   |S )a  
    Convert normalized bounding box coordinates to absolute pixel coordinates.

    Multiplies each bounding box coordinate by image size and divides by
    `normalization_factor`, mapping values from normalized `[0, normalization_factor]`
    to absolute pixel values for a given resolution.

    Args:
        xyxy: Normalized bounding boxes of shape `(N, 4)`,
            where each row is `(x_min, y_min, x_max, y_max)`, values in
            `[0, normalization_factor]`.
        resolution_wh: Target image resolution as `(width, height)`.
        normalization_factor: Maximum value of input coordinate range.
            Defaults to `1.0`.

    Returns:
        Array of shape `(N, 4)` with absolute coordinates in
            `(x_min, y_min, x_max, y_max)` format.

    Examples:
        ```pycon
        >>> import numpy as np
        >>> import supervision as sv
        >>> xyxy = np.array([
        ...     [0.1, 0.2, 0.5, 0.6],
        ...     [0.3, 0.4, 0.7, 0.8],
        ...     [0.2, 0.1, 0.6, 0.5]
        ... ])
        >>> sv.denormalize_boxes(xyxy, (1280, 720))
        array([[128., 144., 640., 432.],
               [384., 288., 896., 576.],
               [256.,  72., 768., 360.]])

        ```

        ```pycon
        >>> xyxy = np.array([
        ...     [256., 128., 768., 640.]
        ... ])
        >>> sv.denormalize_boxes(xyxy, (1280, 720), normalization_factor=1024.0)
        array([[320.,  90., 960., 450.]])

        ```
    Nr   r	   r
   r   r   )r   r   normalization_factorr   r   r   r   s          r   denormalize_boxesr"   c   sr    p "ME6YY[FAq6	*U26JJF1q!f9Aq6	*V37KKF1q!f9Mr   c                6    | t        j                  ||g      z   S )a  
    Args:
        xyxy: An array of shape `(n, 4)` containing the
            bounding boxes coordinates in format `[x1, y1, x2, y2]`
        offset: An array of shape `(2,)` containing offset values in format
            is `[dx, dy]`.

    Returns:
        Repositioned bounding boxes.

    Examples:
        ```pycon
        >>> import numpy as np
        >>> import supervision as sv
        >>> xyxy = np.array([
        ...     [10, 10, 20, 20],
        ...     [30, 30, 40, 40]
        ... ])
        >>> offset = np.array([5, 5])
        >>> sv.move_boxes(xyxy=xyxy, offset=offset)
        array([[15, 15, 25, 25],
               [35, 35, 45, 45]])

        ```
    )r   hstack)r   offsets     r   
move_boxesr&      s    8 "))VV,---r   c                    | |z   S )a  
    Args:
        xyxyxyxy: An array of shape `(n, 4, 2)` containing the
        oriented bounding boxes coordinates in format
        `[[x1, y1], [x2, y2], [x3, y3], [x3, y3]]`
        offset: An array of shape `(2,)` containing offset values in format
            is `[dx, dy]`.

    Returns:
        Repositioned bounding boxes.

    Examples:
        ```pycon
        >>> import numpy as np
        >>> from supervision.detection.utils.boxes import move_oriented_boxes
        >>> xyxyxyxy = np.array([
        ...     [
        ...         [20, 10],
        ...         [10, 20],
        ...         [20, 30],
        ...         [30, 20]
        ...     ],
        ...     [
        ...         [30, 30],
        ...         [20, 40],
        ...         [30, 50],
        ...         [40, 40]
        ...     ]
        ... ])
        >>> offset = np.array([5, 5])
        >>> move_oriented_boxes(xyxyxyxy=xyxyxyxy, offset=offset)
        array([[[25, 15],
                [15, 25],
                [25, 35],
                [35, 25]],
        <BLANKLINE>
               [[35, 35],
                [25, 45],
                [35, 55],
                [45, 45]]])

        ```
     )xyxyxyxyr%   s     r   move_oriented_boxesr*      s    \ fr   c                   t        j                  |       } | j                  dk7  s| j                  dd dk7  rt	        d| j                         | d   j                  t         j                  d      }| d	   j                  t         j                  d      }|t        j                  |d
d
      z  |t        j                  |d
d
      z  z
  }dt        j                  t        j                  |d
            z  S )aB  Compute the area of N oriented bounding boxes using the shoelace formula.

    Args:
        corners: OBB corner coordinates with shape `(N, 4, 2)`.

    Returns:
        Area of each box as a 1-D float64 array of shape `(N,)`.

    Raises:
        ValueError: If `corners` does not have shape `(N, 4, 2)`.

    Examples:
        >>> import numpy as np
        >>> from supervision.detection.utils.boxes import obb_polygon_area
        >>> corners = np.array([[[0, 5], [5, 10], [10, 5], [5, 0]]], dtype=np.float32)
        >>> obb_polygon_area(corners)
        array([50.])
    r   N   r	   z'corners must have shape (N, 4, 2); got .r   Fr   .r
   axisg      ?)
r   asarrayndimshape
ValueErrorastypefloat64rollabssum)cornersxycrosss       r   obb_polygon_arearA      s    & jj!G||qGMM"#.&8B7==/RSSrzz6Arzz6A2B''!bgga".E*EEEu2.///r   c                |   t        j                  |       } | j                  dk7  s| j                  dd dk7  rt	        d| j                         | d   j                  d      }| d	   j                  d      }| d   j                  d      }| d	   j                  d      }t        j                  ||||gd      S )
ad  Convert oriented bounding box corners to axis-aligned bounding boxes.

    Args:
        xyxyxyxy: OBB corner coordinates with shape `(N, 4, 2)` where each
            box is represented as `[[x1, y1], [x2, y2], [x3, y3], [x4, y4]]`.

    Returns:
        Axis-aligned bounding boxes as an array of shape `(N, 4)`
            in `(x_min, y_min, x_max, y_max)` format.

    Raises:
        ValueError: If `xyxyxyxy` does not have shape `(N, 4, 2)`.

    Examples:
        ```pycon
        >>> import numpy as np
        >>> import supervision as sv
        >>> corners = np.array([
        ...     [[0, 0], [10, 0], [10, 5], [0, 5]],
        ...     [[5, 5], [15, 5], [15, 10], [5, 10]],
        ... ], dtype=np.float32)
        >>> sv.xyxyxyxy_to_xyxy(corners)
        array([[ 0.,  0., 10.,  5.],
               [ 5.,  5., 15., 10.]], dtype=float32)

        ```
    r   r,   Nr-   z(xyxyxyxy must have shape (N, 4, 2); got r/   r1   r2   r0   )r   r4   r5   r6   r7   minmaxstack)r)   x_miny_minx_maxy_maxs        r   xyxyxyxy_to_xyxyrJ     s    < zz(#H}}X^^BC0F:CHNNCSTUUV  b )EV  b )EV  b )EV  b )E88UE5%0r::r   c                    | ddddf   | ddddf   z   dz  }| ddddf   | ddddf   z
  |z  }t        j                  ||dz  z
  ||dz  z   fd      S )a  
    Scale the dimensions of bounding boxes.

    Args:
        xyxy: An array of shape `(n, 4)` containing the
            bounding boxes coordinates in format `[x1, y1, x2, y2]`
        factor: A float value representing the factor by which the box
            dimensions are scaled. A factor greater than 1 enlarges the boxes, while a
            factor less than 1 shrinks them.

    Returns:
        Scaled bounding boxes.

    Examples:
        ```pycon
        >>> import numpy as np
        >>> import supervision as sv
        >>> xyxy = np.array([
        ...     [10, 10, 20, 20],
        ...     [30, 30, 40, 40]
        ... ])
        >>> sv.scale_boxes(xyxy=xyxy, factor=1.5)
        array([[ 7.5,  7.5, 22.5, 22.5],
               [27.5, 27.5, 42.5, 42.5]])

        ```
    Nr	   r
   r2   )r   concatenate)r   factorcenters	new_sizess       r   scale_boxesrP   8  sw    < ArrE{T!QR%[(A-GaetArrE{*f4I>>7Y]2Gi!m4KLSTUUr   c                   t        |       dk(  r| S t        | d      }t        |      D ]  }t        ||      }t	        j
                  |d       t	        j                  |dk(        r ni|dkD  }|ddddf   |ddddf   z   dz  }|ddt        j                  ddf   |t        j                  ddddf   z
  }||ddddt        j                  f   z  }t	        j                  |d      }t        j                  j                  |dd      }	t	        j                  ||	t	        j                  |      |	dk7  	      }
t	        j                  |d      }|ddt        j                  f   |
z  }|d
z  }d||dkD  |dk  z  <   d||dk  |dkD  z  <   |j                  t              }|ddddgfxx   |z  cc<   |ddddgfxx   |z  cc<    t        |d      S )a  
    Spread out boxes that overlap with each other.

    Args:
        xyxy: Numpy array of shape (N, 4) where N is the number of boxes.
        max_iterations: Maximum number of iterations to run the algorithm for.

    Example:
        ```pycon
        >>> import numpy as np
        >>> from supervision.detection.utils.boxes import spread_out_boxes
        >>> xyxy = np.array([
        ...     [10, 10, 20, 20],
        ...     [12, 12, 22, 22]
        ... ])
        >>> spread_out = spread_out_boxes(xyxy=xyxy, max_iterations=10)
        >>> # The boxes should be moved apart
        >>> bool(spread_out[0, 0] < 10 and spread_out[0, 1] < 10)
        True
        >>> bool(spread_out[1, 0] > 12 and spread_out[1, 1] > 12)
        True

        ```
    r   r
   )r   Nr	   r2   T)r3   keepdims)outwhere
   r,   r   r1   )lenr   ranger   r   fill_diagonalallnewaxisr<   linalgnormdivide
zeros_liker8   int)r   max_iterationsxyxy_padded_iouoverlap_maskrN   delta_centers	delta_sumdelta_magnitudedirection_vectorsforce_vectorss               r   spread_out_boxesrj   [  s   8 4yA~DQ'K>" $0K5
a 66#(Qw q"1"u%AqrE(::a?  2::q 01GBJJ1<L4MMaBJJ&677 FF=q1	))..T.JIIi(!Q&	
 s+%am47HHCD}q(]Q->?@DF}q(]R-?@A%,,S1A1vI-/A1vI-/I$0L [R((r   )r   npt.NDArray[np.number]r   tuple[int, int]returnrk   )N)r   rk   r   r_   r   z
int | Nonerm   rk   )g      ?N)
r   rk   r   rl   r!   floatr   znpt.NDArray[np.number] | Nonerm   rk   )r   npt.NDArray[np.float64]r%   npt.NDArray[np.int32]rm   ro   )r)   ro   r%   rp   rm   ro   )r=   znpt.NDArrayrm   ro   )r)   rk   rm   rk   )r   ro   rM   rn   rm   ro   )d   )r   rk   r`   r_   rm   rk   )
__future__r   numpyr   numpy.typingtypingnpt	deprecater   r   'supervision.detection.utils.iou_and_nmsr   r   r   
ARGS_REMAPr"   r&   r*   rA   rJ   rP   rj   r(   r   r   <module>rz      sj   "   , A'
 '"' 'Z ,
 ,, 	, 	,^   #V,	 #&59	8
 8"8  8 3	8
 88v.
!.+@..>.%./D..b08%;$%;%;P V
! V+0 V VJ F)
 F)F) F)r   