NMS算法-pytorch版本

        NMS存在一个非常简约的实现方法,算法输入包含了所有预测框的 得分、左上点坐标、右下点坐标一共5个预测量,以及一个设定的IoU阈 值。具体流程如下:
(1)按照得分,对所有边框进行降序排列,记录下排列的索引 order,并新建一个列表keep,作为最终筛选后的边框索引结果。
(2)将排序后的第一个边框置为当前边框,并将其保留到keep 中,再求当前边框与剩余所有框的IoU。
(3)在order中,仅仅保留IoU小于设定阈值的索引,重复第(2) 步,直到order中仅仅剩余一个边框,则将其保留到keep中,退出循环, NMS结束。
利用PyTorch,可以很方便地实现NMS模块。具体代码如下: 

def nms(self, bboxes, scores, thresh=0.5):      
    x1 = bboxes[:,0]      
    y1 = bboxes[:,1]      
    x2 = bboxes[:,2]      
    y2 = bboxes[:,3]      
    # 计算每个box的面积      
    areas = (x2-x1+1)*(y2-y1+1)       
    # 对得分进行降序排列,order为降序排列的索引      
    _, order = scores.sort(0, descending=True)      
    # keep保留了NMS留下的边框box      
    keep = []      
    while order.numel() > 0:            
        if order.numel() == 1:              # 保留框只剩一个                   
            i = order.item()                   
            keep.append(i)                   
            break        
    else:            
        i = order[0].item()                  # 保留scores最大的那个框box[i]
        keep.append(i)        
    # 巧妙利用tensor.clamp函数求取每一个框与当前框的最大值和最小值        
    xx1 = x1[order[1:]].clamp(min=x1[i])        
    yy1 = y1[order[1:]].clamp(min=y1[i])        
    xx2 = x2[order[1:]].clamp(max=x2[i])        
    yy2 = y2[order[1:]].clamp(max=y2[i])        
    # 求取每一个框与当前框的重合部分面积        
    inter = (xx2-xx1).clamp(min=0) * (yy2-yy1).clamp(min=0)        
    # 计算每一个框与当前框的IoU        
    iou = inter / (areas[i]+areas[order[1:]]-inter)        
    # 保留IoU小于阈值的边框索引        
    idx = (iou <= threshold).nonzero().squeeze()        
    if idx.numel() == 0:                
            break        
    # 这里的+1是为了补充idx与order之间的索引差        
    order = order[idx+1]    
# 返回保留下的所有边框的索引值,类型为torch.LongTensor    
return torch.LongTensor(keep)

 

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Evan Yi

老板行行好,打赏一下吧~

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

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

打赏作者

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

抵扣说明:

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

余额充值