画像から 91x91 ピクセルのパッチを取得し、HOG を使用してその特徴ベクトルを抽出する MATLAB コードがあります。Pythonで関数を書き直したいです。Python で MATLAB と同じ HOG 戻り値を取得する方法を見つけようとしてしばらく苦労しましたが、失敗しました。何かお役に立てば幸いです。
VLFeat ライブラリ ( http://www.vlfeat.org/overview/hog.html ) は MATLAB コードで使用され、Python で scikit-image を使用しています ( http://scikit-image.org/docs/dev/ api/skimage.feature.html?highlight=peak_local_max#skimage.feature.hog )。
Matlab では、入力 'im2single(patch)' は 91*91 配列ですが、Hog の返されるデータ型は 4*4*16 single です。HoG は、セル サイズ 23 と向きの数 4 を使用して適用されます。
hog = vl_hog(im2single(patch),23, 'variant', 'dalaltriggs', 'numOrientations',4) ;
返されるデータは 4*4*16 シングルで、次の形式で表示できます。
val(:,:,1) =
0 0 0 0
0 0 0 0
0 0.2000 0.2000 0.0083
0 0.2000 0.2000 0.0317
....
val(:,:,16) =
0 0 0 0
0 0 0 0
0 0 0.0526 0.0142
0 0 0.2000 0.2000
次に、結果は手動で 256*1 の特徴ベクトルに平坦化されます。要約すると、ピクセルの 91*91 パッチで、256*1 の特徴ベクトルが抽出されます。今、私はPythonで同じ結果を得たいと思っています。
私の Python コードでは、同じセル サイズと向きの数で HOG を適用しようとしました。ブロック サイズは (1,1) に設定されています。
tc = hog(repatch, orientations=4, pixels_per_cell=(23,23), cells_per_block= (1,1), visualise=False, normalise=False)
パッチのサイズを 92*92 に追加したので、パッチのサイズはセル サイズの整数倍になります。入力配列は「repatch」と呼ばれるようになりました。ただし、出力 'tc' は 64*1 配列です (勾配ヒストグラムは特徴ベクトルに平坦化されます)。
tc.shape
(64,)
次に、Skimage のソース コードを調べました。
orientation_histogram = np.zeros((n_cellsy, n_cellsx, orientations))
orientation_histogram.shape
(4, 4, 4)
ここで、n_cellsx は x のセル数、n_cellsy は y のセル数です。Hog の出力は、orientation_histogram の次元に大きく関係しているようです。
値が返される HoG の実際の次元は、次のように決定されます。
normalised_blocks = np.zeros((n_blocksy, n_blocksx,by, bx, orientations))
n_blocksy、n_blocksy は次のように計算されます。
n_blocksx = (n_cellsx - bx) + 1
n_blocksy = (n_cellsy - by) + 1
n_cellsx: x のセルの数。ここでは値は 4 です。n_cellsy も同様です。bx,by は cells_per_block で、(1,1) です。この場合、向きは 4 です。
戻り値 (normalized_blocks) のサイズは 4*4*1*1*4 (n_blocksy * n_blocksx * by * bx * orientations) で計算されるようです。
ブロックサイズを変更しようとしましたが、期待どおりの結果が得られません... (ブロックサイズが (2,2) の場合、返される値は 144*1 配列です)
誰でも助けてもらえますか...どうすればMatlabと同じHog出力を得ることができますか? どうもありがとう。