Si encuentras algún error con tu código o trabajo, recuerda probar siempre en un entorno de testing antes añadir el código al trabajo final.
Solución:
Yo mismo usé la respuesta aceptada para mi procesamiento de imágenes, pero la encuentro (y las otras respuestas) demasiado dependiente de otros módulos. Por lo tanto, aquí está mi solución compacta:
import numpy as np
def gkern(l=5, sig=1.):
"""
creates gaussian kernel with side length l and a sigma of sig
"""
ax = np.linspace(-(l - 1) / 2., (l - 1) / 2., l)
xx, yy = np.meshgrid(ax, ax)
kernel = np.exp(-0.5 * (np.square(xx) + np.square(yy)) / np.square(sig))
return kernel / np.sum(kernel)
Editar: se cambió un rango a linspace para manejar incluso longitudes laterales
¿Desea utilizar el kernel gaussiano para, por ejemplo, suavizar imágenes? Si es así, hay una función. gaussian_filter()
en scipy:
respuesta actualizada
Esto debería funcionar: aunque todavía no es 100% preciso, intenta dar cuenta de la masa de probabilidad dentro de cada celda de la cuadrícula. Creo que usar la densidad de probabilidad en el punto medio de cada celda es un poco menos preciso, especialmente para núcleos pequeños. Consulte https://homepages.inf.ed.ac.uk/rbf/HIPR2/gsmooth.htm para ver un ejemplo.
import numpy as np
import scipy.stats as st
def gkern(kernlen=21, nsig=3):
"""Returns a 2D Gaussian kernel."""
x = np.linspace(-nsig, nsig, kernlen+1)
kern1d = np.diff(st.norm.cdf(x))
kern2d = np.outer(kern1d, kern1d)
return kern2d/kern2d.sum()
Probándolo en el ejemplo de la Figura 3 desde el enlace:
gkern(5, 2.5)*273
da
array([[ 1.0278445 , 4.10018648, 6.49510362, 4.10018648, 1.0278445 ],
[ 4.10018648, 16.35610171, 25.90969361, 16.35610171, 4.10018648],
[ 6.49510362, 25.90969361, 41.0435344 , 25.90969361, 6.49510362],
[ 4.10018648, 16.35610171, 25.90969361, 16.35610171, 4.10018648],
[ 1.0278445 , 4.10018648, 6.49510362, 4.10018648, 1.0278445 ]])
La respuesta original (aceptada) a continuación aceptada es incorrecta
La raíz cuadrada es innecesaria y la definición del intervalo es incorrecta.
import numpy as np
import scipy.stats as st
def gkern(kernlen=21, nsig=3):
"""Returns a 2D Gaussian kernel array."""
interval = (2*nsig+1.)/(kernlen)
x = np.linspace(-nsig-interval/2., nsig+interval/2., kernlen+1)
kern1d = np.diff(st.norm.cdf(x))
kernel_raw = np.sqrt(np.outer(kern1d, kern1d))
kernel = kernel_raw/kernel_raw.sum()
return kernel
Estoy tratando de mejorar la respuesta de FuzzyDuck aquí. Creo que este enfoque es más corto y más fácil de entender. Aquí estoy usando signal.scipy.gaussian
para obtener el núcleo gaussiano 2D.
import numpy as np
from scipy import signal
def gkern(kernlen=21, std=3):
"""Returns a 2D Gaussian kernel array."""
gkern1d = signal.gaussian(kernlen, std=std).reshape(kernlen, 1)
gkern2d = np.outer(gkern1d, gkern1d)
return gkern2d
Graficarlo usando matplotlib.pyplot
:
import matplotlib.pyplot as plt
plt.imshow(gkern(21), interpolation='none')
Te invitamos a corroborar nuestra función escribiendo un comentario y valorándolo te estamos eternamente agradecidos.