signal pass low conv2 code python image matlab signal-processing convolution

pass - Convolución 2D en Python similar a la conv2 de Matlab



scipy.signal python (3)

¿Por qué no implementarlo por sí mismo? Tenga en cuenta que conv2 utiliza una implementación formal directa de la ecuación de convolución bidimensional en forma espacial. Si a y b son funciones de dos variables discretas, n1 y n2, entonces la fórmula para la convolución bidimensional de a y b es:

En la práctica, sin embargo, conv2 calcula la convolución para intervalos finitos.

He estado tratando de hacer la Convolución de una Matriz 2D usando SciPy, y Numpy, pero he fallado. Para SciPy lo intenté, sepfir2d y scipy.signal.convolve y Convolve2D para Numpy. ¿Existe una función simple como conv2 en Matlab para Python?

Aquí hay un ejemplo:

A= [ 5 4 5 4; 3 2 3 2; 5 4 5 4; 3 2 3 2 ]

Quiero convertirlo en [0.707 0.707]

Y el resultado como por conv2 de Matlab es.

3.5350 6.3630 6.3630 6.3630 2.8280 2.1210 3.5350 3.5350 3.5350 1.4140 3.5350 6.3630 6.3630 6.3630 2.8280 2.1210 3.5350 3.5350 3.5350 1.4140

¿Alguna función para calcular esta salida en Python? Estaré agradecido por una respuesta.


Hay varias formas diferentes de hacerlo con scipy , pero la convolución 2D no se incluye directamente en el numpy . (También es fácil de implementar con un Fft usando solo números, si necesita evitar una dependencia escéptica).

scipy.signal.convolve2d , scipy.signal.convolve , scipy.signal.fftconvolve y scipy.ndimage.convolve manejarán una convolución 2D (las tres últimas son Nd) de diferentes maneras.

scipy.signal.fftconvolve hace la convolución en el dominio fft (donde es una simple multiplicación). Esto es mucho más rápido en muchos casos, pero puede llevar a diferencias muy pequeñas en los efectos de borde que en el caso discreto, y sus datos se convertirán en un punto flotante con esta implementación en particular. Además, hay un uso innecesario de la memoria al convertir una matriz pequeña con una matriz mucho más grande. En general, los métodos basados ​​en fft pueden ser mucho más rápidos, pero hay algunos casos de uso comunes en los que scipy.signal.fftconvolve no es una solución ideal.

scipy.signal.convolve2d , scipy.signal.convolve y scipy.ndimage.convolve utilizan una convolución discreta implementada en C, sin embargo, la implementan de diferentes maneras.

scipy.ndimage.convolve mantiene el mismo tipo de datos y le da control sobre la ubicación de la salida para minimizar el uso de la memoria. Si está uint8 (por ejemplo, datos de imagen), a menudo es la mejor opción. La salida siempre tendrá la misma forma que la primera matriz de entrada, lo que tiene sentido para las imágenes, pero quizás no para una convolución más general. ndimage.convolve le da mucho control sobre cómo se manejan los efectos de borde a través del mode kwarg (que funciona de manera completamente diferente al mode kwarg de scipy.signal).

Evite scipy.signal.convolve si está trabajando con matrices 2d. Funciona para el caso Nd, pero es subóptimo para las matrices 2d, y scipy.signal.convolve2d existe para hacer exactamente lo mismo un poco más eficiente. Las funciones de convolución en scipy.signal dan control sobre la forma de salida usando el mode kwarg. (De forma predeterminada, se comportarán como conv2 de matlab). Esto es útil para la convolución matemática general, pero menos útil para el procesamiento de imágenes. Sin embargo, scipy.signal.convolve2d es generalmente más lento que scipy.ndimage.convolve .

Hay muchas opciones diferentes en parte debido a la duplicación en los diferentes submódulos de scipy y en parte porque hay diferentes maneras de implementar una convolución que tienen diferentes compromisos de desempeño.

Si puede dar un poco más de detalles sobre su caso de uso, podemos recomendarle una mejor solución. Si está convirtiendo dos matrices de aproximadamente el mismo tamaño, y ya están flotando, fftconvolve es una excelente opción. De lo contrario, scipy.ndimage.convolve puede vencerlo.


scipy''s convolved1d () hace lo que quieres, solo trata los bordes de manera un poco diferente:

sp.ndimage.filters.convolve1d(A,[0.707,0.707],axis=1,mode=''constant'')

Te regalaré:

array([[ 6.363, 6.363, 6.363, 2.828], [ 3.535, 3.535, 3.535, 1.414], [ 6.363, 6.363, 6.363, 2.828], [ 3.535, 3.535, 3.535, 1.414]])

Si desea el mismo resultado exacto, solo agregue una columna de ceros a A como esta:

sp.ndimage.filters.convolve1d(np.c_[np.zeros((4,1)),A],[0.707,0.707],axis=1,mode=''constant'')

y obtendrá:

array([[ 3.535, 6.363, 6.363, 6.363, 2.828], [ 2.121, 3.535, 3.535, 3.535, 1.414], [ 3.535, 6.363, 6.363, 6.363, 2.828], [ 2.121, 3.535, 3.535, 3.535, 1.414]])

Desde mi experiencia, puedes hacer en Scipy / Numpy la mayor parte de lo que haces en Matlab muy fácilmente (y más).