在特定位置创建一个均值 = 1 的高斯二维数组

问题描述

正如标题所说,我有以下内容一个 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,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

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

解决方法

这使用 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)

输出:

enter image description here

,

您可以使用 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,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])
>>> plt.show()

2D gaussian

,

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

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

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

我认为它会像这样实现:

ele

如上计算 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) 在距原点合理距离处切断高斯。