使用NMS演算法去除目標中存在包含關係的矩形框

2021-10-11 22:01:13 字數 4641 閱讀 7819

nms演算法(非極大值抑制演算法)的主要作用是通過搜尋區域性極大值的思想來實現,主要的實現步驟可以分為以下幾個步驟:

1、設定目標框的置信度閾值,常用的閾值為0.5左右。

2、根據置信度排序排列候選框列表。

3、選取置信度最高的框a新增到輸出列表,並將其從候選框的列表中刪除。

4、計算a與候選框列表中的所有框的iou值,刪除大於閾值的候選框。

5、重複上述過程,直到候選框的列表為空,返回輸出列表。

其中計算iou值的公式為:

nms演算法的**為:

#coding:utf-8

import numpy as np

def py_cpu_nms(dets, thresh):

"""pure python nms baseline."""

x1 = dets[:, 0]

y1 = dets[:, 1]

x2 = dets[:, 2]

y2 = dets[:, 3]

scores = dets[:, 4]

areas = (x2 - x1 + 1) * (y2 - y1 + 1)

#從大到小排列,取index

order = scores.argsort()[::-1]

#keep為最後保留的邊框

keep =

while order.size > 0:

#order[0]是當前分數最大的視窗,之前沒有被過濾掉,肯定是要保留的

i = order[0]

#計算視窗i與其他所以視窗的交疊部分的面積

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 = np.maximum(0.0, xx2 - xx1 + 1)

h = np.maximum(0.0, yy2 - yy1 + 1)

inter = w * h

#交/並得到iou值

ovr = inter / (areas[i] + areas[order[1:]] - inter)

#ind為所有與視窗i的iou值小於threshold值的視窗的index,其他視窗此次都被視窗i吸收

inds = np.where(ovr <= thresh)[0]

#下一次計算前要把視窗i去除,所有i對應的在order裡的位置是0,所以剩下的加1

order = order[inds + 1]

return keep

nms演算法的輸入資料應當為:

boxes=np.array([[100,100,210,210,0.72],

[250,250,420,420,0.8],

[220,220,320,330,0.92],

[100,100,210,210,0.72],

[230,240,325,330,0.81],

[220,230,315,340,0.9]])

資料中包括的位置資訊為極座標點,

[ x1, y1, x2, y2, thread ] = [ xmin, ymax, xmax, ymax , confidence]
nms演算法實現的效果為:

nms演算法的效果是將資料中的重疊部分的閾值低的進行過濾。

import numpy as np

def nms(bboxes):

"""非極大抑制過程

:param bboxes: 同類別候選框座標

:param confidence: 同類別候選框分數

:param threshold: iou閾值

:return:

"""# 1、傳入無候選框返回空

if len(bboxes) == 0:

return ,

# 強轉陣列

bboxes = np.array(bboxes)

# 從x,y,w,h四個值轉換為左上角頂點和右下角頂點

center_x = bboxes[:, 0]

center_y = bboxes[:, 1]

w = bboxes[:, 2]

h = bboxes[:, 3]

# 取出n個的極座標點

x1 = np.maximum(0.0, center_x - (w / 2))

y1 = np.maximum(0.0, center_y - (h / 2))

x2 = np.maximum(0.0, center_x + (w / 2))

y2 = np.maximum(0.0, center_y + (h / 2))

# 2、對候選框進行nms篩選

# 返回的框座標和分數

picked_boxes =

# 對置信度進行排序, 獲取排序後的下標序號, argsort預設從小到大排序

order = np.argsort(np.ones(len(bboxes)))

areas = (x2 - x1) * (y2 - y1)

while order.size > 0:

# 將當前置信度最大的框加入返回值列表中

index = order[-1]

# 獲取當前置信度最大的候選框與其他任意候選框的相交面積

x11 = np.maximum(x1[index], x1[order[:-1]])

y11 = np.maximum(y1[index], y1[order[:-1]])

x22 = np.minimum(x2[index], x2[order[:-1]])

y22 = np.minimum(y2[index], y2[order[:-1]])

# 計算當前矩形框與其餘框的比值

rate = areas[index] / areas[order[:-1]]

# 計算其餘框于u當前框的比值

rate1 = areas[order[:-1]] / areas[index]

w = np.maximum(0.0, x22 - x11)

h = np.maximum(0.0, y22 - y11)

intersection = w * h

# 利用相交的面積和兩個框自身的面積計算框的交並比, 保留大於閾值的框

ratio = intersection / (areas[index] + areas[order[:-1]] - intersection)

# rate==ratio表示包含關係,保留不為包含關係的框

keep_boxes_indics = np.where(ratio != rate)

keep_boxes_indics1 = np.where(ratio != rate1)

if keep_boxes_indics.__len__() < keep_boxes_indics1.__len__():

order = order[keep_boxes_indics]

else:

order = order[keep_boxes_indics1]

return picked_boxes

if __name__ == '__main__':

bounding = [(267.5509948730469, 291.084228515625, 11.240452766418457, 13.544210433959961), (150, 67, 15, 14), (246, 121, 11, 25), (189, 85, 14, 23)]

picked_boxes = nms(bounding)

print('最終bbox列表:', picked_boxes)

輸出為:

最終bbox列表: [array([189.,  85.,  14.,  23.]), array([246., 121.,  11.,  25.]), array([150.,  67.,  15.,  14.]), array([267.55099487, 291.08422852,  11.24045277,  13.54421043])]
其中輸入的資料為:

[ x, y, w, h ] = [中心點x值,中心點y值, 寬, 高 ]
實現的效果為:

演算法 去除英文文字中重複單詞

假設有一段英文文字,其中有重複的單詞,要求去除重複單詞,只保留乙個,例如 hello world hello python 程式輸出為 hello world python 1 首先我們得把這段文字中的每個單詞提取出來 2 提取出每個單詞後,我們只需遍歷這個列表,然後再判斷這個單詞是否存在這個空列表...

多目標跟蹤中SORT演算法的理解

多目標跟蹤中sort演算法的理解 在跟蹤之前,對所有目標已經完成檢測,實現了特徵建模過程。1.第一幀進來時,以檢測到的目標初始化並建立新的 標註id。2.後面幀進來時,先到卡爾曼濾波器中得到由前面幀box產生的狀態 和協方差 求 所有目標狀態 與本幀檢測的box的iou,通過匈牙利指派演算法得到io...

目標檢測中的RPN區域提取演算法

用已知尺寸的視窗遍歷整個影象,生成很多子影象,漫無目的的搜尋。selective search在rcnn和fast rcnn中用到,它的具體做法是將影象分割成很多小的區域,計算區域之間的相似度 顏色 紋理等等 結合各尺度結果,進行融合,形成大一些的region。具體參見 本文主要講解的是region...