
    3jS]                        S SK Jr  S SKrS SKJr  S SKrSSKJr  / SQrSS jr	SS jr
SS	 jrSS
 jrSS jrSS jr          SS jr              SS jr S         SS jjrSS jrg)    )annotationsN)Optional   )transform_points)
bbox_generatorbbox_generator3dbbox_to_maskbbox_to_mask3dinfer_bbox_shapeinfer_bbox_shape3dnmstransform_bboxvalidate_bboxvalidate_bbox3dc                :   [        U R                  5      S;   a)  U R                  SS [        R                  " SS/5      :X  d  g[        U R                  5      S:X  a  U R	                  SSS5      n U S   U S	   p!U S
   U S   pCU S   U S   peU S   U S   pX1-
  S-   XW-
  S-   pXB-
  S-   Xh-
  S-   p[        R
                  " X-
  5      n[        R
                  " X-
  5      n[        R                  " US:  5      (       a  g[        R                  " US:  5      (       a  gg)a  Validate if a 2D bounding box usable or not. This function checks if the boxes are rectangular or not.

Args:
    boxes: a tensor containing the coordinates of the bounding boxes to be extracted. The tensor must have the shape
        of Bx4x2, where each box is defined in the following ``clockwise`` order: top-left, top-right, bottom-right,
        bottom-left. The coordinates must be in the x, y order.

      Nr      F).r   r   ).r   r   ).r   r   ).r   r   ).r   r   ).r   r   ).r   r   ).r   r   r   g-C6?T)lenshapetorchSizeviewabsany)boxesx_tly_tlx_try_trx_bry_brx_bly_blwidth_twidth_bheight_theight_b
width_diffheight_diffs                  N/home/wildlama/miniconda3/lib/python3.13/site-packages/kornia/geometry/bbox.pyr   r   )   s    &5;;rs+;uzz1a&?Q+Q
5;;1

2q!$y!5#3$y!5#3$y!5#3$y!5#3${QaWq$+/h 7,-J))H/0K yyd"##yyt#$$    c           
     r   [        U R                  5      S;   a)  U R                  SS [        R                  " SS/5      :X  d  [	        SU R                   S35      e[        U R                  5      S:X  a  U R                  S	SS5      n [        R                  " U S
[        R                  " / SQU R                  [        R                  S95      SS2SS2S4   n[        R                  " U S
[        R                  " / SQU R                  [        R                  S95      SS2SS2S4   nX-
  S
-   n[        R                  " UR                  S
S5      USS2S4   5      (       d  [	        SU S35      e[        R                  " U S
[        R                  " / SQU R                  [        R                  S95      SS2SS2S
4   n[        R                  " U S
[        R                  " / SQU R                  [        R                  S95      SS2SS2S
4   nXE-
  S
-   n[        R                  " UR                  S
S5      USS2S4   5      (       d  [	        SU S35      eU SS2SS2S4   U SS2SS2S4   -
  S
-   n[        R                  " UR                  S
S5      USS2S4   5      (       d  [	        SU S35      eg)a  Validate if a 3D bounding box usable or not. This function checks if the boxes are cube or not.

Args:
    boxes: a tensor containing the coordinates of the bounding boxes to be extracted. The tensor must have the shape
        of Bx8x3, where each box is defined in the following ``clockwise`` order: front-top-left, front-top-right,
        front-bottom-right, front-bottom-left, back-top-left, back-top-right, back-bottom-right, back-bottom-left.
        The coordinates must be in the x, y, z order.

r   r   N   r   z1Box shape must be (B, 8, 3) or (B, N, 8, 3). Got .r   r   r   r   r         devicedtyper   r   r   r      z4Boxes must have be cube, while get different widths r   r   r5   r:   r   r   r   r4   z5Boxes must have be cube, while get different heights r   z4Boxes must have be cube, while get different depths T)r   r   r   r   AssertionErrorr   index_selecttensorr7   longallclosepermuter   leftrightwidthsbotupperheightsdepthss           r.   r   r   N   sX    &5;;rs+;uzz1a&?Q+QPQVQ\Q\P]]^_``
5;;1

2q!$eQ\%,,^c^h^h(ijklnoqrkrsDual5<<_d_i_i)jklmoprslstE\AF>>&..A.q!t==STZS[[\]^^


UAu||L]b]g]g'h
ijkmnpqjq
rCual5<<_d_i_i)jklmoprslstEkAoG>>'//!Q/A??TU\T]]^_``1ab!8_uQAX.2F>>&..A.q!t==STZS[[\]^^r/   c                ~    [        U 5        U SS2SS4   U SS2SS4   -
  S-   nU SS2SS4   U SS2SS4   -
  S-   nX!4$ )a"  Auto-infer the output sizes for the given 2D bounding boxes.

Args:
    boxes: a tensor containing the coordinates of the bounding boxes to be extracted. The tensor must have the shape
        of Bx4x2, where each box is defined in the following ``clockwise`` order: top-left, top-right, bottom-right,
        bottom-left. The coordinates must be in the x, y order.

Returns:
    - Bounding box heights, shape of :math:`(B,)`.
    - Boundingbox widths, shape of :math:`(B,)`.

Example:
    >>> boxes = torch.tensor([[
    ...     [1., 1.],
    ...     [2., 1.],
    ...     [2., 2.],
    ...     [1., 2.],
    ... ], [
    ...     [1., 1.],
    ...     [3., 1.],
    ...     [3., 2.],
    ...     [1., 2.],
    ... ]])  # 2x4x2
    >>> infer_bbox_shape(boxes)
    (tensor([2., 2.]), tensor([2., 3.]))

Nr   r   r   )r   )r   widthheights      r.   r   r   q   sZ    8 %1a.5Aq>9A=E Aq>E!Q'N:Q>F=r/   c           
        [        U 5        [        R                  " U S[        R                  " / SQU R                  [        R
                  S95      SS2SS2S4   n[        R                  " U S[        R                  " / SQU R                  [        R
                  S95      SS2SS2S4   nX-
  S-   SS2S4   n[        R                  " U S[        R                  " / SQU R                  [        R
                  S95      SS2SS2S4   n[        R                  " U S[        R                  " / SQU R                  [        R
                  S95      SS2SS2S4   nXE-
  S-   SS2S4   nU SS2S	S2S
4   U SS2SS	2S
4   -
  S-   SS2S4   nXvU4$ )a  Auto-infer the output sizes for the given 3D bounding boxes.

Args:
    boxes: a tensor containing the coordinates of the bounding boxes to be extracted. The tensor must have the shape
        of Bx8x3, where each box is defined in the following ``clockwise`` order: front-top-left, front-top-right,
        front-bottom-right, front-bottom-left, back-top-left, back-top-right, back-bottom-right, back-bottom-left.
        The coordinates must be in the x, y, z order.

Returns:
    - Bounding box depths, shape of :math:`(B,)`.
    - Bounding box heights, shape of :math:`(B,)`.
    - Bounding box widths, shape of :math:`(B,)`.

Example:
    >>> boxes = torch.tensor([[[ 0,  1,  2],
    ...         [10,  1,  2],
    ...         [10, 21,  2],
    ...         [ 0, 21,  2],
    ...         [ 0,  1, 32],
    ...         [10,  1, 32],
    ...         [10, 21, 32],
    ...         [ 0, 21, 32]],
    ...        [[ 3,  4,  5],
    ...         [43,  4,  5],
    ...         [43, 54,  5],
    ...         [ 3, 54,  5],
    ...         [ 3,  4, 65],
    ...         [43,  4, 65],
    ...         [43, 54, 65],
    ...         [ 3, 54, 65]]]) # 2x8x3
    >>> infer_bbox_shape3d(boxes)
    (tensor([31, 61]), tensor([21, 51]), tensor([11, 41]))

r   r3   r6   Nr   r9   r;   r<   r   r   )r   r   r>   r?   r7   r@   rC   s           r.   r   r      s_   F EeQ\%,,^c^h^h(ijklnoqrkrsDual5<<_d_i_i)jklmoprslstElQ1%F


UAu||L]b]g]g'h
ijkmnpqjq
rCual5<<_d_i_i)jklmoprslstE{Q1%GAqr1Hoa!Qh/!3QT:FF""r/   c                0   [        U 5        [        R                  " X R                  U R                  S9R                  US5      n[        R                  " XR                  U R                  S9R                  SU5      nU SS2SS4   R                  SSS5      nU SS2SS4   R                  SSS5      nU SS2SS4   R                  SSS5      nU SS2SS4   R                  SSS5      nXE:  XG:*  -  X6:  -  X8:*  -  n	U	R                  U R                  5      $ )a  Convert 2D bounding boxes to masks. Covered area is 1. and the remaining is 0.

Args:
    boxes: a tensor containing the coordinates of the bounding boxes to be extracted. The tensor must have the shape
        of Bx4x2, where each box is defined in the following ``clockwise`` order: top-left, top-right, bottom-right
        and bottom-left. The coordinates must be in the x, y order.
    width: width of the masked image.
    height: height of the masked image.

Returns:
    the output mask tensor.

Note:
    It is currently non-differentiable.

Examples:
    >>> boxes = torch.tensor([[
    ...        [1., 1.],
    ...        [3., 1.],
    ...        [3., 2.],
    ...        [1., 2.],
    ...   ]])  # 1x4x2
    >>> bbox_to_mask(boxes, 5, 5)
    tensor([[[0., 0., 0., 0., 0.],
             [0., 1., 1., 1., 0.],
             [0., 1., 1., 1., 0.],
             [0., 0., 0., 0., 0.],
             [0., 0., 0., 0., 0.]]])

r6   r   Nr   r   r   )r   r   aranger7   r8   r   to)
r   rL   rM   yyxxx_miny_minx_maxy_maxmasks
             r.   r	   r	      s    > %	f\\	E	J	J6ST	UB	eLL	D	I	I!U	SB!Q'NAq)E!Q'NAq)E!Q'NAq)E!Q'NAq)EKBK(BK8BKHD775;;r/   c                   [        U 5        Uu  p#nU SS2SS4   R                  5       nU SS2SS4   R                  5       nU SS2SS4   R                  5       nU SS2SS4   R                  5       nU SS2SS4   R                  5       n	U SS2SS4   R                  5       n
[        R                  " X R                  [        R                  S9n[        R                  " X0R                  [        R                  S9n[        R                  " X@R                  [        R                  S9nUSSS24   USS2S4   :  USSS24   USS2S4   :*  -  SS2SSS2SS4   USSS24   USS2S4   :  USSS24   USS2S4   :*  -  SS2SSSS2S4   -  USSS24   U	SS2S4   :  USSS24   U
SS2S4   :*  -  SS2SSSSS24   -  R                  5       nUR                  SSS	9R                  SSS	9nUR                  SSS	9R                  SSS	9nUR                  SSS	9R                  SSS	9nUU-  U-  nUR                  5       $ )
a  Convert 3D bounding boxes to masks. Covered area is 1. and the remaining is 0.

Args:
    boxes: a tensor containing the coordinates of the bounding boxes to be extracted. The tensor must have the shape
        of Bx8x3, where each box is defined in the following ``clockwise`` order: front-top-left, front-top-right,
        front-bottom-right, front-bottom-left, back-top-left, back-top-right, back-bottom-right, back-bottom-left.
        The coordinates must be in the x, y, z order.
    size: depth, height and width of the masked image.

Returns:
    the output mask tensor.

Examples:
    >>> boxes = torch.tensor([[
    ...     [1., 1., 1.],
    ...     [2., 1., 1.],
    ...     [2., 2., 1.],
    ...     [1., 2., 1.],
    ...     [1., 1., 2.],
    ...     [2., 1., 2.],
    ...     [2., 2., 2.],
    ...     [1., 2., 2.],
    ... ]])  # 1x8x3
    >>> bbox_to_mask3d(boxes, (4, 5, 5))
    tensor([[[[[0., 0., 0., 0., 0.],
               [0., 0., 0., 0., 0.],
               [0., 0., 0., 0., 0.],
               [0., 0., 0., 0., 0.],
               [0., 0., 0., 0., 0.]],
    <BLANKLINE>
              [[0., 0., 0., 0., 0.],
               [0., 1., 1., 0., 0.],
               [0., 1., 1., 0., 0.],
               [0., 0., 0., 0., 0.],
               [0., 0., 0., 0., 0.]],
    <BLANKLINE>
              [[0., 0., 0., 0., 0.],
               [0., 1., 1., 0., 0.],
               [0., 1., 1., 0., 0.],
               [0., 0., 0., 0., 0.],
               [0., 0., 0., 0., 0.]],
    <BLANKLINE>
              [[0., 0., 0., 0., 0.],
               [0., 0., 0., 0., 0.],
               [0., 0., 0., 0., 0.],
               [0., 0., 0., 0., 0.],
               [0., 0., 0., 0., 0.]]]]])

Nr   r   r   r   r6   r   T)dimkeepdim)r   r@   r   rP   r7   floatall)r   sizeD0D1D2z_minz_maxrU   rW   rT   rV   zyxmcond1cond2cond3m_outs                      r.   r
   r
      s[   d EJBB!Q'N!E!Q'N!E!Q'N!E!Q'N!E!Q'N!E!Q'N!EREJJ?AREJJ?AREJJ?A D!G*ag
&1T1W:q$w+G	H!TSTVZ\`J`adAgJ%4.(QtQwZ5D>-IJAtUY[\^bLb
c	ddAgJ%4.(QtQwZ5D>-IJAtUY[_abLb
c	d eg	  EEaE&**q$*?EEEaE&**q$*?EEEaE&**q$*?EEME!E;;=r/   c                   U R                   UR                   :X  a  U R                  5       S;   d  [        SU  SU S35      eUR                   UR                   :X  a  UR                  5       S;   d  [        SU SU S35      eU R                  UR                  s=:X  a!  UR                  s=:X  a  UR                  :X  dB  O  [        SU R                   SU R                   SUR                   S	UR                   S
3	5      eU R                  UR                  s=:X  a!  UR                  s=:X  a  UR                  :X  dB  O  [        SU R                   SU R                   SUR                   S	UR                   S
3	5      e[
        R                  " SS/SS/SS/SS///U R                  U R                  S9R                  U R                  5       S:X  a  SO
[        U 5      SS5      nUSS2SS2S4==   U R                  SS5      -  ss'   USS2SS2S4==   UR                  SS5      -  ss'   USS2SS4==   US-
  -  ss'   USS2SS4==   US-
  -  ss'   USS2SS4==   US-
  -  ss'   USS2SS4==   US-
  -  ss'   U$ )a  Generate 2D bounding boxes according to the provided start coords, width and height.

Args:
    x_start: a tensor containing the x coordinates of the bounding boxes to be extracted. Shape must be a scalar
        tensor or :math:`(B,)`.
    y_start: a tensor containing the y coordinates of the bounding boxes to be extracted. Shape must be a scalar
        tensor or :math:`(B,)`.
    width: widths of the masked image. Shape must be a scalar tensor or :math:`(B,)`.
    height: heights of the masked image. Shape must be a scalar tensor or :math:`(B,)`.

Returns:
    the bounding box tensor.

Examples:
    >>> x_start = torch.tensor([0, 1])
    >>> y_start = torch.tensor([1, 0])
    >>> width = torch.tensor([5, 3])
    >>> height = torch.tensor([7, 4])
    >>> bbox_generator(x_start, y_start, width, height)
    tensor([[[0, 1],
             [4, 1],
             [4, 7],
             [0, 7]],
    <BLANKLINE>
            [[1, 0],
             [3, 0],
             [3, 3],
             [1, 3]]])

r   r   z6`x_start` and `y_start` must be a scalar or (B,). Got , r2   z3`width` and `height` must be a scalar or (B,). Got 5All tensors must be in the same dtype. Got `x_start`(), `y_start`(), `width`(), `height`().6All tensors must be in the same device. Got `x_start`(r   r6   r   Nr   r   r   )
r   rZ   r=   r8   r7   r   r?   repeatr   r   )x_starty_startrL   rM   bboxs        r.   r   r   ?  s[   B MMW]]*w{{}/FUV]U^^`ah`iijkllKK6<<'EIIK6,ARSXRYY[\b[ccdeff==GMMHU[[HFLLH }W]]O;u{{m[ghnhthtguuwy
 	
 >>W^^Lu||Lv}}L (gnn5E F||nLrC
 	
 <<1a&1a&1a&1a&9:7>>Y`YfYfgnn[[]aS\1aD 	AqMW\\"a((MAqMW\\"a((MAqMUQYMAqMUQYMAqMVaZMAqMVaZMKr/   c                   U R                   UR                   s=:X  a  UR                   :X  a  O  OU R                  5       S;   d  [        SU  SU SU S35      eUR                   UR                   s=:X  a  UR                   :X  a  O  OUR                  5       S;   d  [        SU SU SU S35      eU R                  UR                  s=:X  aC  UR                  s=:X  a2  UR                  s=:X  a!  UR                  s=:X  a  UR                  :X  d\  O  [        SU R                   SU R                   SU R                   S	UR                   S
UR                   SUR                   S35      eU R                  UR                  s=:X  aC  UR                  s=:X  a2  UR                  s=:X  a!  UR                  s=:X  a  UR                  :X  d\  O  [        SU R                   SU R                   SU R                   S	UR                   S
UR                   SUR                   S35      e[
        R                  " / SQ/ SQ/ SQ/ SQ//U R                  U R                  S9R                  [        U 5      SS5      nUSS2SS2S4==   U R                  SS5      -  ss'   USS2SS2S4==   UR                  SS5      -  ss'   USS2SS2S4==   UR                  SS5      -  ss'   USS2SS4==   U-  ss'   USS2SS4==   U-  ss'   USS2SS4==   U-  ss'   USS2SS4==   U-  ss'   UR                  5       nUSS2SS2S4==   UR                  SS9R                  SS5      -  ss'   [
        R                  " Xg/SS9nU$ )aZ  Generate 3D bounding boxes according to the provided start coords, width, height and depth.

Args:
    x_start: a tensor containing the x coordinates of the bounding boxes to be extracted. Shape must be a scalar
        tensor or :math:`(B,)`.
    y_start: a tensor containing the y coordinates of the bounding boxes to be extracted. Shape must be a scalar
        tensor or :math:`(B,)`.
    z_start: a tensor containing the z coordinates of the bounding boxes to be extracted. Shape must be a scalar
        tensor or :math:`(B,)`.
    width: widths of the masked image. Shape must be a scalar tensor or :math:`(B,)`.
    height: heights of the masked image. Shape must be a scalar tensor or :math:`(B,)`.
    depth: depths of the masked image. Shape must be a scalar tensor or :math:`(B,)`.

Returns:
    the 3d bounding box tensor :math:`(B, 8, 3)`.

Examples:
    >>> x_start = torch.tensor([0, 3])
    >>> y_start = torch.tensor([1, 4])
    >>> z_start = torch.tensor([2, 5])
    >>> width = torch.tensor([10, 40])
    >>> height = torch.tensor([20, 50])
    >>> depth = torch.tensor([30, 60])
    >>> bbox_generator3d(x_start, y_start, z_start, width, height, depth)
    tensor([[[ 0,  1,  2],
             [10,  1,  2],
             [10, 21,  2],
             [ 0, 21,  2],
             [ 0,  1, 32],
             [10,  1, 32],
             [10, 21, 32],
             [ 0, 21, 32]],
    <BLANKLINE>
            [[ 3,  4,  5],
             [43,  4,  5],
             [43, 54,  5],
             [ 3, 54,  5],
             [ 3,  4, 65],
             [43,  4, 65],
             [43, 54, 65],
             [ 3, 54, 65]]])

rm   zA`x_start`, `y_start` and `z_start` must be a scalar or (B,). Got rn   r2   z<`width`, `height` and `depth` must be a scalar or (B,). Got ro   rp   z), `z_start`(rq   rr   z) and `depth`(rs   rt   )r   r   r   r6   r   Nr   r   r   r   rZ   r   )r   rZ   r=   r8   r7   r   r?   ru   r   r   clone	unsqueezecat)rv   rw   z_startrL   rM   depthrx   	bbox_backs           r.   r   r   ~  s#   f MMW]];gmm;QW@WOPWyXZ[bZccefmennop
 	
 KK6<<65;;6599;&;P[\a[bbdekdllnotnuuvwxx==GMMhW]]hekkhV\\h]b]h]hh$]]O=}U\UbUbTc d{{m<~^EKK=XZ\
 	

 >>W^^nw~~nnQWQ^Q^nbgbnbnn$^^,M'..9IW^WeWeVf g||nL~ell^[]_
 	
 <<
Y	9	56w~~U\UbUbfS\1a  	 	AqMW\\"a((MAqMW\\"a((MAqMW\\"a((MAqMUMAqMUMAqMVMAqMVM 

IaBh5??q?188A>>99d&A.DKr/   c                   [        U[        5      (       d  [        S[        U5       35      eUS;  a  [	        SU 35      eUc>  UR
                  SS [        R                  " SS/5      :X  d  [        R                  " SS	S
9  US:X  a  US   US   -   US'   US   US   -   US'   [        XR                  UR
                  S   SS5      5      nUR                  U5      nUb  U(       a  UR
                  SS [        R                  " SS/5      :X  d  UR                  5       n[        R                  " USSS/4   SS9S   US'   [        R                  " USS	S/4   SS9S   US'   [        R                  " USSS/4   SS9S   US'   [        R                  " USS	S/4   SS9S   US'   UnUS:X  a  US   US   -
  US'   US   US   -
  US'   U$ )a>  Apply a transformation matrix to a box or batch of boxes.

Args:
    trans_mat: The transformation matrix to be applied with a shape of :math:`(3, 3)`
        or batched as :math:`(B, 3, 3)`.
    boxes: The boxes to be transformed with a common shape of :math:`(N, 4)` or batched as :math:`(B, N, 4)`, the
        polygon shape of :math:`(B, N, 4, 2)` is also supported.
    mode: The format in which the boxes are provided. If set to 'xyxy' the boxes are assumed to be in the format
        ``xmin, ymin, xmax, ymax``. If set to 'xywh' the boxes are assumed to be in the format
        ``xmin, ymin, width, height``
    restore_coordinates: In case the boxes are flipped, adding a post processing step to restore the
        coordinates to a valid bounding box.

Returns:
    The set of transformed points in the specified mode

zMode must be a string. Got )xyxyxywhz(Mode must be one of 'xyxy', 'xywh'. Got Nr   r   r   aP  Previous behaviour produces incorrect box coordinates if a flip transformation performed on boxes.The previous wrong behaviour has been corrected and will be removed in the future versions.If you wish to keep the previous behaviour, please set `restore_coordinates=False`.Otherwise, set `restore_coordinates=True` as an acknowledgement.r   )
stacklevelr   ).r   ).r   ).r   ).r   r   r   .rz   r   )
isinstancestr	TypeErrortype
ValueErrorr   r   r   warningswarnr   r   view_asr{   minmax)	trans_matr   moderestore_coordinatestransformed_boxesrestored_boxess         r.   r   r     s   ( dC  5d4j\BCC##CD6JKK "EKK,<

Aq6@R,RO 	
 v~ff5fff5f&6y**U[[YZ^]_abBc&d)11%8#':U[[QSQTEUY^YcYcefhidjYkEk*002!&+<S1a&[+Ir!RST!Uv!&+<S1a&[+Ir!RST!Uv!&+<S1a&[+Ir!RST!Uv!&+<S1a&[+Ir!RST!Uv*v~$5f$=@QRX@Y$Y&!$5f$=@QRX@Y$Y&!r/   c                   [        U R                  5      S:w  a,  U R                  S   S:w  a  [        SU R                   S35      e[        UR                  5      S:w  a  [        SUR                   S35      eU R                  S   UR                  S   :w  a%  [        S	U R                  UR                  4 S35      eU R                  S5      u  p4pVXS-
  Xd-
  -  nUR	                  S
S9u  p/ n
U	R                  S   S:  Ga  U	S   nU
R                  U5        [        R                  " X;   X9SS    5      n[        R                  " XK   XISS    5      n[        R                  " X[   XYSS    5      n[        R                  " Xk   XiSS    5      n[        R                  " X-
  SS9n[        R                  " X-
  SS9nUU-  nUX{   XySS    -   U-
  -  n[        R                  " UU:*  5      S   nU	US-      n	U	R                  S   S:  a  GM  [        U
5      S:  a  [        R                  " U
5      $ [        R                  " U
5      $ )a  Perform non-maxima suppression (NMS) on tensor of bounding boxes according to the intersection-over-union (IoU).

Args:
    boxes: tensor containing the encoded bounding boxes with the shape :math:`(N, (x_1, y_1, x_2, y_2))`.
    scores: tensor containing the scores associated to each bounding box with shape :math:`(N,)`.
    iou_threshold: the throshold to discard the overlapping boxes.

Return:
    A tensor mask with the indices to keep from the input set of boxes and scores.

Example:
    >>> boxes = torch.tensor([
    ...     [10., 10., 20., 20.],
    ...     [15., 5., 15., 25.],
    ...     [100., 100., 200., 200.],
    ...     [100., 100., 200., 200.]])
    >>> scores = torch.tensor([0.9, 0.8, 0.7, 0.9])
    >>> nms(boxes, scores, iou_threshold=0.8)
    tensor([0, 3, 1])

r   r   r   zboxes expected as Nx4. Got: r2   r   zscores expected as N. Got: r   z+boxes and scores mus have same shape. Got: T)
descendingNg        )r   )r   r   r   unbindsortappendr   r   r   clampwherestackr?   )r   scoresiou_thresholdx1y1x2y2areas_orderkeepixx1yy1xx2yy2whinterovrindss                        r.   r   r     s   , 5;;1RA!57}AFGG
6<<A6v||nAFGG{{1~a(Fu{{TZT`T`G`Faabcdd\\"%NBBW!E{{d{+HAD
++a.1
!HAiir)}-iir)}-iir)}-iir)}-KK	s+KK	s+Aux%ab	"22U:;{{3-/03dQh ++a.1
  4y1}{{4  <<r/   )r   torch.Tensorreturnbool)r   r   r   z!tuple[torch.Tensor, torch.Tensor])r   r   r   z/tuple[torch.Tensor, torch.Tensor, torch.Tensor])r   r   rL   intrM   r   r   r   )r   r   r^   ztuple[int, int, int]r   r   )
rv   r   rw   r   rL   r   rM   r   r   r   )rv   r   rw   r   r~   r   rL   r   rM   r   r   r   r   r   )r   N)
r   r   r   r   r   r   r   zOptional[bool]r   r   )r   r   r   r   r   r\   r   r   )
__future__r   r   typingr   r   linalgr   __all__r   r   r   r   r	   r
   r   r   r   r    r/   r.   <module>r      s   $ #    $"J FD.#b( VM`<<$0<9E<O[<<~XXX X 	X
 X X Xx mq99$098;9[i99x8r/   