记录之目标检测NMS(非极大值抑制)
NMS
·
NMS思想:
1.首先将所有框按置信度排序,选择置信度最大的框,记作 S
2.剩余框与 S 做IOU计算,大于设定阈值 threshold (常设0.7)的则进行抑制,最基本的抑制手段是将这些框的置信度置0。
3.在剩余的框中继续寻找得分最高的,重复1,2。到没有重复的框,算法停止。
pytorch实现(引用:https://blog.csdn.net/KANG157/article/details/124649838):
具体分析我在代码里给了注释
def NMS(boxes,scores, thresholds):
x1 = boxes[:,0] #左上点x
y1 = boxes[:,1] #左上点y
x2 = boxes[:,2] #右下点x
y2 = boxes[:,3] #右下点y
areas = (x2-x1)*(y2-y1) # 计算每一个框的面积,存在aeras里
_,order = scores.sort(0,descending=True) # 给所有框的得分降序排列,返回order索引
keep = []
while order.numel() > 0: # 当order元素数目不为0
i = order[0] # 取得分最高的索引赋给i,记该框为S
keep.append(i) # 添加入keep集
if order.numel() == 1: # 如果只有一个框,则算法结束
break
xx1 = x1[order[1:]].clamp(min=x1[i]) # 通过clamp函数,选取其余框与S交集的左上点x值
yy1 = y1[order[1:]].clamp(min=y1[i]) # 通过clamp函数,选取其余框与S交集的左上点y值
xx2 = x2[order[1:]].clamp(max=x2[i]) # 通过clamp函数,选取其余框与S交集的右下点x值
yy2 = y2[order[1:]].clamp(max=y2[i]) # 通过clamp函数,选取其余框与S交集的左上点x值
w = (xx2-xx1).clamp(min=0) #将交集的width负值情况限制到0,目的是没有交集的框,交集部分设为0
h = (yy2-yy1).clamp(min=0) #将交集的height负值情况限制到0,同上
inter = w*h # 计算交集面积
ovr = inter/(areas[i] + areas[order[1:]] - inter) #计算iou
ids = (ovr<=thresholds).nonzero().squeeze() #获取所有iou值小于阈值的框的索引
if ids.numel() == 0: #当不存在和当前框的iou值小于阈值的框时,代码结束
break
order = order[ids+1] #注意这里的加1,因为ids计算时是除了第一个框的,做一在恢复到order时要后退1个,故加上1
return torch.LongTensor(keep)
函数解析:
torch.sort(input, dim=0, descending=False)
dim:排序维度
descending:是否降序
return:1.排好序的数组
2.对应的索引
torch.clamp(input, min=a, max=b)
usage:将input数据限制在[a,b]闭区间内
原理:
input[i] = a, if input[i] <= a
= input[i] if input[i] > a and input[i] < b
= b if input[i] >= b
torch.nonzero(input)
return: input中所有非0元素的索引
更多推荐
所有评论(0)