34從傳統(tǒng)算法到深度學(xué)習(xí):目標(biāo)檢測入門實(shí)戰(zhàn) --方向梯度直方圖

什么是方向梯度直方圖

在前面的實(shí)驗(yàn) 1髓考、實(shí)驗(yàn) 2 中部念,我們了解到傳統(tǒng)的目標(biāo)檢測流程可分為三個(gè)步驟,第一步是使用滑動窗口和圖像金字塔從圖片中選擇一些區(qū)域氨菇。第二步是將選擇出來的區(qū)域轉(zhuǎn)化為人工設(shè)計(jì)的特征儡炼,可稱為特征提取。第三步是將這些特征輸入分類器進(jìn)行分類查蓉。方向梯度直方圖(Histogram of Oriented Gradients)以下簡稱 HOG射赛,就是一種人工設(shè)計(jì)的特征,用來簡化圖像表述的特征描述符奶是。
下圖中左邊的圖片是一只貓楣责,我們不僅可以看出貓身體上的特征、顏色聂沙、紋理秆麸,而且還能看到背景。右邊的圖片是使用 HOG 來表示的圖片及汉,除了可以看到圖中能看出貓的外形沮趣,其他的細(xì)節(jié)包括背景幾乎都被去除了,故右邊的圖片是左邊圖片的一種簡化表示形式坷随。HOG 可以用來表示物體的形狀房铭、外形特征,將這些特征輸入分類器就可以實(shí)現(xiàn)目標(biāo)的分類温眉。


image.png

在傳統(tǒng)的算法中缸匪,使用 HOG 描述圖片,可以保留有用信息类溢,剔除無用的信息凌蔬,這樣不僅減少計(jì)算量,還使得分類器的效果更好闯冷。HOG 可以分為以下幾個(gè)步驟:預(yù)先歸一化砂心、計(jì)算水平和垂直方向梯度、計(jì)算梯度直方圖蛇耀、區(qū)域(Blocks)歸一化辩诞。

方向梯度直方圖流程

預(yù)先歸一化(Normalization)

在計(jì)算梯度前可對圖片歸一化(Normalization)處理,歸一化的目的是使所有的數(shù)值落入到統(tǒng)一的范圍內(nèi)纺涤,從而使算法能有更好的表現(xiàn)译暂。在 HOG 的原論文中提到使用伽馬矯正的方法處理輸入圖片抠忘,伽馬矯正可以增加圖像的對比度。但是在很多情況下秧秉,伽馬矯正對提升算法效果不明顯褐桌,我們可以跳過圖片預(yù)先歸一化衰抑,直接計(jì)算圖片梯度象迎。

計(jì)算梯度

前面提到可以不用預(yù)先對圖片進(jìn)行歸一化,故可以說 HOG 特征是從計(jì)算圖像在水平方向和垂直方向上的梯度開始的呛踊。圖像的梯度計(jì)算是使用卷積核對圖像進(jìn)行卷積操作砾淌,例如我們可以使用矩陣 [[-1, 0, 1]] 和 [[-1], [0], [1]] 分別與圖像上的每個(gè)像素進(jìn)行運(yùn)算來獲得水平和垂直方向上的梯度。


image.png

image.png

image.png

image.png

上面的兩個(gè)公式分別計(jì)算每個(gè)像素的梯度幅值G和梯度方向θ谭网。下面左圖是合并水平汪厨、垂直方向上的梯度獲得的梯度幅值,可以看到相較于水平愉择、垂直方向上的圖片劫乱,左圖中貓的輪廓更清晰明顯。右圖表示圖片中的梯度方向锥涕。


image.png

方向梯度直方圖

現(xiàn)在我們已經(jīng)有了梯度幅值G和梯度方向θ衷戈,接下來我們就可以計(jì)算方向梯度直方圖了。在計(jì)算方向梯度直方圖之前层坠,我們需要將圖片分成若干個(gè)小方格(Cells)殖妇,為避免歧義下文皆書寫為 Cell 或 Cells 。例如破花,下圖是一張寬高為649×385 的圖片谦趣,我們將其平均分割成若干個(gè) Cells,每個(gè) Cell 內(nèi)包含 8×8 個(gè)像素座每,所以圖片的高被分為 ?385÷8?=48 份前鹅,圖片的寬被分為 ?649÷8?=81 份(?? 表示向下取整),故整張圖片有48×81 個(gè) Cells峭梳。


image.png

至此我們已經(jīng)將圖片分成許多 Cells嫡纠,對于每一個(gè) Cell,使用G和θ 來構(gòu)建方向梯度直方圖延赌。首先我們先選擇梯度方向的范圍除盏,梯度方向的范圍可分為 0 到 180 度(無符號)和 0 到 360 度(有符號),通常使用 0 到 180 度的范圍挫以。然后將 0 到 180 度的范圍分成 9 個(gè)區(qū)間(bins)者蠕,分別為 0 到 20 度,20 到 40 度掐松, 40 到 60 度 …… 160 到 180 度踱侣。每個(gè)像素都有一個(gè)梯度幅值和一個(gè)梯度方向粪小,所以方向梯度直方圖的計(jì)算就是每個(gè)像素所對應(yīng)的梯度方向落在 9 個(gè)區(qū)間中的哪一個(gè),那么該像素的梯度幅值就在該區(qū)間中累加抡句。
下圖是一個(gè)計(jì)算方向梯度圖的例子探膊,對于紅色方框中的像素,假設(shè)其中有些像素對應(yīng)的梯度方向落在 0 到 20 區(qū)間待榔,那么將這些像素對應(yīng)的梯度幅值在 0 到 20 區(qū)間內(nèi)進(jìn)行累加逞壁,同理其他區(qū)間也做同樣的運(yùn)算,最終得到下圖中右邊的方向梯度直方圖锐锣。同樣地腌闯,整張圖片中的所有 Cells 都用同樣的方法計(jì)算方向梯度直方圖。


image.png

區(qū)域(Blocks)歸一化

我們已經(jīng)將圖像分成若干個(gè) Cells雕憔,并且計(jì)算了每個(gè) Cell 的方向梯度直方圖姿骏。接下來我們要對圖像進(jìn)行區(qū)域歸一化處理,歸一化的目的是減少光照變化對圖像梯度的影響斤彼。 現(xiàn)在讓我們來看看如何進(jìn)行歸一化處理分瘦。
首先我們先來介紹什么是區(qū)域(Blocks),為避免歧義下文皆書寫為 Block 或 Blocks琉苇,前面我們將圖像分成若干個(gè) Cells嘲玫,每個(gè) Cell 內(nèi)有若干個(gè)像素,類似地翁潘,一個(gè) Block 是一塊由若干個(gè) Cells 組成的矩形趁冈。對圖像進(jìn)行歸一化的過程類似于前面實(shí)驗(yàn)學(xué)習(xí)的滑動窗口,將一個(gè) Block 從左向右拜马、從上向下在圖中滑動渗勘,然后在每個(gè) Block 區(qū)域內(nèi)進(jìn)行歸一化計(jì)算。
讓我們通過下圖來理解如何通過 Blocks 對圖片進(jìn)行歸一化俩莽。 下圖中右邊圖片是我們從原圖片中選取的一部分旺坠,在這塊區(qū)域里面有若干個(gè) Cells,我們用紅色矩形框表示一個(gè) Blcok扮超,紅色矩形框在圖上向右滑動一個(gè) Cell 的步長后我們就得到了藍(lán)色矩形框取刃,所以區(qū)域歸一化的方法就是設(shè)定一個(gè)尺寸為K×K 個(gè) Cells 的 Block,在圖上從左向右出刷、從上向下滑動璧疗,然后在每個(gè) Block 內(nèi)進(jìn)行歸一化。


image.png

在每個(gè) Block 內(nèi)有2×2 個(gè) Cells馁龟,前面我們將梯度方向分為 9 個(gè)區(qū)間并為每個(gè) Cell 計(jì)算了方向梯度直方圖崩侠,故每個(gè) Cell 有 9 個(gè)向量财饥,則在一個(gè) Block 內(nèi)共有2×2×9 個(gè)向量根悼。然后我們可以使用L1范數(shù)或L2范數(shù)對 Block 內(nèi)的向量進(jìn)行歸一化抄腔。其中使用L2范數(shù)進(jìn)行歸一化的效果相對較好售淡,下面就是使用L2范數(shù)歸一化的公式,即 Block 內(nèi)的每個(gè)向量除以由 Block 內(nèi)所有向量計(jì)算得到的L2范數(shù)系瓢。其中vi表示 Block 內(nèi)的向量阿纤,? 的作用是防止出現(xiàn)分母為 0 的情況,它是一個(gè)很小的值夷陋。


image.png

從上圖中可以看出每一個(gè) Cell 不止出現(xiàn)在一個(gè) Block 內(nèi)欠拾,也就是說一個(gè) Cell 將被重復(fù)的用于歸一化計(jì)算中,這樣做會看似比較冗余肌稻,但是會提高特征描述的表現(xiàn)清蚀。最后對所有的 Block 完成歸一化計(jì)算匕荸,合并所有獲得的歸一化后的向量爹谭,這樣我們就完成了圖像的 HOG 特征化表示。

使用 Scikit-image 實(shí)現(xiàn)方向梯度直方圖

本節(jié)實(shí)驗(yàn)我們將通過幾行簡單的代碼來實(shí)現(xiàn) HOG 算法榛搔。首先我們執(zhí)行下面命令下載需要用到的圖片诺凡。

!wget https://labfile.oss.aliyuncs.com/courses/3096/pets.jpg

然后我們從 Scikit-image 導(dǎo)入 feature 和 exposure 模塊。feature 模塊里存放著一些用于計(jì)算特征的算法践惑,exposure 模塊具有一些直方圖處理的功能腹泌。我們還需要導(dǎo)入 cv2 模塊用于圖片的讀取。

from skimage import feature
from skimage import exposure
from matplotlib import pyplot as plt
import cv2

%matplotlib inline

接著使用 cv2.imread 函數(shù)讀取圖片尔觉。

image = cv2.imread("pets.jpg")

我們使用 feature.hog 用于計(jì)算圖片的方向梯度直方圖凉袱。該函數(shù)的參數(shù)意義如下所示。
第一個(gè)參數(shù) image 表示輸入圖像侦铜。
orientations 表示要將梯度方向分成幾個(gè)區(qū)間专甩,這里我們將梯度方向分為 9 個(gè)區(qū)間。
pixels_per_cell 表示 Cell 的尺寸钉稍,即一個(gè) Cell 中有幾個(gè)像素涤躲,需要傳遞一個(gè)元組給該參數(shù),我們將 (8, 8) 傳遞給該參數(shù)贡未。
cells_per_block 表示每個(gè) Block 的尺寸种樱,即一個(gè) Block 中有幾個(gè) Cells,這里需要傳遞一個(gè)元組給該參數(shù)俊卤,我們將 (2, 2) 傳遞給該參數(shù)嫩挤。
transform_sqrt 表示伽馬校正,我們將 True 傳遞給該參數(shù)表示使用伽馬校正預(yù)先對圖片進(jìn)行歸一化處理消恍。
visualize 表示可視化岂昭,將 True 傳遞給該參數(shù)表示返回 HOG 圖像。

(o, hog) = feature.hog(image, orientations=9, pixels_per_cell=(8, 8),
    cells_per_block=(2, 2), transform_sqrt=True, visualize=True)

該函數(shù)返回 2 個(gè)值哺哼,第一個(gè)值 o 是 HOG 圖像的一維展開數(shù)組佩抹。第二個(gè)值 hog 表示返回一個(gè)高和寬同輸入圖像一樣的二維數(shù)組叼风,這個(gè)值可用于可視化方向梯度直方圖。
接下來我們使用 exposure.rescale_intensity 來調(diào)整的輸入圖片的像素值大小或像素強(qiáng)度棍苹。因?yàn)楂@得的 hog 中的元素值都為被歸一化了无宿,所以這些值都比較小,如果直接將這些值作為圖像的像素值枢里,那么該圖像看起來像一張全黑圖片孽鸡,我們需要用該函數(shù)將這些值拉伸到一個(gè)較大的范圍。

hog = exposure.rescale_intensity(hog, out_range=(0, 255))
hog = hog.astype("uint8")
hog[hog > 50] = 255

我們傳遞 2 個(gè)參數(shù)給該函數(shù)栏豺,第一個(gè)參數(shù) hog 表示前面獲取的可視化二維數(shù)組彬碱。第二個(gè)參數(shù) out_range 表示將輸入圖片的像素強(qiáng)度拉伸到設(shè)定的范圍,這里我們將 hog 中的每個(gè)元素值拉伸到 (0, 255) 范圍內(nèi)奥洼。接下來我們使用 astype 方法將 hog 中的元素轉(zhuǎn)換為 uint8 類型巷疼。最后我們將 hog 中大于 50 的元素賦值為 255。
我們使用 plt.figure 創(chuàng)建畫板灵奖,參數(shù) dpi=150 表示圖像的分辨率設(shè)置為 150嚼沿。最后使用 plt.imshow 函數(shù)顯示圖片。

plt.figure(dpi=150)
plt.imshow(hog, cmap = 'gray', aspect='auto')

如下圖瓷患,左邊圖片是輸入圖片骡尽,右邊是對輸入圖片使用 HOG 提取特征后的圖片,可以看到相較于左邊圖片擅编,右邊圖片僅保留了動物的外形特征攀细。


image.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市爱态,隨后出現(xiàn)的幾起案子谭贪,更是在濱河造成了極大的恐慌,老刑警劉巖肢藐,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件故河,死亡現(xiàn)場離奇詭異,居然都是意外死亡吆豹,警方通過查閱死者的電腦和手機(jī)鱼的,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來痘煤,“玉大人凑阶,你說我怎么就攤上這事≈钥欤” “怎么了宙橱?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我师郑,道長环葵,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任宝冕,我火速辦了婚禮张遭,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘地梨。我一直安慰自己菊卷,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布宝剖。 她就那樣靜靜地躺著洁闰,像睡著了一般。 火紅的嫁衣襯著肌膚如雪万细。 梳的紋絲不亂的頭發(fā)上扑眉,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天,我揣著相機(jī)與錄音雅镊,去河邊找鬼襟雷。 笑死刃滓,一個(gè)胖子當(dāng)著我的面吹牛仁烹,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播咧虎,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼卓缰,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了砰诵?” 一聲冷哼從身側(cè)響起征唬,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎茁彭,沒想到半個(gè)月后总寒,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡理肺,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年摄闸,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片妹萨。...
    茶點(diǎn)故事閱讀 40,115評論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡年枕,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出乎完,到底是詐尸還是另有隱情熏兄,我是刑警寧澤,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站摩桶,受9級特大地震影響桥状,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜硝清,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一岛宦、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧耍缴,春花似錦砾肺、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蚁趁,卻和暖如春裙盾,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背他嫡。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工番官, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人钢属。 一個(gè)月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓徘熔,卻偏偏與公主長得像,于是被迫代替她去往敵國和親淆党。 傳聞我的和親對象是個(gè)殘疾皇子酷师,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評論 2 355

推薦閱讀更多精彩內(nèi)容