[pythonと画像処理]Pythonは画像HOGの特徴を抽出する
23167 ワード
Python、numpyライブラリを用いて画像HOGの特徴の抽出を実現し、主にHOGの特徴を分析する具体的なアルゴリズムフローに用いられる.参照リンク:https://blog.csdn.net/qq_37141382/article/details/89342081参考資料:HOGの経典論文:Dalal N,Triggs B.Histograms of oriented gradients for human detection[C]//Computer Vision and Pattern Recognition,2005.CVPR 2005. IEEE Computer Society Conference on. IEEE, 2005, 1: 886-893.(2016:Google Citation: 14046)
HOG特徴抽出アルゴリズムの全実現過程は大体以下の通りである:1、必要な画像を読み込む;2、RGB画像を階調画像に変換する(入力されたカラーの画像のr,g,b値を特定の数式で階調値に変換する).3、入力画像をGamma補正法で色空間の標準化(正規化)する.4、画像の各画素の勾配(大小と方向を含む)を計算し、輪郭情報を取得する.5、各cellを統計する(88例)勾配ヒストグラム(異なる勾配方向の振幅値)、各cellのfeature descriptorを形成する;6、4つのcellを1つのblockに構成する(22を例として)、1つのブロック内の4つのcellの特徴を直列に接続してそのブロックのHOG特徴descriptorを得る;7、画像内のすべてのブロックのHOG特徴descriptorを直列に接続してその画像のHOG特徴descriptorを得る、これが最終分類の特徴ベクトルである.
Pythonコードは、必要に応じてcellのサイズを変更し、blockのサイズを変更します.
HOG特徴抽出アルゴリズムの全実現過程は大体以下の通りである:1、必要な画像を読み込む;2、RGB画像を階調画像に変換する(入力されたカラーの画像のr,g,b値を特定の数式で階調値に変換する).3、入力画像をGamma補正法で色空間の標準化(正規化)する.4、画像の各画素の勾配(大小と方向を含む)を計算し、輪郭情報を取得する.5、各cellを統計する(88例)勾配ヒストグラム(異なる勾配方向の振幅値)、各cellのfeature descriptorを形成する;6、4つのcellを1つのblockに構成する(22を例として)、1つのブロック内の4つのcellの特徴を直列に接続してそのブロックのHOG特徴descriptorを得る;7、画像内のすべてのブロックのHOG特徴descriptorを直列に接続してその画像のHOG特徴descriptorを得る、これが最終分類の特徴ベクトルである.
Pythonコードは、必要に応じてcellのサイズを変更し、blockのサイズを変更します.
#coding:utf-8
#*********************************************************************************************************
'''
: python/numpy/opencv HOG
:
:
1) ,resize (128,64);
2) gamma ;
3) Sobel , X Y / ,
(X Y ), gradient_magnitude、
gradient_angle
4) (cell_x = 128/8 =16, cell_y= 64/8 =8) cell ---- grad_cell , ang_cell ,
cell 8*8 = 64 ;
5) cell (0-180) 9 bin, cell , cell 9 ;
6) (2*2) cell block, 15*7 block, block , , block 9*4=36 ;
7) HOG: Block HOG
:15*7*36 = 3780,
, SVM 。
'''
import cv2
import numpy as np
import matplotlib.pyplot as plt
# gamma
def gamma(img):
# gamma
# img1 = img.copy()
# img2 = img.copy()
# img1 = np.power( img1 / 255.0, 0.5 )
# img2 = np.power( img2 / 255.0, 2.2 )
return np.power( img / 255.0, 1 )
# cell , cell
def div( img, cell_x, cell_y, cell_w ):
cell = np.zeros( shape = ( cell_x, cell_y, cell_w, cell_w ) )
img_x = np.split( img, cell_x, axis = 0 )
for i in range( cell_x ):
img_y = np.split( img_x[i], cell_y, axis = 1 )
for j in range( cell_y ):
cell[i][j] = img_y [j]
return cell
# , 9
def get_bins( grad_cell, ang_cell ):
bins = np.zeros( shape = ( grad_cell.shape[0], grad_cell.shape[1], 9 ) )
for i in range( grad_cell.shape[0] ):
for j in range( grad_cell.shape[1] ):
binn = np.zeros(9)
grad_list = np.int8( grad_cell[i,j].flatten() )# cell 64 ,
ang_list = ang_cell[i,j].flatten()# cell 64 )
ang_list = np.int8( ang_list / 20.0 )#0-9
ang_list[ ang_list >=9 ] = 0
for m in range(len(ang_list)):
binn[ang_list[m]] += int( grad_list[m] )# ,
# cell
# N = 9
# x = np.arange( N )
# str1 = ( '0-20', '20-40', '40-60', '60-80', '80-100', '100-120', '120-140', '140-160', '160-180' )
# plt.bar( x, height = binn, width = 0.8, label = 'cell histogram', tick_label = str1 )
# for a, b in zip(x, binn):
# plt.text( a, b+0.05, '{}'.format(b), ha = 'center', va = 'bottom', fontsize = 10 )
# plt.show()
bins[i][j] = binn
return bins
# HOG , 15*7*36 = 3780
def hog( img, cell_x, cell_y, cell_w ):
height, width = img.shape
gradient_values_x = cv2.Sobel( img, cv2.CV_64F, 1, 0, ksize = 5 )#x
gradient_values_y = cv2.Sobel( img, cv2.CV_64F, 0, 1, ksize = 5 )#y
gradient_magnitude = np.sqrt( np.power( gradient_values_x, 2 ) + np.power( gradient_values_y, 2 ) )
gradient_angle = np.arctan2( gradient_values_x, gradient_values_y )
print( gradient_magnitude.shape, gradient_angle.shape )
# plt.figure()
# plt.subplot( 1, 2, 1 )
# plt.imshow(gradient_angle)
# (0-180)
gradient_angle[ gradient_angle > 0 ] *= 180 / 3.14
gradient_angle[ gradient_angle < 0 ] = ( gradient_angle[ gradient_angle < 0 ] + 3.14 ) *180 / 3.14
# plt.subplot( 1, 2, 2 )
# plt.imshow( gradient_angle )
# plt.show()
grad_cell = div( gradient_magnitude, cell_x, cell_y, cell_w )
ang_cell = div( gradient_angle, cell_x, cell_y, cell_w )
bins = get_bins ( grad_cell, ang_cell )
feature = []
for i in range( cell_x - 1 ):
for j in range( cell_y - 1 ):
tmp = []
tmp.append( bins[i,j] )
tmp.append( bins[i+1,j] )
tmp.append( bins[i,j+1] )
tmp.append( bins[i+1,j+1] )
tmp -= np.mean( tmp )
feature.append( tmp.flatten() )
return np.array( feature ).flatten()
if __name__ == '__main__':
img = cv2.imread( './data/basketball1.png', cv2.IMREAD_GRAYSCALE )
if( img is None ):
print( 'Not read image.' )
print( img.shape )
resizeimg = cv2.resize( img, ( 128, 64 ), interpolation = cv2.INTER_CUBIC )
cell_w = 8
cell_x = int( resizeimg.shape[0] / cell_w )#cell
cell_y = int( resizeimg.shape[1] / cell_w )#cell
print( 'The size of cellmap is {}*{} '.format( cell_x, cell_y ) )
gammaimg = gamma( resizeimg )*255
feature = hog( gammaimg, cell_x, cell_y, cell_w )
print( feature.shape )