
    khU              	           d Z ddlZddlmZ dej                  fdZ	 	 	 	 ddededed	efd
Z	 	 	 	 ddededed	efdZ	y)z PyTorch Soft-NMS

This code was adapted from a PR for detectron2 submitted by https://github.com/alekseynp
https://github.com/facebookresearch/detectron2/pull/1183/files

Detectron2 is licensed Apache 2.0, Copyright Facebook Inc.
    N)Listreturnc           	      8   | dddf   | dddf   z
  | dddf   | dddf   z
  z  }|dddf   |dddf   z
  |dddf   |dddf   z
  z  }t        j                  | dddddf   |ddddf         t        j                  | dddddf   |ddddf         z
  }|j                  d       |j	                  d      }t        j
                  |dkD  ||dddf   |z   |z
  z  t        j                  d|j                  |j                              }|S )	aH  
    Given two lists of boxes of size N and M,
    compute the IoU (intersection over union)
    between __all__ N x M pairs of boxes.
    The box order must be (xmin, ymin, xmax, ymax).
    Args:
        boxes1,boxes2 (Boxes): two `Boxes`. Contains N & M boxes, respectively.
    Returns:
        Tensor: IoU, sized [N,M].
    N   r         )min)dimdtypedevice)	torchr	   maxclamp_prodwherezerosr   r   )boxes1boxes2area1area2width_heightinterious          K/var/www/teggl/fontify/venv/lib/python3.12/site-packages/effdet/soft_nms.pypairwise_iour      s:    AqD\F1a4L(VAqD\F1a4L-HIEAqD\F1a4L(VAqD\F1a4L-HIE99VAtQRK0&AB-@599q${VArrE]D L A!$E ++	q$w%'%/0AU[[>C
 J    method_gaussiansigmaiou_thresholdscore_thresholdc                 R   | j                   }| j                         }|j                         }|j                         d   }	t        j                  |	      }
t        j
                  |	t        j                  |      }t        j
                  |	t        j                  |      }d}|j                         dkD  rt        j                  |      }|
|   ||<   ||   ||<   |dz  }||   }t        |j                  d      |      d   }|r.t        j                  t        j                  |d       |z        }n%t        j                  |      }||kD  }d||   z
  ||<   ||z  }||kD  }t        j                  d|      ||<   ||   }||   }|
|   }
|j                         dkD  r|d| |d| fS )a  
    Soft non-max suppression algorithm.

    Implementation of [Soft-NMS -- Improving Object Detection With One Line of Codec]
    (https://arxiv.org/abs/1704.04503)

    Args:
        boxes_remain (Tensor[N, ?]):
           boxes where NMS will be performed
           if Boxes, in (x1, y1, x2, y2) format
           if RotatedBoxes, in (x_ctr, y_ctr, width, height, angle_degrees) format
        scores_remain (Tensor[N]):
           scores for each one of the boxes
        method_gaussian (bool): use gaussian method if True, otherwise linear        
        sigma (float):
           parameter for Gaussian penalty function
        iou_threshold (float):
           iou threshold for applying linear decay. Nt from the paper
           re-used as threshold for standard "hard" nms
        score_threshold (float):
           boxes with scores below this threshold are pruned at each iteration.
           Dramatically reduces computation time. Authors use values in [10e-4, 10e-2]

    Returns:
        tuple(Tensor, Tensor):
            [0]: int64 tensor with the indices of the elements that have been kept
            by Soft NMS, sorted in decreasing order of scores
            [1]: float tensor with the re-scored scores of the elements that were kept
    r   r   r   r   F)r   N)r   clonesizer   aranger   int64float32numelargmaxr   	unsqueezeexppow	ones_liketensor)boxesscoresr   r   r    r!   r   boxes_remainscores_remainnum_elemidxsidxs_out
scores_outcounttop_idxtop_boxiousdecay
decay_maskkeeps                       r   soft_nmsr>   *   s   J \\F;;=LLLNM!!#A&H<<!D{{85;;vFHXU]]6JJE



!
#,,}-w-)'2
5
w'G--a0,?BIIuyyq11E9:EOOD)E-J !D$4 4E*.U6:W#D)%d+Dz- 


!
#0 FUZ///r   c                 p   | j                         dk(  r`t        j                  dt        j                  | j                        t        j                  dt        j
                  |j                        fS | j                         }|j                  |       |dz   z  }| |dddf   z   }	t        |	|||||      S )a  
    Performs soft non-maximum suppression in a batched fashion.

    Each index value correspond to a category, and NMS
    will not be applied between elements of different categories.

    Args:
        boxes (Tensor[N, 4]):
           boxes where NMS will be performed. They
           are expected to be in (x1, y1, x2, y2) format
        scores (Tensor[N]):
           scores for each one of the boxes
        idxs (Tensor[N]):
           indices of the categories for each one of the boxes.
        method (str):
           one of ['gaussian', 'linear', 'hard']
           see paper for details. users encouraged not to use "hard", as this is the
           same nms available elsewhere in detectron2
        sigma (float):
           parameter for Gaussian penalty function
        iou_threshold (float):
           iou threshold for applying linear decay. Nt from the paper
           re-used as threshold for standard "hard" nms
        score_threshold (float):
           boxes with scores below this threshold are pruned at each iteration.
           Dramatically reduces computation time. Authors use values in [10e-4, 10e-2]
    Returns:
        tuple(Tensor, Tensor):
            [0]: int64 tensor with the indices of the elements that have been kept
            by Soft NMS, sorted in decreasing order of scores
            [1]: float tensor with the re-scored scores of the elements that were kept
    r   )r   r   r   N)r   r   r    r!   )	r(   r   emptyr&   r   r'   r   tor>   )
r/   r0   r4   r   r   r    r!   max_coordinateoffsetsboxes_for_nmss
             r   batched_soft_nmsrE   s   s    N {{}KKEKKEKKEMM&--H
 	
 YY[Nggen 23GGAtG,,Mve#_ r   )T      ?rF   g{Gzt?)TrF   rF   gMbP?)
__doc__r   typingr   Tensorr   boolfloatr>   rE    r   r   <module>rM      s     ELL B !"F0 F0 	F0
 F0 F0V !"66 6 	6
 6r   