编程语言
首页 > 编程语言> > 7、Python对NMS(非极大值抑制)理解

7、Python对NMS(非极大值抑制)理解

作者:互联网

问题描述:最近再看tensorflow检测的源代码,用了NMS(非极大值抑制)的使用,所以写一个demo记录一下;

 

 

# -*- coding: UTF-8 -*-
import numpy as np
import cv2
import numpy as np
 
def py_nms(dets, scores,thresh):
    """Pure Python NMS baseline."""
    #x1、y1、x2、y2、以及score赋值
    x1 = dets[:, 0]
    y1 = dets[:, 1]
    x2 = dets[:, 2]
    y2 = dets[:, 3]
    #scores = dets[:, 4]
    #列向量x1 x2 y1 y2
    #每一个候选框的面积
    areas = (x2 - x1 + 1) * (y2 - y1 + 1)
    print (areas)
    #4组坐标点围成的面积
    #order是按照score降序排序的
    order = scores.argsort()[::-1]
    #argsort函数返回的是数组值从小到大的索引值
    print ("order=",order)
    keep = []
    while order.size > 0:
        print ("---------------------")
        i = order[0]
        keep.append(i)
        #计算当前概率最大矩形框与其他矩形框的相交框的坐标,会用到numpy的broadcast机制,得到的是向量
        xx1 = np.maximum(x1[i], x1[order[1:]])
        yy1 = np.maximum(y1[i], y1[order[1:]])
        xx2 = np.minimum(x2[i], x2[order[1:]])
        yy2 = np.minimum(y2[i], y2[order[1:]])
 
        #计算相交框的面积,注意矩形框不相交时w或h算出来会是负数,用0代替
        w = np.maximum(0.0, xx2 - xx1 + 1)
        h = np.maximum(0.0, yy2 - yy1 + 1)
        inter = w * h
        #计算重叠度IOU:重叠面积/(面积1+面积2-重叠面积)
        ovr = inter / (areas[i] + areas[order[1:]] - inter)
        print ("over=",ovr)
        #找到重叠度不高于阈值的矩形框索引
        inds = np.where(ovr <= thresh)[0]
        print ("inds=",inds)
        #将order序列更新,由于前面得到的矩形框索引要比矩形框在原order序列中的索引小1,所以要把这个1加回来
        order = order[inds + 1]
        print ("update order=",order)
    return keep
'''
非极大值抑制的方法是:先假设有6个矩形框,根据分类器的类别分类概率做排序,假设从小到大属于车辆的概率 分别为A、B、C、D、E、F。

(1)从最大概率矩形框F开始,分别判断A~E与F的重叠度IOU是否大于某个设定的阈值;

(2)假设B、D与F的重叠度超过阈值,那么就扔掉B、D;并标记第一个矩形框F,是我们保留下来的。

(3)从剩下的矩形框A、C、E中,选择概率最大的E,然后判断E与A、C的重叠度,重叠度大于一定的阈值,那么就扔掉;并标记E是我们保留下来的第二个矩形框。

就这样一直重复,找到所有被保留下来的矩形框。
摘自--(明也无涯)-解释
''' 
# test
img =cv2.imread("1.jpg")

pts = np.array([[255, 36],[418, 36], [418, 196],[255, 196],  #四维坐标
               [259, 21], [411,21],[411, 203],[259,203],
               [267, 8],[408, 8],[408,184],[267,184],
               [279,47],[404,47],[404,190],[279,190]]) # 
cv2.polylines(img, [pts], True, (255, 255, 0), 2)
cv2.imwrite('original.jpg', img)

mylist = []
for arr in range(0,len(pts),2):
    for i in range(0,2):
        mylist.append(pts[arr][i])

dets=np.array(mylist).reshape(4,4)   #转化成通过两个点描述的位置左边(类似labelme坐标形式)

score=np.array([0.54,0.62,0.66,0.5])
thresh = 0.7 # 暂且不考虑出现多个比对框结果;只留唯一
keep_dets = py_nms(dets,score, thresh)
print (keep_dets)
print(dets[keep_dets])

ohlist = []
for arr in range(0,len(pts)):
    for i in range(0,2):
        ohlist.append(pts[arr][i])
print (ohlist)
pt=np.array(ohlist)
print (pt)
img =cv2.imread("1.jpg")
for item in range(0,len(keep_dets)):
      print (np.array(pt[keep_dets[item]*8:keep_dets[item]*8+8]).reshape(4,2))
      cv2.polylines(img, [np.array(pt[keep_dets[item]*8:keep_dets[item]*8+8]).reshape(4,2)], True, (255, 255, 255), 2)
      cv2.imwrite('nms_original.jpg', img)

cv2.waitKey(0)
cv2.destroyAllWindows()


'''
ubuntu@ubuntu:~$ python a.py 
[26404 27999 25134 18144]
order= [2 1 0 3]
---------------------
over= [ 0.78029821  0.69644503  0.67161066]
inds= [1 2]
update order= [0 3]
---------------------
over= [ 0.68716861]
inds= [0]
update order= [3]
---------------------
over= []
inds= []
update order= []
[2, 0, 3]
[[267   8 408 184]
 [255  36 418 196]
 [279  47 404 190]]
[255, 36, 418, 36, 418, 196, 255, 196, 259, 21, 411, 21, 411, 203, 259, 203, 267, 8, 408, 8, 408, 184, 267, 184, 279, 47, 404, 47, 404, 190, 279, 190]
[255  36 418  36 418 196 255 196 259  21 411  21 411 203 259 203 267   8
 408   8 408 184 267 184 279  47 404  47 404 190 279 190]
[[267   8]
 [408   8]
 [408 184]
 [267 184]]
[[255  36]
 [418  36]
 [418 196]
 [255 196]]
[[279  47]
 [404  47]
 [404 190]
 [279 190]]
ubuntu@ubuntu:~$ 


'''

 

 

标签:NMS,Python,x2,y1,极大值,np,dets,y2,order
来源: https://blog.csdn.net/sxj731533730/article/details/98086149