詳解非極大值抑制算法之Python實(shí)現(xiàn)
一、概述
這里不討論通用的NMS算法(參考論文《Efficient Non-Maximum Suppression》對1維和2維數(shù)據(jù)的NMS實(shí)現(xiàn)),而是用于目標(biāo)檢測中提取分?jǐn)?shù)最高的窗口的。例如在行人檢測中,滑動窗口經(jīng)提取特征,經(jīng)分類器分類識別后,每個窗口都會得到一個分?jǐn)?shù)。但是滑動窗口會導(dǎo)致很多窗口與其他窗口存在包含或者大部分交叉的情況。這時就需要用到NMS來選取那些鄰域里分?jǐn)?shù)最高(是行人的概率最大),并且抑制那些分?jǐn)?shù)低的窗口。
NMS在計(jì)算機(jī)視覺領(lǐng)域有著非常重要的應(yīng)用,如視頻目標(biāo)跟蹤、數(shù)據(jù)挖掘、3D重建、目標(biāo)識別以及紋理分析等。
二、NMS 在目標(biāo)檢測中的應(yīng)用
2.1、人臉檢測框重疊例子
我們的目的就是要去除冗余的檢測框,保留最好的一個.
有多種方式可以解決這個問題,Triggs et al. 建議使用Mean-Shift
算法,利用bbox的坐標(biāo)和當(dāng)前圖片尺度的對數(shù)來檢測bbox的多種模式.但效果可能并不如使用強(qiáng)分類器結(jié)合NMS的效果好.
2.2、目標(biāo)檢測 pipline
產(chǎn)生proposal后使用分類網(wǎng)絡(luò)給出每個框的每類置信度,使用回歸網(wǎng)絡(luò)修正位置,最終應(yīng)用NMS.
三、NMS 原理
對于Bounding Box的列表B及其對應(yīng)的置信度S,采用下面的計(jì)算方式.選擇具有最大score的檢測框M,將其從B集合中移除并加入到最終的檢測結(jié)果D中.通常將B中剩余檢測框中與M的IoU大于閾值Nt的框從B中移除.重復(fù)這個過程,直到B為空.
3.1、重疊率(重疊區(qū)域面積比例IOU)閾值
常用的閾值是 0.3 ~ 0.5
.
其中用到排序,可以按照右下角的坐標(biāo)排序或者面積排序,也可以是通過SVM等分類器得到的得分或概率,R-CNN中就是按得分進(jìn)行的排序.
就像上面的圖片一樣,定位一個車輛,最后算法就找出了一堆的方框,我們需要判別哪些矩形框是沒用的。非極大值抑制的方法是:先假設(shè)有6個矩形框,根據(jù)分類器的類別分類概率做排序,假設(shè)從小到大屬于車輛的概率 分別為A、B、C、D、E、F。
(1)從最大概率矩形框F開始,分別判斷A~E與F的重疊度IOU是否大于某個設(shè)定的閾值;
(2)假設(shè)B、D與F的重疊度超過閾值,那么就扔掉B、D;并標(biāo)記第一個矩形框F,是我們保留下來的。
(3)從剩下的矩形框A、C、E中,選擇概率最大的E,然后判斷E與A、C的重疊度,重疊度大于一定的閾值,那么就扔掉;并標(biāo)記E是我們保留下來的第二個矩形框。
就這樣一直重復(fù),找到所有被保留下來的矩形框。
3.2、代碼示例
在R-CNN中使用了NMS來確定最終的bbox,其對每個候選框送入分類器,根據(jù)分類器的類別分類概率做排序(論文中稱為greedy-NMS).但其實(shí)也可以在分類之前運(yùn)用簡單版本的NMS來去除一些框.
python實(shí)現(xiàn)的單類別nms:py_cpu_nms.py.
def py_cpu_nms(dets, 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] #每一個檢測框的面積 areas = (x2 - x1 + 1) * (y2 - y1 + 1) #按照score置信度降序排序 order = scores.argsort()[::-1] keep = [] #保留的結(jié)果框集合 while order.size > 0: i = order[0] keep.append(i) #保留該類剩余box中得分最高的一個 #得到相交區(qū)域,左上及右下 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:]]) #計(jì)算相交的面積,不重疊時面積為0 w = np.maximum(0.0, xx2 - xx1 + 1) h = np.maximum(0.0, yy2 - yy1 + 1) inter = w * h #計(jì)算IoU:重疊面積 /(面積1+面積2-重疊面積) ovr = inter / (areas[i] + areas[order[1:]] - inter) #保留IoU小于閾值的box inds = np.where(ovr <= thresh)[0] order = order[inds + 1] #因?yàn)閛vr數(shù)組的長度比order數(shù)組少一個,所以這里要將所有下標(biāo)后移一位 return keep
Faster R-CNN的MATLAB實(shí)現(xiàn)與python版實(shí)現(xiàn)一致,代碼在這里:nms.m.另外,nms_multiclass.m是多類別nms,加了一層for循環(huán)對每類進(jìn)行nms而已.
四、NMS loss
值的注意的是對多類別檢測任務(wù),如果對每類分別進(jìn)行NMS,那么當(dāng)檢測結(jié)果中包含兩個被分到不同類別的目標(biāo)且其IoU較大時,會得到不可接受的結(jié)果。如下圖所示:
一種改進(jìn)方式便是在損失函數(shù)中加入一部分NMS損失。NMS損失可以定義為與分類損失相同:
即真實(shí)列別u對應(yīng)的log損失,p是C個類別的預(yù)測概率。實(shí)際相當(dāng)于增加分類誤差。
參考論文《Rotated Region Based CNN for Ship Detection》(IEEE2017會議論文)的Multi-task for NMS部分。
五、Soft-NMS
上述NMS算法的一個主要問題是當(dāng)兩個ground truth的目標(biāo)的確重疊度很高時,NMS會將具有較低置信度的框去掉(置信度改成0),參見下圖所示.
論文:《Improving Object Detection With One Line of Code》
改進(jìn)之處:
改進(jìn)方法在于將置信度改為IoU的函數(shù):f(IoU),具有較低的值而不至于從排序列表中刪去.
1.線性函數(shù)
函數(shù)值不連續(xù),在某一點(diǎn)的值發(fā)生跳躍.
2.高斯函數(shù)
時間復(fù)雜度同傳統(tǒng)的greedy-NMS,為
5.1、python代碼實(shí)現(xiàn)
ua = float((tx2 - tx1 + 1) * (ty2 - ty1 + 1) + area - iw * ih) ov = iw * ih / ua #iou between max box and detection box if method == 1: # linear if ov > Nt: weight = 1 - ov else: weight = 1 elif method == 2: # gaussian weight = np.exp(-(ov * ov)/sigma) else: # original NMS if ov > Nt: weight = 0 else: weight = 1 # re-scoring 修改置信度 # boxes[pos, 4] = weight*boxes[pos, 4]
5.2、Caffe C++ 版實(shí)現(xiàn)
效果
在基于proposal方法的模型結(jié)果上應(yīng)用比較好,檢測效果提升:
在R-FCN以及Faster-RCNN模型中的測試階段運(yùn)用Soft-NMS,在MS-COCO數(shù)據(jù)集上mAP@[0.5:0.95]
能夠獲得大約1%的提升(詳見這里). 如果應(yīng)用到訓(xùn)練階段的proposal選取過程理論上也能獲得提升. 在自己的實(shí)驗(yàn)中發(fā)現(xiàn)確實(shí)對易重疊的目標(biāo)類型有提高(目標(biāo)不一定真的有像素上的重疊,切斜的目標(biāo)的矩形邊框會有較大的重疊).
而在SSD,YOLO等非proposal方法中沒有提升.
六、其它應(yīng)用
邊緣檢測:Canny算子中的非極大值抑制是沿著梯度方向進(jìn)行的,即是否為梯度方向上的極值點(diǎn);
特征點(diǎn)檢測:在角點(diǎn)檢測等場景下說的非極大值抑制,則是檢測中心點(diǎn)處的值是否是某一個鄰域內(nèi)的最大值.
以上就是詳解非極大值抑制算法之Python實(shí)現(xiàn)的詳細(xì)內(nèi)容,更多關(guān)于非極大值抑制 Python實(shí)現(xiàn)的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
django框架基于模板 生成 excel(xls) 文件操作示例
這篇文章主要介紹了django框架基于模板 生成 excel(xls) 文件操作,結(jié)合具體實(shí)例形式分析了Django框架基于模板生成excel的實(shí)現(xiàn)步驟與相關(guān)操作技巧,需要的朋友可以參考下2019-06-06詳解利用OpenCV提取圖像中的矩形區(qū)域(PPT屏幕等)
這篇文章主要介紹了詳解利用OpenCV提取圖像中的矩形區(qū)域(PPT屏幕等),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-07-07Python爬蟲scrapy框架Cookie池(微博Cookie池)的使用
這篇文章主要介紹了Python爬蟲scrapy框架Cookie池(微博Cookie池)的使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01Pyqt5 關(guān)于流式布局和滾動條的綜合使用示例代碼
這篇文章主要介紹了Pyqt5 關(guān)于流式布局和滾動條的綜合使用示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03python subprocess 殺掉全部派生的子進(jìn)程方法
下面小編就為大家?guī)硪黄猵ython subprocess 殺掉全部派生的子進(jìn)程方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-01-01詳解django的serializer序列化model幾種方法
序列化是將對象狀態(tài)轉(zhuǎn)換為可保持或傳輸?shù)母袷降倪^程。這篇文章主要介紹了詳解django的serializer序列化model幾種方法。具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-10-10人工智能學(xué)習(xí)pyTorch自建數(shù)據(jù)集及可視化結(jié)果實(shí)現(xiàn)過程
這篇文章主要為大家介紹了人工智能學(xué)習(xí)pyTorch自建數(shù)據(jù)集及可視化結(jié)果的實(shí)現(xiàn)過程,有需要的朋友可以借鑒參考下,希望能夠有所幫助2021-11-11一文帶你了解Python 四種常見基礎(chǔ)爬蟲方法介紹
這篇文章主要介紹了一文帶你了解Python 四種常見基礎(chǔ)爬蟲方法介紹,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12python 字符串轉(zhuǎn)列表 list 出現(xiàn)\ufeff的解決方法
下面小編就為大家?guī)硪黄猵ython 字符串轉(zhuǎn)列表 list 出現(xiàn)\ufeff的解決方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-06-06Python 過濾字符串的技巧,map與itertools.imap
Python中的map函數(shù)非常有用,在字符轉(zhuǎn)換和字符遍歷兩節(jié)都出現(xiàn)過,現(xiàn)在,它又出現(xiàn)了,會給我們帶來什么樣的驚喜呢?是不是要告訴我們,map是非常棒的,以后要多找它玩呢?2008-09-09