2009-03-24 45 views
5

Estoy tratando de implementar un algoritmo de visión, que incluye una etapa de prefiltrado con un filtro laplaciano de 9x9 de Gauss. ¿Puedes señalar un documento que explica las implementaciones rápidas de filtros brevemente? Creo que debería hacer uso de FFT para un filtrado más eficiente.Manera rápida de implementar la convolución 2D en C

Respuesta

10

¿Estás seguro de que deseas utilizar FFT? Esa será una transformación de matriz completa, que será costosa. Si ya se decidió por un filtro de convolución 9x9, no necesita ninguna FFT.

En general, la manera más económica de hacer convolución en C es configurar un bucle que mueve un puntero sobre la matriz, sumando los valores convolucionados en cada punto y escribiendo los datos en una nueva matriz. Este bucle se puede paralelizar utilizando su método favorito (vectorización de compiladores, bibliotecas MPI, OpenMP, etc.).

En cuanto a los límites:

  • Si asumen los valores sean 0 fuera de los límites, a continuación, añadir un borde de 4 elementos de 0 a su matriz 2D de puntos. Esto evitará la necesidad de declaraciones `if` para manejar los límites, que son caros.
  • Si sus datos se ajustan a los límites (es decir, son periódicos), utilice un módulo o agregue un borde de 4 elementos que copie el lado opuesto de la cuadrícula (abcdefg -> fgabcdefgab para 2 puntos). ** Nota: esto es lo que está asumiendo implícitamente con cualquier tipo de transformada de Fourier, incluida FFT **. Si ese no es el caso, deberá contarlo antes de realizar cualquier FFT.

Los 4 puntos se deben a que la superposición límite máxima de un núcleo de 9x9 es de 4 puntos fuera de la red principal. Por lo tanto, se necesitan n puntos de borde para un kernel 2n + 1 x 2n + 1.

Si necesita que esta convolución sea realmente rápida, y/o la cuadrícula es grande, considere dividirla en partes más pequeñas que puedan guardarse en la memoria caché del procesador, y así calcular mucho más rápidamente. Esto también se aplica a cualquier descarga de GPU que desee realizar (son ideales para este tipo de cálculo de coma flotante).

+0

El uso de un límite de ceros supone que los datos son bastante blancos y de media cero. El uso de un filtro de desenfoque en datos medios distintos de cero con límite cero provocaría distorsiones no deseadas en los bordes. –

+0

Cierto. El uso de FFT supondría en cambio que los datos se ajustan a los límites, lo que también puede ser incorrecto. Los ceros fueron para eliminar costosos ifs. Añadiré algo sobre los límites. –

+0

Jukka el límite siempre sufre.Tienes que hacer algo para dar cuenta y Phil menciona un par de métodos tradicionales. La única manera de no sufrir los límites es realizar la convolución 2d y luego recortarla en 4 píxeles en todos los lados de la imagen. –

2

Aquí hay un enlace teoría http://hebb.mit.edu/courses/9.29/2002/readings/c13-1.pdf

Y aquí es un enlace a FFTW, que es una muy buena biblioteca FFT que he utilizado en el pasado (licencias de verificación para asegurarse de que es adecuado) http://www.fftw.org/

Todo lo que hace es FFT su imagen y kernel (la matriz de 9x9). Multiplicar juntos, luego volver a transformar.

Sin embargo, con una matriz de 9x9 puede ser mejor hacerlo en coordenadas reales (solo con un doble ciclo sobre los píxeles de la imagen y la matriz). ¡Prueba ambas formas!

1

En realidad, no es necesario utilizar un tamaño de FFT lo suficientemente grande como para contener toda la imagen. Puedes hacer un montón de 2d ffts superpuestos más pequeños. Puede buscar "convolución rápida" "superposición guardar" "superposición agregar".

Sin embargo, para un núcleo de 9x9. Es posible que no vea mucha ventaja en el sentido de la velocidad.

Cuestiones relacionadas