【问题标题】:Creating a Gaussian 2d array with mean = 1 at specificed location在指定位置创建均值 = 1 的高斯二维数组
【发布时间】:2021-03-11 10:17:43
【问题描述】:

正如标题所说,我有以下内容 : 一个 NXN 平方一热编码数组,它只有一个单元格为 1,所有其他单元格为 0。这个 1 可以在网格上的任何位置,不一定在中心。

我想使用 tensorflow 现在使正方形成为高斯型二维数组,其中 1 的单元格是值为 1 的平均值,并且它周围的所有单元格都是值

import numpy as np
import matplotlib.pyplot as plt
x, y = np.meshgrid(np.linspace(-1,1,10), np.linspace(-1,1,10))
d = np.sqrt(x*x+y*y)
sigma, mu = 1.0, 1.0
g = np.exp(-( (d-mu)**2 / ( 2.0 * sigma**2 ) ) )
plt.imshow(g, interpolation='none')
plt.show()

输出example output

对于上述我的问题的任何建议/帮助将不胜感激!

【问题讨论】:

    标签: python numpy tensorflow statistics computer-vision


    【解决方案1】:

    这使用scipy 来生成高斯核。和np.where 获取值1的坐标。

    import numpy as np
    from scipy import signal
    import matplotlib.pyplot as plt
    N = 7   # kernel size
    k1d = signal.gaussian(N, std=1).reshape(N, 1)
    kernel = np.outer(k1d, k1d)
    plt.imshow(kernel)
    plt.show()
    
    A = np.zeros((16, 16))
    A[5, 9] = 1    # random
    plt.imshow(A)
    plt.show()
    
    row, col = np.where(A == 1)
    A[row[0]-(N//2):row[0]+(N//2)+1, col[0]-(N//2):col[0]+(N//2)+1] = kernel
    plt.imshow(A)
    

    输出:

    【讨论】:

    • 嗨,谢谢@Kh4zit 这看起来很有希望:会试试看!你知道如何使用 Tensorflow 实现相同的目标吗?因为 scipy 在那里不存在
    • 查看@Lescurel 的get_gaussian 函数。或者您可以使用公式计算高斯核。
    【解决方案2】:

    您可以使用tfp.distributions.MultivariateNormalDiag from tensorflow_probability中的概率分布函数:

    import tensorflow_probability as tfp
    import tensorflow as tf
    
    def get_gaussian(mu, sigma):
        mvn = tfp.distributions.MultivariateNormalDiag(loc=mu, scale_diag=sigma)
        x,y = tf.cast(tf.linspace(-1,1,10),tf.float32), tf.cast(tf.linspace(-1,1,10), tf.float32)
        # meshgrid as a list of [x,y] coordinates
        coords = tf.reshape(tf.stack(tf.meshgrid(x,y),axis=-1),(-1,2))
        gauss = mvn.prob(coords)
        return tf.reshape(gauss, (10,10))
    

    平均值为 (0.4,-0.6) 和方差为 (0.5,0.5) 的示例:

    >>> g = get_gaussian([0.4,-0.6], [0.5,0.5])
    >>> plt.imshow(g, extent=[-1,1,-1,1])
    >>> plt.show()
    

    【讨论】:

    • 谢谢:这看起来真不错!我假设我通过将它与上面@Kh4zit 的代码结合来选择 label= 1 的位置
    • 有没有办法指定大小:高斯拉伸到像上面Kh4zit的代码一样的单元格数?
    • 您可以通过将 mu 设置为所需位置来指定位置:它是高斯的平均值,因此它对应于峰值。为了拉伸高斯,您需要使用 sigma,它控制高斯的“平坦”程度。要将峰值变为 1,您需要将其放大,因为它使用 pdf,因此整个平方和为 1。(通过标准化很容易实现)。
    【解决方案3】:

    实现此目的的简单方法是使用高斯核进行卷积(即应用高斯平滑)。

    TensorFlow 在函数tfa.gaussian_filter2d 中有一个二维高斯平滑。

    因为平滑保留了总强度,所以原来为 1 的像素在之后将具有较低的值。您可以手动计算必要的缩放以将其恢复为 1(这取决于 sigma),或者您可以简单地将图像标准化以使其最大值为 1。

    我认为它会像这样实现:

    import tensorflow as tf
    import tensorflow_addons as tfa
    import numpy as np
    
    img = (your array)
    sigma = 1.0
    
    size = ceil(3*sigma)*2+1
    img = tfa.image.gaussian_filter2d(img, size, sigma, 'CONSTANT', 0)
    
    img /= np.amax(img)
    

    如上计算size 会在距原点合理距离处切断高斯。

    【讨论】:

    • @astroboy:我已经添加了关于如何使用 TensorFlow 实现它的猜测。我什至没有安装 TensorFlow,但文档很清楚。
    猜你喜欢
    • 2017-03-11
    • 2020-08-16
    • 2013-09-25
    • 2017-12-07
    • 1970-01-01
    • 2013-09-22
    • 1970-01-01
    • 2010-11-06
    相关资源
    最近更新 更多