我有一段MATLAB代码,它从图像中获取91x91像素补丁并使用HOG来提取其特征向量。我想在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。
看起来返回值(normalised_blocks)的大小是由4 * 4 * 1 * 1 * 4(n_blocksy * n_blocksx * by * bx * orientation)计算的
我试图改变块大小但仍然无法得到我的预期...(虽然块大小为(2,2),返回值为144 * 1数组)
任何人都可以帮忙...我怎样才能获得与Matlab相同的Hog输出?非常感谢。
答案 0 :(得分:1)
与scikit-image相比,VLFeat库做了一些不同的事情。 VLFeat库返回9(方向数)对比度不敏感,18对比敏感和4维捕获方块中的总梯度能量(包含四个单元)。因此它每个单元输出31个维度。然而,scikit-image程序是不同的,我认为你对它有很好的理解。
根据我的经验,如果你想使用scikit-image和MATLAB找到相同的HoG矢量,你至少应该将cells_per_block= (2,2)
放入scikit-image。