ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

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

2019-08-01 18:41:03  阅读:308  来源: 互联网

标签:NMS Python x2 y1 极大值 np dets y2 order


问题描述:最近再看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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有