計算機視覺愛好者必看:特徵工程HOG特徵描述子指南

全文共4499字,預計學習時長9分鐘算法

特徵工程在機器學習算法領域中能夠說是「改變遊戲規則」的存在。特徵工程是進行最多實驗的領域——根據現有內容設計新特徵並改善模型的表現。數據庫

一些世界上頂尖的數據科學家依靠特徵工程提升本身在黑客馬拉松中的排行榜得分。微信

那麼此項技術能夠擴展應用於非結構化數據嗎,例如圖像?這對計算機視覺愛好者來講是一個有趣的謎題,本文將揭曉答案。準備好對圖像數據應用特徵提取技術,從而執行特徵工程。機器學習

事實上,特徵提取有衆多方法。

本文將介紹一種熱門的圖像特徵提取方法——方向梯度直方圖(Histogram of Oriented Gradients),稱做HOG更爲熟知。具體包括:理解HOG特徵描述子是什麼、工做機制(算法背後完整的數學運算),以及在Python中的應用。函數

目錄工具

1. 什麼是特徵描述子?學習

2. HOG特徵描述子介紹ui

3. HOG計算過程人工智能

3.1 數據預處理設計

3.2 梯度計算

3.3 幅值和方向計算

4. 使用梯度和方向建立直方圖的方法

5. HOG計算過程

5.1 梯度直方圖計算

5.2 梯度規範化

5.3 完整圖像特徵

6. 在Python中應用HOG特徵描述子

什麼是特徵描述子?

請看下面兩張圖片。你能辨別出圖片中的物體嗎?

能夠清楚地看到,左圖中有一輛汽車,右圖中有一條狗。接下來,把這個問題變得稍微複雜點——辨別下圖中的物體。

仍是很簡單,對吧?你知道兩個問題的區別嗎?第一組圖片包含不少信息,如物體形狀、顏色、邊緣和背景等。

相比來看,第二組圖片中的信息少多了(只有形狀和邊緣),但這些信息足以辨別圖片中物體。

你知道咱們接下來要講什麼了嗎?在第二組圖片中,能夠輕鬆辨識物體,由於其中包含了識別物體所需的必要信息。而這也就是特徵描述子的做用:

特徵描述子是圖片的簡略替代,其中只包含圖像最重要的信息。

此外還有不少種特徵描述子。如下是最熱門的幾種:

· HOG: 方向梯度直方圖

· SIFT: 尺度不變特徵變換

· SURF: 加速穩健特徵

本文聚焦HOG特徵描述子及其工做機制。如今開始吧!

HOG特徵描述子介紹

HOG,也稱做方向梯度直方圖,是經常使用於提取圖像數據特徵的一種特徵子。其普遍應用於計算機視覺任務以進行目標檢測。

一同看看HOG與其它特徵描述子的區別:

· HOG特徵描述子關注物體的結構或形狀。你可能會問,這和提取的圖像邊緣信息有什麼區別?就邊緣信息而言,只能辨別此像素是否屬於邊緣。而HOG還能提供邊緣的方向。這是經過提取邊緣的梯度和方向實現的。

· 另外,這些方向是在「局部」區域計算得出的。這就意味着一張完整的圖片被分紅了幾個小部分,針對每一個區域計算其梯度和方向。更多相關細節會在下文說起。

· 最後,HOG會分別爲這些部分生成直方圖。因爲它們是使用像素值的梯度和方向創造出來的,因此得名「方向梯度直方圖」。

其正式定義爲:

HOG特徵描述子用於統計和計算圖片中局部區域出現的梯度方向。

使用相似OpenCV的工具應用HOG很是簡單。因爲skimage.feature庫中已有被稱爲hog的預約義函數,因此只需幾行代碼便可。然而,本文的重點聚焦這些特徵究竟是怎樣計算出來的。

HOG計算過程

經過上文,想必你對HOG特徵描述子已有基本瞭解。如今該開始研究本文背後的核心思想了。你們共同逐步討論HOG的計算過程。

思考下圖尺寸(180 x 280)。一同詳細瞭解這張圖像的HOG特徵是如何建立的。

第1步:數據預處理(64 x 128)

大家中大多數人應該都很熟悉這一步。數據預處理在任何機器學習項目中都是關鍵步驟,處理圖像時也不例外。

在此須要對圖像進行預處理,將寬高比降爲1:2。圖像最佳尺寸爲64 x 128。這是由於須要將圖片分爲8*8和16*16的小塊以提取特徵。使用特定的尺寸(64 x 128)會讓後續運算很是簡便。實際上,這個數據就是原始論文(http://lear.inrialpes.fr/people/triggs/pubs/Dalal-cvpr05.pdf)中使用的值。

回到本文所給出的例子上,選用64 x 28這一大小的圖像做爲當前的標準圖像尺寸。下圖是修改尺寸後的圖像。

第2步:梯度計算(x和y方向)

下一步是計算圖像中每一像素的梯度。梯度是x和y方向所發生的微小變化。本文中,筆者從圖像中取一小塊區域,並計算其梯度:

從上圖的小塊區域中獲得像素值。對此區域,生成了以下的像素矩陣(下圖所示的矩陣僅用做例子,且不是所示區域的初始像素值):

圖源:機器學習應用課程

筆者已將像素值85高亮表示。如今,肯定x方向的梯度(或變化),須要用像素值85右側值減去其左側值。相應地,計算y方向的梯度,須要用所選像素值85上方的值減去其下方的值。

由此計算出這一像素在x和y方向的梯度爲:

· x方向變化(Gx) = 89 – 78 = 11

· y方向變化(Gy) = 68 – 56 = 8

此過程得出兩個新矩陣——一組x方向的存儲梯度,一組y方向的存儲梯度。這與使用大小爲1的索伯算子相似。密度上有劇烈變化時,如邊緣周圍的密度,幅度則會升高。

目前已分別計算求得x和y方向的梯度。請對圖像中全部像素重複同一步驟。下一步就是使用這些值計算出幅值和方向。

第3步:幅值和方向計算

使用上一步中計算出的梯度,而後肯定每一個像素值的幅值和方向。在此步驟中,會運用到勾股定理(是的,就是你在學校學過的那個!)。

請看下圖:

梯度基本上對應的都是相似圖中的底邊和垂直邊。因此,上例的Gx爲11,Gy爲8。 應用勾股定理計算總斜率幅值:

總斜率幅值= √[(Gx)2+(Gy)2]

總斜率幅值= √[(11)2+(8)2] = 13.6

接下來,計算每一個像素的方向。能夠用tan計算角度。

tan(Φ) = Gy / Gx

所以,角度值爲:

Φ = atan(Gy / Gx)

把值帶入函數後,得出的方向值爲36。因此至此,已經有每一個像素值的總梯度和方向。而後須要使用這些梯度和方向值生成直方圖。

但等等——在深刻了解HOG特徵描述子中的直方圖是如何建立的以前,先休息一下。把這想做整個過程當中的一個小步驟。文中將先討論使用已擁有的兩個值——梯度和方向來建立直方圖的一些簡單方法。

使用梯度和方向建立直方圖的方法

直方圖是展現一組連續數據分佈頻率的圖表。已有x軸上的變量(bin形式)和y軸上的頻率。本文中使用x軸上的角度或方向,y軸上的頻率。

方法1:

首先是最簡單的生成直方圖的方式。使用每一個像素值,找出像素的方向並更新頻率表。

下圖是高亮的像素值(85)的過程。由於此像素的方向值爲36,因此針對此值在36上方填入一個數字,以表示頻率:

來源: 機器學習應用課程

對全部像素值重複此過程,直至標記完圖像中這些角度和出現頻率表。這個頻率表可以使用x軸的角度值和y軸的頻率值生成直方圖。

這是建立直方圖的一種方法。注意,此處直方圖的bin值爲1。由此獲得約180個不一樣的bucket,每一個表明一個方向值。另外一種方法是爲更大的bin值建立直方圖特徵。

方法2:

此法與方法1相似,惟一的不一樣是bin的大小爲20。因此,得出bucket的數量爲9。

隨後,檢查每一個像素的方向並存儲9x1矩陣中方向值的頻率。繪製此圖得出直方圖:

來源: 機器學習應用課程

方法3:

以上兩種方法僅用方向值生成直方圖,沒有將梯度值考慮在內。方法3是生成直方圖的另外一種方法——將梯度幅值填入矩陣,而不是頻率。請看下圖示例:

來源:機器學習應用課程

可能會注意到,使用方向值30,只更新爲20的bin值。另外,還應該給其它bin增長一些權重。

方法4:

此法對方法4作出一些微調。在此,將像素梯度的contribution值加到像素梯度任意一邊的bin中。請記住,bin值越接近方向值的,contribution更高。


來源:機器學習應用課程

這就是HOG特徵描述子建立直方圖的方式。

第4步:計算8x8單元(9x1)的梯度直方圖

HOG特徵描述子中建立的直方圖不是爲整幅圖像生成的。相反,圖像被分紅8x8的幾個單元,且爲每一個單元計算定向梯度直方圖。你以爲這會發生什麼呢?

這樣作獲得更小區域的特徵(或直方圖),相應地表明整幅圖像。在此固然能夠將8x8的值改成16x16或32x32。

若是將圖像分爲8x8單元並生成直方圖,相應每一個單元會獲得一個9x1的矩陣。此矩陣使用上文提到的方法4生成。

一旦爲圖片中8x8的區域生成HOG,接下來就是進行直方圖規範化。

第5步:在16x16單元(36x1)中進行梯度規範化

理解規範化如何進行以前,先理解這樣作的緣由很重要。

儘管已經爲圖像8x8單元建立了HOG特徵,圖像的梯度對總體的亮度尤其敏感。這意味着對於一張特定圖片,圖像的某一部分與其餘部分相比會很是明亮。

雖然沒法今後圖像中完全清除亮度的差異,可是能夠經過對16x16區域進行梯度規範化來減弱亮度變化。下圖例子能夠解釋16x16區域是如何建立出來的。

在此合併四個8x8單元建立一個16x16的區域。已知每一個8x8的單元的直方圖有一個9x1矩陣。因此,此處應有4個9x1矩陣或者一個36x1矩陣。爲對矩陣進行規範化,用每個值除以值的平方和的平方根。給定的向量V的數學表示爲:

V = [a1, a2, a3, ….a36]

計算平方和的平方根數值:

k = √(a1)2+ (a2)2+ (a3)2+ ….(a36)2

用向量V中的每個值除以k:

結果將是一個大小爲36x1的規範化向量

第6步:完整圖像特徵

目前處於爲圖像生成HOG特徵的最後一步。至此,已經爲圖像中的16x16區域建立特徵。如今將全部特徵合併用於得到最終圖片的特徵。

你能猜出給定圖像最終的特徵總數是多少嗎?首先須要求出一個64×128圖像能夠獲得多少16×16大小的區域:

105(7x15)塊16x16區域。每一塊都有一個36x1的向量做爲特徵。所以,圖片的特徵總數爲105x36x1=3780個。

如今已爲一幅圖片生成了HOG特徵,文末還會驗證是否獲得了相同數量的特徵。

在Python中應用HOG特徵描述子

是時候打開Python了!筆者敢保證這是本文最使人期待的部分。一塊兒看下去吧。

下文將顯示一幅圖的HOG特徵是如何生成的,以及一樣的方法可否應用於更大的數據集。首先下載所需的數據庫和即將要建立HOG特徵的圖像:

#importing required libraries

from skimage.io import imread, imshow

from skimage.transform import resize

from skimage.feature import hog

from skimage import exposure

import matplotlib.pyplot as plt

%matplotlib inline

#reading the image

img = imread('puppy.jpeg')

imshow(img)

print(img.shape)

(663, 459, 3)

由上可見,圖像大小爲663x459。須要將圖像大小變爲64x128。請注意,文中所使用的是skimage,其須要輸入高度x寬度。

#resizing image

resized_img = resize(img, (128,64))

imshow(resized_img)

print(resized_img.shape)

(128, 64, 3)

本文中將直接使用skimage.features的hog函數。所以沒必要單獨計算梯度、幅值(總梯值)和方向。hog函數將在內部計算它並返回特徵矩陣。
此外,若是設置參數爲‘visualize = True’,它將返回一張HOG的圖像。
#creating hog features
fd, hog_image = hog(resized_img, orientations=9, pixels_per_cell=(8, 8),
cells_per_block=(2, 2), visualize=True, multichannel=True)
在繼續前,先介紹一下這些超參數都表明什麼。

· orientations是所建立的bucket數量。由於本文中想獲得一個9x1的矩陣,因此將orientations設置爲9。

· pixels_per_cell定義所建立直方圖的單元尺寸。本文中所涉及的例子都使用了8x8單元,在此將設置相同的值。正如上文所提,你能夠選擇改變這個值。

· 另外一個超參數cells_per_block指所規範化的直方圖上的小塊區域大小。本文提到的單元是指每小塊區域,而不是像素的數量。因此,此處用2x2表示,而不是16x16。

函數的特徵矩陣存儲在變量fd中, 圖像存儲於hog_image中。檢查一下特徵矩陣的大小:

fd.shape

(3780,)

正如預期那樣,共有3780個圖像特徵,這驗證了以前在第7步中所作的計算。你能夠選擇更改超參數的值,這將提供不一樣大小的特徵矩陣。

最後,來看一看HOG圖像:

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(16, 8), sharex=True, sharey=True)

ax1.imshow(resized_img, cmap=plt.cm.gray)

ax1.set_title('Input image')

# Rescale histogram for better display

hog_image_rescaled = exposure.rescale_intensity(hog_image, in_range=(0, 10))

ax2.imshow(hog_image_rescaled, cmap=plt.cm.gray)

ax2.set_title('Histogram of Oriented Gradients')

plt.show()

留言 點贊 關注

咱們一塊兒分享AI學習與發展的乾貨
歡迎關注全平臺AI垂類自媒體 「讀芯術」


(添加小編微信:dxsxbb,加入讀者圈,一塊兒討論最新鮮的人工智能科技哦~)

相關文章
相關標籤/搜索