天天看點

圖像處理(十四)HOG特征提取

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)
           

繼續閱讀