我有以下代码用8个箱子计算HOG图像并预先计算Sobel X和Y滤波图像:
for y in xrange(0, 480):
for x in xrange(0, 640):
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)
我试图修改它以避免循环:
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
hog[:,:,angle] += np.sqrt(sobel_X**2 + sobel_Y**2)
但是,最后一个表达式没有正确计算。我基本上需要的是根据来自角度数组的索引,在hog数组的每个(y,x)点处将幅度(np.sqrt ...表达式)添加到hog数组。任何解决方案?
答案 0 :(得分:2)
使用
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]
是正确的表达方式,但它相当于物理学家的dimensionality check,这表明我们至少可以走上正轨。
使用NumPy fancy indexing,当Y
,X
和angle
具有相同的形状(或广播到相同的形状)时,
hog[Y, X, angle]
也将具有相同的形状。 (i,j)
中的hog[Y, X, angle]
元素将等于
hog[Y[i,j], X[i,j], angle[i,j]]
这就是hog[Y, X, angle] += magnitude
有效的原因。