【问题标题】:numpy 2d array (coordinates) need to assign into 3D array, to some particular binnumpy 2d 数组(坐标)需要分配到 3D 数组中,分配给某个特定的 bin
【发布时间】:2013-07-15 18:17:48
【问题描述】:

我有以下代码来计算带有 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 ...表达式)添加到猪数组中。有什么解决办法吗?

【问题讨论】:

    标签: python arrays opencv numpy indexing


    【解决方案1】:

    使用

    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,当YXangle都具有相同的形状(或广播到相同的形状),

    hog[Y, X, angle]
    

    也将具有相同的形状。 hog[Y, X, angle] 中的 (i,j)th 元素将等于

    hog[Y[i,j], X[i,j], angle[i,j]]
    

    这就是hog[Y, X, angle] += magnitude 起作用的原因。

    【讨论】:

    • 10 毫秒!太棒了,谢谢你! :) 正在考虑像索引数组这样的东西应该在每个维度中,但不确定是否有解决方案,现在我明白了,thanx!
    猜你喜欢
    • 2017-11-15
    • 1970-01-01
    • 2013-08-28
    • 2010-12-21
    • 1970-01-01
    • 2020-09-01
    • 2015-08-09
    • 2021-12-26
    • 1970-01-01
    相关资源
    最近更新 更多