3

我有以下代码来计算带有 8 个 bin 和预先计算的 Sobel X 和 Y 滤波图像的 HOG 图像:

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)

但是,最后一个表达式计数不正确。我基本上需要的是根据角度数组的索引,在猪数组的每个(y,x)点将幅度(np.sqrt ...表达式)添加到猪数组中。有什么解决办法吗?

4

1 回答 1

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]正确表达的证明,但它相当于物理学家的维数检查,表明我们至少可以走在正确的轨道上。


使用NumPy 花式索引,when YXangle都具有相同的形状(或广播到相同的形状),

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有效。

于 2013-07-15T18:42:28.310 回答