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