(转)非极大抑制(Non-Maximum Suppression)
轉載自非極大抑制(Non-Maximum Suppression)。
參考文章:
1. Non-Maximum Suppression for Object Detection in Python
2. NMS非極大值抑制
最近在做人臉識別的項目,其中在人臉檢測算法中MTCNN算法是用到了NMS算法來篩選候選的人臉區(qū)域得到最佳的人臉位置。
這個算法其實應用非常廣泛,在比較流行的檢測算法中都有使用,包括RCNN、SPP-Net中,因為它主要作用就是在一堆候選區(qū)域找到最好最佳的區(qū)域。
大概原理如下:
假設從一個圖像中得到了2000region proposals,通過在RCNN和SPP-net之后我們會得到2000*4096的一個特征矩陣,然后通過N的SVM來判斷每一個region屬于N的類的scores。其中,SVM的權重矩陣大小為4096*N,最后得到2000*N的一個score矩陣(其中,N為類別的數(shù)量)。
Non-Maximum Suppression就是需要根據(jù)score矩陣和region的坐標信息,從中找到置信度比較高的bounding box。首先,NMS計算出每一個bounding box的面積,然后根據(jù)score進行排序,把score最大的bounding box作為隊列中。接下來,計算其余bounding box與當前最大score與box的IoU,去除IoU大于設定的閾值的bounding box。然后重復上面的過程,直至候選bounding box為空。最終,檢測了bounding box的過程中有兩個閾值,一個就是IoU,另一個是在過程之后,從候選的bounding box中剔除score小于閾值的bounding box。需要注意的是:Non-Maximum Suppression一次處理一個類別,如果有N個類別,Non-Maximum Suppression就需要執(zhí)行N次。
python實現(xiàn)代碼如下(參考自Non-Maximum Suppression for Object Detection in Python):
# import the necessary packages import numpy as np import cv2# Felzenszwalb et al. def non_max_suppression_slow(boxes, overlapThresh):# if there are no boxes, return an empty listif len(boxes) == 0:return []# initialize the list of picked indexespick = []# grab the coordinates of the bounding boxesx1 = boxes[:,0]y1 = boxes[:,1]x2 = boxes[:,2]y2 = boxes[:,3]# compute the area of the bounding boxes and sort the bounding# boxes by the bottom-right y-coordinate of the bounding boxarea = (x2 - x1 + 1) * (y2 - y1 + 1)idxs = np.argsort(y2)# keep looping while some indexes still remain in the indexes# listwhile len(idxs) > 0:# grab the last index in the indexes list, add the index# value to the list of picked indexes, then initialize# the suppression list (i.e. indexes that will be deleted)# using the last indexlast = len(idxs) - 1i = idxs[last]pick.append(i)suppress = [last]# loop over all indexes in the indexes listfor pos in xrange(0, last):# grab the current indexj = idxs[pos]# find the largest (x, y) coordinates for the start of# the bounding box and the smallest (x, y) coordinates# for the end of the bounding boxxx1 = max(x1[i], x1[j])yy1 = max(y1[i], y1[j])xx2 = min(x2[i], x2[j])yy2 = min(y2[i], y2[j])# compute the width and height of the bounding boxw = max(0, xx2 - xx1 + 1)h = max(0, yy2 - yy1 + 1)# compute the ratio of overlap between the computed# bounding box and the bounding box in the area listoverlap = float(w * h) / area[j]# if there is sufficient overlap, suppress the# current bounding boxif overlap > overlapThresh:suppress.append(pos)# delete all indexes from the index list that are in the# suppression listidxs = np.delete(idxs, suppress)# return only the bounding boxes that were pickedreturn boxes[pick]# construct a list containing the images that will be examined # along with their respective bounding boxes images = [("images/audrey.jpg", np.array([(12, 84, 140, 212),(24, 84, 152, 212),(36, 84, 164, 212),(12, 96, 140, 224),(24, 96, 152, 224),(24, 108, 152, 236)])),("images/bksomels.jpg", np.array([(114, 60, 178, 124),(120, 60, 184, 124),(114, 66, 178, 130)])),("images/gpripe.jpg", np.array([(12, 30, 76, 94),(12, 36, 76, 100),(72, 36, 200, 164),(84, 48, 212, 176)]))]# loop over the images for (imagePath, boundingBoxes) in images:# load the image and clone itprint "[x] %d initial bounding boxes" % (len(boundingBoxes))image = cv2.imread(imagePath)orig = image.copy()# loop over the bounding boxes for each image and draw themfor (startX, startY, endX, endY) in boundingBoxes:cv2.rectangle(orig, (startX, startY), (endX, endY), (0, 0, 255), 2)# perform non-maximum suppression on the bounding boxespick = non_max_suppression_slow(boundingBoxes, 0.3)print "[x] after applying non-maximum, %d bounding boxes" % (len(pick))# loop over the picked bounding boxes and draw themfor (startX, startY, endX, endY) in pick:cv2.rectangle(image, (startX, startY), (endX, endY), (0, 255, 0), 2)# display the imagescv2.imshow("Original", orig)cv2.imshow("After NMS", image)cv2.waitKey(0)效果如下圖:
總結
以上是生活随笔為你收集整理的(转)非极大抑制(Non-Maximum Suppression)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 通过vba代码将word转换为PDF
- 下一篇: 浅谈低代码平台