Python實現非極大值抑制演算法(NMS)

2021-10-07 17:18:43 字數 4479 閱讀 7388

import cv2

import numpy as np

defnms

(bounding_boxes, confidence_score, threshold)

:'''

:param bounding_boxes: 候選框列表,[左上角座標, 右下角座標], [min_x, min_y, max_x, max_y], 原點在影象左上角

:param confidence_score: 候選框置信度

:param threshold: iou閾值

:return: 抑制後的bbox和置信度

'''# 如果沒有bbox,則返回空列表

iflen

(bounding_boxes)==0

:return

,# bbox轉為numpy格式方便計算

boxes = np.array(bounding_boxes)

# 分別取出bbox的座標

start_x = boxes[:,

0]start_y = boxes[:,

1]end_x = boxes[:,

2]end_y = boxes[:,

3]# 置信度轉為numpy格式方便計算

score = np.array(confidence_score)

# [0.9 0.75 0.8 0.85]

# 篩選後的bbox和置信度

picked_boxes =

picked_score =

# 計算每乙個框的面積

areas =

(end_x - start_x +1)

*(end_y - start_y +1)

# 將score中的元素從小到大排列,提取其對應的index(索引),然後輸出到order

order = np.argsort(score)

# [1 2 3 0]

# iterate bounding boxes

while order.size >0:

# the index of largest confidence score

# 取出最大置信度的索引

index = order[-1

]# pick the bounding box with largest confidence score

# 將最大置信度和最大置信度對應的框新增進篩選列表裡))

# 求置信度最大的框與其他所有框相交的長寬,為下面計算相交面積做準備

# 令左上角為原點,

# 兩個框的左上角座標x取大值,右下角座標x取小值,小值-大值+1==相交區域的長度

# 兩個框的左上角座標y取大值,右下角座標y取小值,小值-大值+1==相交區域的高度

# 這裡可以在草稿紙上畫個圖,清晰明了

x1 = np.maximum(start_x[index]

, start_x[order[:-

1]])

x2 = np.minimum(end_x[index]

, end_x[order[:-

1]])

y1 = np.maximum(start_y[index]

, start_y[order[:-

1]])

y2 = np.minimum(end_y[index]

, end_y[order[:-

1]])

# 計算相交面積,當兩個框不相交時,w和h必有乙個為0,面積也為0

w = np.maximum(

0.0, x2 - x1 +1)

h = np.maximum(

0.0, y2 - y1 +1)

intersection = w * h

# 計算iou

ratio = intersection /

(areas[index]

+ areas[order[:-

1]]- intersection)

# 保留小於閾值的框的索引

left = np.where(ratio < threshold)

# 根據該索引修正order中的索引(order裡放的是按置信度從小到大排列的索引)

order = order[left]

return picked_boxes, picked_score

# 影象路徑

# 自己設定候選框

bounding_boxes =[(

210,

180,

337,

380),(

180,

120,

330,

340),(

270,

160,

350,

360),(

220,

210,

345,

410)

]confidence_score =

[0.9

,0.75

,0.8

,0.85

]# 讀取影象

image = cv2.imread(image_name)

# 複製乙份原圖矩陣

org = image.copy(

)# 畫框引數

font = cv2.font_hershey_******x

font_scale =

1thickness =

2# iou閾值設定

threshold =

0.4# 畫框(未執行nms)

for(start_x, start_y, end_x, end_y)

, confidence in

zip(bounding_boxes, confidence_score)

:(w, h)

, baseline = cv2.gettextsize(

str(confidence)

, font, font_scale, thickness)

cv2.rectangle(org,

(start_x, start_y -(2

* baseline +5)

),(start_x + w, start_y),(

0,255,

255),-

1)cv2.rectangle(org,

(start_x, start_y)

,(end_x, end_y),(

0,255,

255),2

) cv2.puttext(org,

str(confidence)

,(start_x, start_y)

, font, font_scale,(0

,0,0

), thickness)

# 執行nms演算法

picked_boxes, picked_score = nms(bounding_boxes, confidence_score, threshold)

# 畫框(執行了nms後)

for(start_x, start_y, end_x, end_y)

, confidence in

zip(picked_boxes, picked_score)

:(w, h)

, baseline = cv2.gettextsize(

str(confidence)

, font, font_scale, thickness)

cv2.rectangle(image,

(start_x, start_y -(2

* baseline +5)

),(start_x + w, start_y),(

0,255,

255),-

1)cv2.rectangle(image,

(start_x, start_y)

,(end_x, end_y),(

0,255,

255),2

) cv2.puttext(image,

str(confidence)

,(start_x, start_y)

, font, font_scale,(0

,0,0

), thickness)

# 展示影象

非極大值抑制

nms non maximum suppression 中文名非極大值抑制,在很多計算機視覺任務中都有廣泛應用,如 邊緣檢測 目標檢測等。這裡主要以人臉檢測中的應用為例,來說明nms,並給出matlab和c 示例程式。人臉檢測的一些概念 1 絕大部分人臉檢測器的核心是分類器,即給定乙個尺寸固定,分類...

非極大值抑制

參考 思想 1.將每乙個檢測框的得分值排序,得到得分值最大的檢測框,將該檢測框記錄下來 2.然後其他計算所有的檢測框與該框的iou,將iou大於閾值的檢測框去除,iou小於閾值的認為是不同的目標,則保留 3.對剩下的檢測框繼續做上述的處理 import numpy as np def py cpu ...

非極大值抑制

在進行目標檢測的時候,當多個方框都 到同乙個目標的時候,我們需要去除iou小的方框,原始碼如下 def nms boxes,threshold,method union param boxes n,9 x1,y1,x2,y2,score,offset x1,offset y1,offset x2,o...