torchvision.ops.nms实现NMS

NMS(非极大值抑制)用于目标检测模型中去除重复的检测框,主要步骤包括概率筛选、按概率排序和IOU计算。torchvision.ops.nms函数执行NMS操作,输入包含框坐标和概率,返回保留的框索引。在Yolov8的例子中,通过batchedNMS处理多类别检测,避免不同类别间的误删。
摘要由CSDN通过智能技术生成

nms原理:
当目标检测模型对一个目标有多个检测框时,需要滤掉多余的框,留下最接近真实目标的框。

在这里插入图片描述

步骤是这样的:
1.先把目标框初筛一波,比如设阈值为0.25, 把预测概率 < 0.25的目标框滤掉。
2.把 每个类别的 目标框 按预测概率从大到小排序。
3.每个类别的目标框 两两计算 IOU,当IOU > 阈值时,说明这两个目标框高度重合,没必要都留着,留概率较大的那个。注意这里是同类别的框计算IOU,不同类别的即使高度重合也不滤掉。

这样每个类别就滤掉了多余的框。因为已经按照预测概率从大到小排序,所以两两计算IOU时优先计算的是概率较大的框。

下面看下torchvision.ops.nms的用法,
这里假设有N个目标框。
传入参数boxes为Tensor,shape为[N,4], 每个box坐标格式是(x1,y1,x2,y2),即左上角右下角坐标。
如果你的目标框为(x,y,w,h), 需要做格式转换。
score: Tensor, shape为[N], 每个目标框检测的概率,如果是COCO,预测了80个类别的概率,就把最大的概率取出来。
iou阈值:float型,每个类别内两两目标框IOU > 这个阈值时,扔掉概率小的那个。

用它之前先用概率阈值初筛一波box, 把预测概率很低的box去掉。
需要把box的坐标转为左上角右下角坐标格式。
把box按概率从大到小排序。
提取每个box的预测概率。

torchvision.ops.nms的注释:
```python
def nms(boxes: Tensor, scores: Tensor, iou_threshold: float) -> Tensor:
    """
    Performs non-maximum suppression (NMS) on the boxes according
    to their intersection-over-union (IoU).

    NMS iteratively removes lower scoring boxes which have an
    IoU greater than iou_threshold with another (higher scoring)
    box.

    If multiple boxes have the exact same score and satisfy the IoU
    criterion with respect to a reference box, the selected box is
    not guaranteed to be the same between CPU and GPU. This is similar
    to the behavior of argsort in PyTorch when repeated values are present.

    Args:
        boxes (Tensor[N, 4])): boxes to perform NMS on. They
            are expected to be in ``(x1, y1, x2, y2)`` format with ``0 <= x1 < x2`` and
            ``0 <= y1 < y2``.
        scores (Tensor[N]): scores for each one of the boxes
        iou_threshold (float): discards all overlapping boxes with IoU > iou_threshold

    Returns:
        Tensor: int64 tensor with the indices of the elements that have been kept
        by NMS, sorted in decreasing order of scores
    """

下面以yolov8为例,说明如何用torchvision.ops.nms来计算nms, 过滤掉多余的目标框。

这里yolov8的prediction是(1,116,5460), 其中5460是anchor的数量,
116的前4个是目标框坐标(x,y,w,h), 中间80个是COCO数据集中80个类的预测概率,
后面32个是mask coeff, 分割mask用的,nms这里不用。只用到前面84个。

正常情况下每个类别都要算一次nms, 这里用了batched nms, 用了小技巧把所有类别的nms一起计算。

代码为了阅读简洁做了修改。

def non_max_suppression(
        prediction,
        conf_thres=0.25,
        iou_thres=0.45,
        classes=None,
        agnostic=False,
        multi_label=False,
        labels=(),
        max_det=300,
        nc=0,  # number of classes (optional)
        max_time_img=0.05,
        max_nms=30000,
        max_wh=7680,
):
  #prediction:(1,116,5460) 
    
    bs = prediction.shape[0]  # batch size  #这里只有一张图片,所以是1
    nc = 80  # 80个类别
    nm = 32  #最后32是mask coeff,用于目标分割的
    mi = 84  # mask start index
    #4~84是80个类别概率所在的位置,每个anchor取出最大的预测概率,用0.25的阈值过滤一波。
    #最大的都滤掉的话,说明这个anchor处没有预测到目标,得到的是boolean(1,5460), anchor数量
    xc = prediction[:, 4:mi].amax(1) > conf_thres  # candidates

    #用来保存nms结果
    output = [torch.zeros((0, 6 + nm), device=prediction.device)] * bs
    
    for xi, x in enumerate(prediction):  # image index, image inference #每个图片计算一次
        #取出刚刚用阈值滤掉一波剩下的anchor,input x是(116,5460),滤掉后剩27个anchor
        #x transpose后变为(5460,116),过滤后为(27,116)
        x = x.transpose(0, -1)[xc[xi]]  # confidence
   
        # 把前面说的box坐标,80个类别的概率和mask分开
        #分别是(27,4), (27,80), (27,32)
        box, cls, mask = x.split((4, nc, nm), 1)
        #torchvision的nms要求是(x1,y1,x2,y2)格式
        box = xywh2xyxy(box)  # center_x, center_y, width, height) to (x1, y1, x2, y2)
        
        #cls:(27,80), 取每行最大值,得到(27,1). conf是最大value, j是最大value对应的index, 也就是class id
        conf, j = cls.max(1, keepdim=True)
        
        #上次已经用conf_thres筛过一次了,这次>conf_thres应该全是true
        #cat之后是(27,38), box:(27,4),conf:(27,1),j:(27,1), mask:(27,32)
        x = torch.cat((box, conf, j.float(), mask), 1)[conf.view(-1) > conf_thres]

        # Check shape
        n = x.shape[0]  # number of boxes
        if not n:  # no boxes
            continue
        #把x的所有行按conf从大到小排序,(27,38)
        x = x[x[:, 4].argsort(descending=True)[:max_nms]]  # sort by confidence and remove excess boxes

        # Batched NMS
        #如果你不想每个类别都做一次nms,而是所有类别一起做nms
        #就需要把不同类别的目标框尽量没有重合,不至于把不同类别的IOU大的目标框滤掉
        #先用每个类别id乘一个很大的数,作为offset,把每个类别的box坐标都加上相应的offset,这是batched nms
        c = x[:, 5:6] * (0 if agnostic else max_wh)  # classes
        boxes, scores = x[:, :4] + c, x[:, 4]  # boxes (offset by class), scores
        i = torchvision.ops.nms(boxes, scores, iou_thres)  # NMS

        i = i[:max_det]  # limit detections
        
        output[xi] = x[i]  #取出NMS过滤剩下的prediction
        
    return output
  • 9
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: torchvision.ops.nms是一个非极大值抑制(non-maximum suppression)的实现,用于在目标检测任务中剔除多余的检测框。它通过比较检测框的得分(如置信度)来决定哪些检测框需要被保留,从而减少检测的冗余。 ### 回答2: torchvision.ops.nms是一个计算非极大值抑制(NMS)的PyTorch库函数,用于在目标检测任务中过滤掉重复的边界框(bounding box)。 在目标检测中,通常会先使用一种预测模型(比如Faster R-CNN、SSD、YOLO等)生成若干个bounding box,每个bounding box都是一种可能的目标。但是由于模型预测的不确定性,有时会出现重复的bounding box,这会影响检测结果的准确性。这时就需要使用NMS算法抑制掉这些重复的bounding box。 NMS算法的原理是,首先将所有bounding box按照置信度(confidence score)从高到低排序,然后从置信度最高的bounding box开始,依次遍历其余的bounding box,计算它们与当前bounding box的IoU(Intersection over Union),如果IoU大于一定阈值(比如0.5),就说明两个bounding box重叠度很高,需要将置信度低的bounding box抑制掉。最终,所有未被抑制的bounding box都可视为检测到的目标。 torchvision.ops.nms函数的输入参数包括bounding box的坐标(左上角和右下角)和置信度,以及IoU阈值和抑制的方法。它的输出是一个列表,每个元素表示一个保留的bounding box的索引。 需要注意的是,torchvision.ops.nms只是进行了简单的NMS算法,没有考虑一些更复杂的情况,比如同时检测出多个目标的情况,或者不同目标之间存在遮挡的情况。如果需要更高级的NMS算法,可以考虑使用第三方库(如Detectron2、mmdetection等)中提供的更复杂的NMS实现。 ### 回答3: torchvision.ops.nms是PyTorch图像处理库中常用的一种操作。顾名思义,“nms”即“非极大值抑制”,它用于筛选目标检测算法输出的一组边界框(bounding box),保留其中置信度最高的框,去除重合程度较高的小框,以达到优化检测结果的目的。 在目标检测中,通过使用某些算法(例如R-CNN,YOLO等)预测出一组边界框,其中每个框都有与其相关联的置信度。NMS算法就是用于过滤掉重复的框以及设计一个策略来找到最终的有效边界框。NMS算法会执行以下步骤: 1. 将所有边界框按照其得分从高到低进行排序。 2. 选择得分最高的框,将其与所有余下的框进行IoU(交并比)计算。 3. 将IoU大于某个阈值的框从列表中删除。 4. 重复执行步骤2和3,直到所有框都被检查完。 5. 最终剩余的框就是检测结果。 在PyTorch中,torchvision.ops.nms可以利用类似的方法执行NMS算法。它采用类似于Cython的实现方式,使用类似于Numpy的代码格式,实现了非常高效的NMS算法。该函数包含三个参数:boxes、scores和iou_threshold。其中boxes是一个形状为(N,4)的张量,其中N是边界框的数量,每个框都由左上和右下角坐标表示。scores是一个形状为(N,)的张量,表示每个框的得分。iou_threshold是IoU阈值,用于控制删除重叠框的数量。 因此,torchvision.ops.nms的功能是为目标检测算法提供一个高效的非极大值抑制实现,它可以对检测到的物体边界框进行排名和筛选,以输出最优的结果。它的使用可以减少模型检测时间,提高检测精度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝羽飞鸟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值