2009-06-01 15 views
5

Escribo mi propio filtro gaussiano pero es muy lento.Cómo funciona el algoritmo del filtro gaussiano en OpenCV

El algoritmo gaussiano de OpenCV es mucho más rápido, 20 veces que mi filtro gaussiano. Quiero reescribir el algoritmo gaussiano de OpenCV en mi proyecto, y no quiero incluir opencv en mi proyecto.

Sin embargo,

¿Puede alguien darme la descripción del algoritmo, el código fuente de OpenCV parece demasiado difícil de entender?

Respuesta

12

El filtro Gauss tiene una propiedad que lo hace muy fácil de acelerar: el filtro se puede aplicar en ambas dimensiones de forma independiente. Usted define un filtro unidimensional que opera verticalmente, y otro que opera horizontalmente, y los aplica a ambos; esto produce el mismo efecto que un solo filtro aplicado en dos dimensiones.

Más allá de eso, es probable que deba ver el SIMD instructions, p. SSE3 disponible para su procesador.

+2

Esta es una manera rápida y fácil de acelerar la convolución directa con un núcleo PxP desde operaciones P^2 hasta operaciones 2P. – las3rjock

+0

Mi gaussiano está aplicando en ambas dimensiones, su complejidad de tiempo es 2 * p * M * N, es 20 veces más lento que el de opencv – user25749

4

Para responder a la segunda parte de su pregunta, un desenfoque gaussiano es simplemente la superficie gaussiana 3-d aplicada como un núcleo de convolución sobre la imagen. Wikipedia tiene una gran referencia en el propio algoritmo, pero básicamente, se toma los valores de una curva de Gauss y convertir eso en una matriz cuadrada, y se multiplica por cada píxel de la imagen, por ejemplo:

Kernel:    
[0 1 2 0 0 
1 4 6 4 1  X Iterate over every single pixel in the image 
2 6 10 6 2 
1 4 6 4 1 
0 1 2 1 0] 

(Tenga en cuenta que esto es solo un kernel de muestra, hay eqns muy específicas que, dependiendo de sus variables gaussianas, obtendrá diferentes resultados)

Para responder a la parte del rendimiento de su pregunta, la velocidad total de este algoritmo dependería en algunas cosas, suponiendo una imagen de tamaño constante. Digamos que la imagen es NxM píxeles, y el núcleo de convolución es PxP píxeles. Tendrá que hacer P P N * M operaciones. Cuanto mayor sea P, más operaciones tendrá que hacer para una imagen determinada. Puede hacerse astuto con el algoritmo que usa aquí, haciendo una fila muy específica o matemática basada en columnas.

La implementación también es muy importante. Si quiere ser extremadamente eficiente, probablemente quiera usar las instrucciones más avanzadas que su arquitectura ofrezca. Si está utilizando un chip Intel x86, probablemente quiera obtener una licencia para las primitivas de rendimiento de Intel (IPP) y llamar directamente a esas instrucciones. IIRC, OpenCV hace uso de IPP cuando está disponible ...

También podría hacer algo muy inteligente y trabajar con todos los enteros escalados si el rendimiento de coma flotante en su arquitectura dada es pobre. Esto probablemente aceleraría un poco las cosas, pero buscaría otras opciones antes de seguir por este camino.

2

Intente verificar here. Desea averiguar la matriz gaussiana discreta antes de tiempo, luego conviértala con la imagen.

+0

Muchas gracias, rlbond – user25749

1

Si su kernel de convolución es relativamente grande y está implementando convolución directa, la diferencia de rendimiento puede deberse a que OpenCV está implementando convolución utilizando una transformada de Fourier rápida (FFT).

-1

Odio ser pedante, pero usted está pidiendo un algoritmo, es decir, una secuencia precisa de pasos necesarios para realizar una tarea. Ya tienes el algoritmo gaussiano.Entonces, el punto clave de su pregunta es cuando solicita algo más rápido, que no es lo mismo que pedir un algoritmo.

Para responder a la pregunta más rápida, desea saber cómo OpenCV optimiza su código, que es un tema muy técnico y amplio. Me atrevería a decir que usa lenguaje ensamblador y funciones específicas de la GPU. Comenzaría aprendiendo ensamblaje e investigando el paquete CUDA para aprovechar su GPU.

Cuestiones relacionadas