HOG特征提取分四步
一、将在x,y方向上的差分圖譜笛卡爾坐标轉換成極坐标擷取HOG特征,HOG特征分兩副特征圖譜,分别是長度圖譜、角度圖譜
二、分别對長度圖譜與角度圖譜進行切割,重組,切割的最小單元為重組後的細胞元,也就是将原二維圖譜變為四維圖譜
三、将每個細胞元進行提取特征,也就是提取特征向量(角度、長度),值得注意的是提取特征向量時需考慮權重,也就是對應角度在左右兩邊所占的比例
四、每個細胞元的特征向量與周圍2*2的範圍内特征向量進行歸一化,連接配接所有細胞元特征向量,作為整幅圖的特征向量
代碼如下:
import numpy as np
import cv2
path = 'test.jpg'
image = cv2.imread(path,0)
image = cv2.resize(image,(64,128))
#進行差分,提取邊緣
gx = cv2.Sobel(image,cv2.CV_32F,dx=1,dy=0)
gy = cv2.Sobel(image,cv2.CV_32F,dx=0,dy=1)
#将笛卡爾坐标轉換成極坐标
mag,ang = cv2.cartToPolar(gx,gy,angleInDegrees=True)
#設定細胞元大小及整幅圖中各次元細胞元數量
cells_x = 16
cells_y = 8
cells_w = 8
#對圖像進行切割重組,增加次元,二維變四維
def devil_ag(mag,cells_x,cells_y,cells_w):
new_map = np.zeros((cells_x,cells_y,cells_w,cells_w))
mag_x = np.split(mag,cells_x,axis=0)
for i,l in enumerate(mag_x):
mag_x[i] = np.asarray(l)
mag_y = np.split(mag_x[i],cells_y,axis=1)
for j,l1 in enumerate(mag_y):
mag_y[j] = np.asarray(l1)
new_map[i,j] = mag_y[j]
return new_map
#對角度譜圖與長度譜圖提取特征,擷取細胞元特征向量
def get_bins(mag_cell,ang_cell):
bin_num = 9
bins = [0.0]*bin_num
offset = 20
mag_list = mag_cell.flatten()
ang_list = ang_cell.flatten()
for i,ang in enumerate(ang_list):
if ang>=180:
ang -= 180
left = int(ang/offset)
right = left+1 if left!=bin_num-1 else 0
left_ration = ang/offset - left
right_ration = 1-left_ration
bins[left] = mag_list[i]*left_ration
bins[right] = mag_list[i]*right_ration
return bins
hist = []
mag_cells = devil_ag(mag,16,8,8)
ang_cells = devil_ag(ang,16,8,8)
#對特征向量進行2*2範圍内的歸一化
for i in range(cells_x-1):
for j in range(cells_y-1):
mag_sum = np.sum(mag_cells[i][j])+np.sum(mag_cells[i+1][j])+np.sum(mag_cells[i][j+1])+np.sum(mag_cells[i+1][j+1])
hist.extend(get_bins(mag_cells[i][j]/mag_sum,ang_cells[i][j]))
hist.extend(get_bins(mag_cells[i+1][j]/mag_sum,ang_cells[i+1][j]))
hist.extend(get_bins(mag_cells[i][j+1]/mag_sum,ang_cells[i][j+1]))
hist.extend(get_bins(mag_cells[i+1][j+1]/mag_sum,ang_cells[i+1][j+1]))
print(hist)