計算機視覺(八):提取Cifar-10資料集的HOG、HSV特徵並使用神經網路進行分類
1 - 引言
之前我們都是將整張圖片輸入進行分類,要想進一步提升準確率,我們就必須提取出圖片更容易區分的特徵,再將這些特徵當做特徵向量進行分類。在之前我們學了一些常用的影象特徵,在這次實驗中,我們使用了兩種特徵
- 梯度方向直方圖(HOG)
- 顏色直方圖(HSV)
為什麼選用這兩種特徵呢?
應為HOG捕捉到的是影象的紋理特徵,而忽略了顏色資訊,顏色直方圖會表示影象的顏色特徵而忽略了紋理特徵,因此將這兩者的特徵結合起來可能會得到一個比較好的結果,當然,我們也可以試試選用其他的特徵,有可能可以得到更好的效果哦
然後把每張圖的梯度方向直方圖和顏色直方圖特徵合併形成我們最後的特徵向量,將特徵向量輸入進神經網路中進行訓練,並完成分類。
2 - 具體步驟
2.1 - RGB彩色影象轉化成灰度圖
由公式
可得
def rgb2gray(rgb):
"""
將RGB圖片轉換成灰度圖片:公式img = 0.299 * R + 0.587 * G + 0.144 * B
輸入:
rgb : RGB 圖片
返回:
gray : 灰度圖片
"""
return np.dot(rgb[..., :3], [0.299, 0.587, 0.144])
我們可以測試一下
import numpy as np
import matplotlib.pyplot as plt
def rgb2gray(rgb):
return np.dot(rgb[..., :3], [0.299, 0.587, 0.114])
img = plt.imread('images/car.jpg')
gray = img
plt.imshow(gray, cmap=plt.get_cmap('gray'))
plt.show()
2.2 - 提取HOG特徵
提取HOG特徵的步驟如下:
-
計算水平和垂直方向的梯度
某個畫素點的X方向的梯度計算可以通過這個畫素點左右兩邊的畫素值的差值的絕對值計算出來,而y方向的梯度可以通過該畫素上下兩邊的畫素值的差值的絕對值計算。我們可以使用Sobel運算元來計算 -
計算梯度的幅值g和方向theta:
-
在88 的網格中計算梯度直方圖並且對應到9個bin的直方圖中
直方圖的橫軸代表著方向角度
縱軸代表著這88個網格中梯度大小的和 -
塊歸一化
用一個 的視窗(4個 ),也就是4個 的直方圖組合成 的向量,然後做歸一化。之後將視窗朝後面挪8個畫素,重複這個過程把整張圖遍歷一遍
對向量使用L2歸一化:
-
計算HOG特徵向量
根據這個思想可以建構函式:
def hog_feature(im):
"""
計算圖片的梯度方向直方圖(HOG)特徵
從 skimage.feature.hog 中修改而來
http://pydoc.net/Python/scikits-image/0.4.2/skimage.feature.hog
Reference:
Histograms of Oriented Gradients for Human Detection
Navneet Dalal and Bill Triggs, CVPR 2005
Parameters:
im : 灰度圖片或者RBG圖片
Returns:
feat: HOG 特徵
"""
# 如果影象維數是3維,則轉換成灰度圖
if im.ndim == 3:
image = rgb2gray(im)
else:
image = np.at_least_2d(im)
sx, sy = image.shape # 圖片尺寸
orientations = 9 # 梯度直方圖的數量
cx, cy = (8, 8) # 一個單元的畫素個數
gx = np.zeros(image.shape)
gy = np.zeros(image.shape)
gx[:, :-1] = np.diff(image, n=1, axis=1) # compute gradient on x-direction
gy[:-1, :] = np.diff(image, n=1, axis=0) # compute gradient on y-direction
grad_mag = np.sqrt(gx ** 2 + gy ** 2) # gradient magnitude
grad_ori = np.arctan2(gy, (gx + 1e-15)) * (180 / np.pi) + 90 # gradient orientation
n_cellsx = int(np.floor(sx / cx)) # number of cells in x
n_cellsy = int(np.floor(sy / cy)) # number of cells in y
# compute orientations integral images
orientation_histogram = np.zeros((n_cellsx, n_cellsy, orientations))
for i in range(orientations):
# create new integral image for this orientation
# isolate orientations in this range
temp_ori = np.where(grad_ori < 180 / orientations * (i + 1),
grad_ori, 0)
temp_ori = np.where(grad_ori >= 180 / orientations * i,
temp_ori, 0)
# select magnitudes for those orientations
cond2 = temp_ori > 0
temp_mag = np.where(cond2, grad_mag, 0)
orientation_histogram[:, :, i] = uniform_filter(temp_mag, size=(cx, cy))[int(cx / 2)::cx, int(cy / 2)::cy].T
return orientation_histogram.ravel()
HOG演算法重點
Dalal提出的HOG特徵特區的過程,把樣本影象分割為若干個畫素的單元(cell),把梯度方向平均劃分成9個區間(bin),在每個單元裡面對所有畫素的梯度方向在各個方向區間進行直方圖統計,得到一個9維的特徵向量,每相鄰的4個單元構成一個塊(block),把一個塊內的特徵向量連起來得到36維的特徵向量,用塊對樣本影象進行掃描,掃描步長為一個單元。最後將所有塊的特徵串聯起來。
例如
一個圖片為
的影象,每
的畫素組成一個cell,每
個cell組成一個快,因為每個cell有9個特徵,所以每個塊內又
個特徵,以8個畫素為步長,那麼,水平方向將有7個掃描視窗,垂直方向有15個掃描視窗,也就是說,64128的圖片,總共有367*15 = 3780 個特徵
2.3 - 提取HSV特徵
HSV是一種比較直觀的顏色模型,所以在許多影象編輯工具中應用比較廣泛,這個模型中顏色的引數分別是:色調(H, Hue),飽和度(S,Saturation),明度(V, Value)。
色調H
用角度度量,取值範圍為0°~360°,從紅色開始按逆時針方向計算,紅色為0°,綠色為120°,藍色為240°。它們的補色是:黃色為60°,青色為180°,品紅為300°;
飽和度S
飽和度S表示顏色接近光譜色的程度。一種顏色,可以看成是某種光譜色與白色混合的結果。其中光譜色所佔的比例愈大,顏色接近光譜色的程度就愈高,顏色的飽和度也就愈高。飽和度高,顏色則深而豔。光譜色的白光成分為0,飽和度達到最高。通常取值範圍為0%~100%,值越大,顏色越飽和。
明度V
明度表示顏色明亮的程度,對於光源色,明度值與發光體的光亮度有關;對於物體色,此值和物體的透射比或反射比有關。通常取值範圍為0%(黑)到100%(白)。
RGB轉換HSV公式
設max等於r、g、b中的最大者,min為最小者,對應的HSV空間中的(h,s,v)值為: