非极大值抑制non-maximum suppression
简称NMS。。。
故事背景
在object detection中,任务一般有两个方面:
- 首先要找到物体的大概位置(如图所示的框框,bounding box,简写为bbox)
- 然后分析这框框里是个啥物体(分类 class)
但是实际上我们可能找到好些框框,其实圈住的大概是同一个物体,这样的情况下其实保留一个最好的框框就够了。
算法
理念很简单呐,以左边的一只狗为例
- 首先呢,蓝色框框和橘色框框的重叠区域过大,证明他们其实很可能指的是同一只狗
- 那么就选出最有可能是这只狗的框的bbox。其余的统统丢弃。
那么问题来了:
- 重叠区域怎么算?专业术语交并比,Intersection over Union(简称IoU),顾名思义,就是两个框框的交集面积比两个框框的并集。
实现
先实现个IoU
def IoU(a, b):
"""求两个矩形a和b的交并比
Args:
a (2*2 matrix): 矩形a,两行两列,一个是左上角的点,一个是右下角的点
b (2*2 matrix): 矩形a,两行两列,一个是左上角的点,一个是右下角的点
Returns:
flost: 交集面积比并集面积
"""
x_a1 = min(a[:][0])
x_a2 = max(a[:][0])
y_a1 = min(a[:][1])
y_a2 = min(a[:][1])
x_b1 = min(b[:][0])
x_b2 = max(b[:][0])
y_b1 = min(b[:][1])
y_b2 = min(b[:][1])
inter = (x_a2 - x_b1) * (y_a2 - y_b1) # 交集面积
union = (x_a2 - x_a1) * (y_a2-y_a1) + (x_b2 - x_b1) * \
(y_b2-y_b1) - (x_a2 - x_b1) * (y_a2 - y_b1) # 并集面积
return inter / union
再实现个NMS
def NMS(rectangles, threshold, gt):
"""非极大值抑制的python实现
Args:
rectangles (tuple): 三元组,前两个元素是矩形两个顶点,第三个元素是类别sco
threshold ([type]): [description]
gt (list)): 真实值,矩形
Returns:
tuple: 返回最佳的长方形
"""
rectangles_sorted = sorted(
rectangles, key=lambda x: x[2], reverse=True) # 按照那个类别分数先排个序,分高的排在前面
for rec in rectangles_sorted:
if IoU(rec, gt) >= threshold:
return rec
return None完结撒花 🎉🎉🎉🎉

