nms python代码_7、Python对NMS(非极大值抑制)理解

本文通过一个Python demo详细介绍了非极大值抑制(NMS)的原理和实现,涉及矩形框的面积计算、IOU计算以及NMS算法的迭代过程,通过实例展示了如何应用NMS进行目标检测框的筛选。
摘要由CSDN通过智能技术生成

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

fa3acab91fa80194107258dc694d96e7.png

e909128c2d2ac175e248e794ea17ea61.png

42a79b840ca7193d6b33a68ba5ba226b.png

# -*- 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:~$

'''

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值