利用
magnitude = np.sqrt(sobel_X**2 + sobel_Y**2)
Y, X = np.ogrid[0:angle.shape[0], 0:angle.shape[1]]
hog[Y, X, angle] += magnitude
更新hog
。
import numpy as np
def using_for_loop(hog, sobel_Y, sobel_X):
for y in xrange(0, sobel_Y.shape[0]):
for x in xrange(0, sobel_X.shape[1]):
base_angle = np.arctan2(sobel_Y[y, x], sobel_X[y, x]) * 180 / np.pi
if base_angle < 0:
base_angle += 360
angle = int(round(base_angle / 45))
if angle == 8:
angle = 0
hog[y, x, angle] += np.sqrt(sobel_X[y, x] ** 2 +
sobel_Y[y, x] ** 2)
return hog
def using_indexing(hog, sobel_Y, sobel_X):
base_angle = np.arctan2(sobel_Y, sobel_X) * 180 / np.pi
base_angle[base_angle < 0] += 360
angle = (base_angle / 45).round().astype(np.uint8)
angle[angle == bins] = 0
magnitude = np.sqrt(sobel_X ** 2 + sobel_Y ** 2)
Y, X = np.ogrid[0:angle.shape[0], 0:angle.shape[1]]
hog[Y, X, angle] += magnitude
return hog
bins = 8
sobel_Y, sobel_X = np.meshgrid([1, 2, 3], [4, 5, 6, 7])
# hog = np.zeros(sobel_X.shape + (bins,))
hog = np.random.random(sobel_X.shape + (bins,))
answer = using_for_loop(hog, sobel_Y, sobel_X)
result = using_indexing(hog, sobel_Y, sobel_X)
assert np.allclose(answer, result)
请注意,如果
In [62]: angle.shape
Out[62]: (4, 3)
然后
In [74]: hog[:,:,angle].shape
Out[74]: (4, 3, 4, 3)
那不是正确的形状。相反,如果你定义
In [75]: Y, X = np.ogrid[0:angle.shape[0], 0:angle.shape[1]]
然后hog[Y, X, angle]
具有与 相同的形状magnitude
:
In [76]: hog[Y, X, angle].shape
Out[76]: (4, 3)
In [77]: magnitude = np.sqrt(sobel_X ** 2 + sobel_Y ** 2)
In [78]: magnitude.shape
Out[78]: (4, 3)
当然,这不是一个hog[Y, X, angle]
正确表达的证明,但它相当于物理学家的维数检查,表明我们至少可以走在正确的轨道上。
使用NumPy 花式索引,when Y
、X
和angle
都具有相同的形状(或广播到相同的形状),
hog[Y, X, angle]
也将具有相同的形状。中的(i,j)
第 th 个元素hog[Y, X, angle]
将等于
hog[Y[i,j], X[i,j], angle[i,j]]
这就是为什么hog[Y, X, angle] += magnitude
有效。