今天跟大家伙儿唠唠我最近搞的NMS,也就是非极大值抑制,这玩意儿在目标检测里头那是相当重要。
事情是这么开始的,前段时间我在搞一个目标检测的项目,模型跑出来效果还行,就是框框太多,一个目标能给你框出一堆,看着就烦。咋办?就得用NMS来收拾收拾这些框框。
我啥也不懂,就直接上网搜,看别人咋搞的。 发现NMS的核心思想就是把那些重叠度太高的框框给干掉,只留下置信度最高的那个。简单来说,就是优中选优,把最靠谱的框框留下来。
然后就开始动手。第一步,先把所有的框框按照置信度从高到低排个队。 就像选美一样,先看看谁最漂亮。用Python写个简单的排序函数,搞定!
第二步,从置信度最高的框框开始,逐个遍历。 每次拿出一个框框,就跟剩下的框框算一下重叠度,也就是IoU(Intersection over Union)。这玩意儿就是算两个框框的交集面积除以并集面积,值越大说明重叠得越厉害。
第三步,如果IoU大于某个设定的阈值,那就把这个框框给干掉。 比如我设个阈值是0.5,意思是如果两个框框重叠度超过50%,那就认为它们框的是同一个目标,直接把置信度低的那个框框扔掉。
- 算IoU的时候,我一开始写个很笨的函数,效率贼低。 后来优化一下,用NumPy的广播机制,速度立马就上去。
- 阈值的选择也很重要。 太大,容易把一些靠谱的框框也给干掉;太小,又起不到抑制的效果。我试好几个值,选个0.5感觉还不错。
第四步,重复第二步和第三步,直到所有的框框都遍历完。 这样一轮下来,剩下的框框就是经过NMS处理后的结果,数量少很多,也更加准确。
刚开始跑的时候,发现效果不太有些目标还是会被框出好几个。后来仔细检查一下代码,发现是有些细节没处理 比如,在干掉框框的时候,没注意更新索引,导致后面的计算出错。
改这些bug之后,NMS的效果就好多。目标检测的结果一下子就清爽很多,看着也舒服多。 虽然代码写得比较粗糙,但是能用就行。
这回实践让我对NMS有更深的理解。理论看再多,不如自己动手实践一遍。 只有真正去写代码,才能发现那些隐藏的坑,才能真正掌握这个算法。
以后有机会,我还想尝试一些更高级的NMS算法,比如Soft-NMS,看看能不能进一步提升目标检测的效果。
还没有评论,来说两句吧...