1
本文作者: AI研習(xí)社-譯站 | 2018-08-06 15:59 |
雷鋒網(wǎng)按:本文為AI研習(xí)社編譯的技術(shù)博客,原標(biāo)題 (Faster) Non-Maximum Suppression in Python,作者為 Adrian Rosebrock 。
翻譯 | 陶玉龍 校對(duì) | 吳桐 整理 | MY
我有一個(gè)困惑:我不能停止對(duì)目標(biāo)檢測(cè)的思考。
你知道的,昨晚在我在看《行尸走肉》時(shí),不是享受僵尸野蠻和被迫吃人,或引人入勝的故事情節(jié),我只想建立一個(gè)目標(biāo)檢測(cè)系統(tǒng)來(lái)對(duì)僵尸進(jìn)行識(shí)別。
這個(gè)檢測(cè)系統(tǒng)會(huì)很有用嗎?可能不會(huì)。
我是說(shuō),如果一個(gè)僵尸跟在你后面那將是很明顯的:光是那陣惡臭就會(huì)告訴你這是一個(gè)死人(嘿,看看這個(gè)一語(yǔ)雙關(guān))散發(fā)出來(lái)的,更不用說(shuō)猙獰的牙齒和揮動(dòng)的手臂。我們也可能會(huì)陷入那些從僵尸喉嚨里發(fā)出的「腦子.... 腦子...」呻吟聲中。
就像我說(shuō)的,如果有一個(gè)僵尸在你身后,你當(dāng)然不需要計(jì)算機(jī)視覺(jué)系統(tǒng)來(lái)告訴你這件事。但這只是一個(gè)每天都在我腦海里流淌的例子罷了。
為了給你一些相關(guān)信息,兩個(gè)星期前,我在帖子中展示了如何使用直方圖的方向梯度和線性支持向量機(jī)來(lái)建立一個(gè)目標(biāo)檢測(cè)系統(tǒng)。厭倦了 OpenCV Haar 復(fù)雜的結(jié)構(gòu)和糟糕的性能,更不要說(shuō)那么長(zhǎng)的訓(xùn)練時(shí)間,因此我自己動(dòng)手編寫(xiě)了自己的 Python 目標(biāo)檢測(cè)框架。
到目前為止,它運(yùn)行得非常好,而且實(shí)現(xiàn)起來(lái)非常有趣。
但是在構(gòu)建目標(biāo)檢測(cè)系統(tǒng)——重疊候選框這個(gè)不可回避的問(wèn)題你必須處理。這是會(huì)發(fā)生的,沒(méi)有任何辦法可以繞過(guò)它。但事實(shí)上,這是一個(gè)很好的跡象,表明你的目標(biāo)檢測(cè)器正在進(jìn)行合理的微調(diào),所以我甚至不說(shuō)它是一個(gè)「問(wèn)題」。
為了處理這些需要移除的重疊候選框(對(duì)同一個(gè)對(duì)象而言),我們可以對(duì) Mean Shift 算法進(jìn)行非極大值抑制。雖然 Dalal 和 Triggs 更喜歡 Mean-Shift 算法,我卻發(fā)現(xiàn) Mean Shift 給出了低于平均值的結(jié)果。
在收到我朋友 Tomasz Malisiewicz 博士(目標(biāo)檢測(cè)方面的專(zhuān)家)的建議之后,我決定將他 Matlab 上實(shí)現(xiàn)的非最大抑制方法移植到 Python 上。
上周我向你們展示了如何實(shí)施 FelZeZZWalb 等方法。這周我要向你們展示 MalISIEWICZ 這種運(yùn)行速度快 100 倍的方法。
注:我本來(lái)打算在十一月發(fā)布這篇博客,但由于我糟糕的拖延癥,我花了很多時(shí)間才把這篇文章寫(xiě)出來(lái)。不過(guò)無(wú)論如何,它現(xiàn)在已經(jīng)在網(wǎng)上了!
那么提速是從哪里來(lái)的呢?我們是如何獲得這么快的抑制時(shí)間的呢?
繼續(xù)閱讀去找出答案。
(更快的)在Python上的非極大值抑制方法
在我們開(kāi)始之前,如果你還沒(méi)有讀過(guò)上周關(guān)于非極大值抑制的帖子,我建議你先看一下那個(gè)帖子。
如果你已經(jīng)看過(guò)那個(gè)帖子,那么在你最喜歡的編輯器中新建一個(gè)文件,命名為 nms.py,讓我們開(kāi)始創(chuàng)建一個(gè)更快的非極大值抑制實(shí)現(xiàn)方法:
請(qǐng)花幾秒鐘時(shí)間仔細(xì)檢查這個(gè)代碼,將其與上周提出的 FelZeZZWalb 方法進(jìn)行比較。
代碼看起來(lái)幾乎一樣,對(duì)吧?
所以你可能會(huì)問(wèn)自己:「這 100 倍加速是從哪里來(lái)的?」
答案是我們移除了一個(gè)內(nèi)部循環(huán)結(jié)構(gòu)。
上周提出的實(shí)現(xiàn)方法需要一個(gè)額外的內(nèi)部循環(huán)來(lái)計(jì)算邊界區(qū)域的大小和重疊區(qū)域的比率。
在本文中取而代之的是,Malisiewicz 博士用矢量化代碼替換了這個(gè)內(nèi)部循環(huán),這就是我們?cè)趹?yīng)用非極大值抑制時(shí)能夠?qū)崿F(xiàn)更快速度的原因。
與其像上周那樣我一個(gè)人逐行逐行地閱讀代碼,不如讓我們一起來(lái)看一下其中關(guān)鍵的部分。
我們這個(gè)更快的非極大值抑制函數(shù)第 6-22 行基本與上周相同。我們通過(guò)抓取檢測(cè)框的(x,y)坐標(biāo),計(jì)算它們的面積,并根據(jù)每個(gè)框的右下 y 坐標(biāo)將他們分類(lèi)到框列表中。
第 31-55 行包含我們的加速過(guò)程,其中第 41-55 行特別重要。我們不再使用內(nèi)部 for 循環(huán)來(lái)對(duì)單獨(dú)對(duì)每個(gè)框進(jìn)行循環(huán),而是使用 np.maximum 和 np.minimum 對(duì)代碼進(jìn)行矢量化,這使得我們能夠在坐標(biāo)軸上找到最大值和最小值而不僅僅是一個(gè)數(shù)。
注意:你在這里必須使用 np.maximum 和 np.minimum——它們?cè)试S您混合標(biāo)量和向量。然而 np.max 和 np.min 函數(shù)就沒(méi)有這樣的功能,當(dāng)你使用它們時(shí),你會(huì)發(fā)現(xiàn)有一些非常嚴(yán)重的 bug 需要查找和修復(fù)。當(dāng)我把算法從 Matlab 移植到 Python 時(shí),我花了很長(zhǎng)時(shí)間來(lái)解決這個(gè)問(wèn)題。第 47 行和第 48 行也被矢量化,在這里我們計(jì)算每個(gè)矩形的寬度和高度來(lái)進(jìn)行檢查。相似的,第 51 行上的重疊率也被矢量化。從那里,我們只需刪除我們的 IDX 列表中的所有條目,這些條目都大于我們提供的重疊閾值。通常重疊閾值在 0.3-0.5 之間。
Malisiewicz 等人提出的方法與 FelZeZnZWalb 等的基本相同。但通過(guò)使用矢量化代碼,我們能夠在非極大值抑制上實(shí)現(xiàn) 100 倍加速!
運(yùn)行更快的非極大值抑制方法
讓我們繼續(xù)并研究幾個(gè)例子。我們從這張照片的頂部的一個(gè)恐怖的小女孩僵尸開(kāi)始:
圖 1:圖像中有 3 個(gè)檢測(cè)邊界框,但非極大值抑制方法讓其中的兩個(gè)重疊框消失。
......
想要繼續(xù)閱讀,請(qǐng)移步至我們的AI研習(xí)社社區(qū):https://club.leiphone.com/page/TextTranslation/626
更多精彩內(nèi)容盡在 AI 研習(xí)社。
不同領(lǐng)域包括計(jì)算機(jī)視覺(jué),語(yǔ)音語(yǔ)義,區(qū)塊鏈,自動(dòng)駕駛,數(shù)據(jù)挖掘,智能控制,編程語(yǔ)言等每日更新。
手機(jī)端可以掃描二維碼訪問(wèn)
雷鋒網(wǎng)雷鋒網(wǎng)
雷鋒網(wǎng)
雷峰網(wǎng)原創(chuàng)文章,未經(jīng)授權(quán)禁止轉(zhuǎn)載。詳情見(jiàn)轉(zhuǎn)載須知。