Ë
    ¼Ó^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 &(§W¡W¨T£]€FØ!�M€Eˆ6Øšq 1 a &˜yÑ)×.Ñ.¨q°%Ó8€FŠ1ˆq�!ˆfˆ9ÑØšq 1 a &˜yÑ)×.Ñ.¨q°&Ó9€FŠ1ˆq�!ˆfˆ9ÑØ€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Øˆà�Y‰Y‹[€FØ
Š1ˆq�!ˆfˆ9Ó˜"˜b˜Ñ!ÓØ
Š1ˆq�!ˆfˆ9Ó˜"˜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 "�M€Eˆ6Ø�Y‰Y‹[€Fà¢ A q 6 	Ñ*¨UÑ2Ð6JÑJ€FŠ1ˆq�!ˆfˆ9ÑØ¢ A q 6 	Ñ*¨VÑ3Ð7KÑK€FŠ1ˆq�!ˆfˆ9Ñà€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 ”"—)‘)˜V VÐ,Ó-Ñ-Ð-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Î   € ô& �j‰j˜Ó!€GØ‡|�|�qÒ˜GŸM™M¨"¨#Ð.°&Ò8ÜÐBÀ7Ç=Á=À/ÐRÓSÐSØ�‰×ÑœrŸz™z°ÐÓ6€AØ�‰×ÑœrŸz™z°ÐÓ6€AØ”—‘˜˜2 BÔ'Ñ'¨!¬b¯g©g°a¸À"Ô.EÑ*EÑE€EØ”—‘œŸ™˜u¨2Ô.Ó/Ñ/Ð/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Â   € ô< �z‰z˜(Ó#€HØ‡}�}˜Ò˜XŸ^™^¨B¨CÐ0°FÒ:ÜÐCÀHÇNÁNÐCSÐTÓUÐUØ�VÑ× Ñ  bÐ Ó)€EØ�VÑ× Ñ  bÐ Ó)€EØ�VÑ× Ñ  bÐ Ó)€EØ�VÑ× Ñ  bÐ Ó)€EÜ�8‰8�U˜E 5¨%Ð0°rÔ:Ð: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   € ð< ’A�r˜�r�E‰{˜T¢! Q¡R %™[Ñ(¨AÑ-€GØ’a˜™�e‘˜t¢A r¨ r E™{Ñ*¨fÑ4€IÜ�>‰>˜7 Y°¡]Ñ2°G¸iÈ!¹mÑ4KÐLÐSTÔ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 ˆ4ƒy�A‚~Øˆä˜D QÔ'€KÜ�>Ó"ó $0ˆä˜K¨Ó5ˆÜ
×Ñ˜˜aÔ Ü�6‰6�#˜‘(ÔÚà˜Q‘wˆð šq " 1 "˜uÑ%¨²A°q±r°EÑ(:Ñ:¸aÑ?ˆð  ¢¤2§:¡:ªqÐ 0Ñ1°G¼B¿J¹JÊÊ1Ð<LÑ4MÑMˆØ˜¢aª¬B¯J©JÐ&6Ñ7Ñ7ˆô —F‘F˜=¨qÔ1ˆ	ÜŸ)™)Ÿ.™.¨¸ÀT˜.ÓJˆÜŸI™IØØÜ—‘˜iÓ(Ø! QÑ&ô	
Ðô Ÿ™˜s¨Ô+ˆØ%¢a¬¯© mÑ4Ð7HÑHˆà˜ÑˆØCDˆ�} qÑ(¨]¸QÑ->Ñ?Ñ@ØDFˆ�} qÑ(¨]¸RÑ-?Ñ@ÑAà%×,Ñ,¬SÓ1ˆà’A˜˜1�v�IÓ -Ñ/ÓØ’A˜˜1�v�IÓ -Ñ/ÕðI$0ôL �[ 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0ð8%;Ø$ð%;àó%;ðP VØ
!ð VØ+0ð Vàó VðJ ðF)Ø
 ðF)àðF)ð ôF)r   