非极大值抑制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
完结撒花 🎉🎉🎉🎉