Filtros 2D FIR (Finite Impulse Response) Los filtros lineales FIR en 2D representan sistemas lineales invariantes a corrimientos (linear location invariant, or shift invariant) y tienen una región de soporte finito. Sea I(x,y) una imagen 2D definida en 0 ≤ x < N, 0 ≤ y < M, es decir que tiene dimensiones (volumen) N×M (= total de pixeles). Sea la región de soporte (o ventana) un rectángulo: W = {(x,y): −Wx ≤ x ≤ Wx , −Wy ≤ y ≤ Wy }. Notar que el rectángulo tiene un total de card(W) = (2Wx+1)×(2Wy+1) pixeles, y puede también describirse (caso continuo o discreto) como el producto cartesiano de dos intervalos cerrados: W = [−Wx ,Wx] × [ −Wy ,Wy]. A veces se define el punto x,y en una esquina de W, y se usa el producto cartesiano de intervalos semiabiertos: W = [0,Wx) × [0,Wy), siendo en este caso card(W) = Wx Wy Definimos la convolución contínua como: I conv ( x, y ) = I ( x, y ) ∗ w( x, y ) = ∫∫ I ( x − x ', y − y ') w( x ', y ')dx ' dy ' W = ∫∫ w( x − x ', y − y ') I ( x ', y ')dx ' dy ' W notar la simetría mediante cambio de variable. En otras notas, la respuesta a impulso o ventana w se escribió como función h. La convolución discreta, con (x,y) ∈ Z2, la definimos como: Jorge A. Márquez Flores - Instrumentación y Señales -CCADET-UNAM © Copyright 2006 I conv (m, n) = I (m, n) ∗ w(m, n) = = Wx Wy ∑ ∑ I (m − i, n − j ) w(i, j ) i =−Wx j =−Wy Wx Wy ∑ ∑ w(m − i, n − j ) I (i, j ) i =−Wx j =−Wy Los valores w(x,y) son los pesos de ponderación (en contínuo es función de ponderación). Cuando la ventana es simétrica respecto a m,n, la convolución coincide (tras un cambio de variable) con el promedio móvil (moving average), como caso particular de w(x,y)=1/N, en todo W, donde N= card(W). En general se normaliza la ventana (kernel, núcleo o mascarilla) de convolución (conjunto de valores w), para que satisfagan: Wx Wy ∑ ∑ w(i, j ) =1 i =−Wx j =−Wy Es común que se diseñen ventanas simétricas en las 2 variables, de modo que w(−x, y)= w(x, y), w(x, −y)= w(x, y) y en consecuencia w(−x, −y)= w(x, y), etc. De allí la conveniencia de centrar los índices en 0,0 por cada punto de I(x,y). La convolución discreta, usando la notación de subíndices discretos (enteros), i, j se escribe también como: I ij ∗ wij = Wx Wy ∑ ∑ n =−Wx m =−Wy I i −n , j −m wnm Algunos autores usan ** y *** para denotar convolución en 2D y en 3D respectivamente. Otros usan el símbolo ⊗ (y también hay la opción de poner ⊗⊗ y ⊗⊗⊗ para convolución 2D, 3D, pero el símbolo ⊗ también es usado para denotar el producto de Krönecker, o inclusive el producto tensorial). Nosotros usaremos simplemente * (salvo en programas, donde significa producto y Jorge A. Márquez Flores - Instrumentación y Señales -CCADET-UNAM © Copyright 2006 “pointer”, según el contexto), y reservamos ⊗ para los productos de Krönecker, y el tensorial: usaremos × para multiplicación escalar (símbolo explícito), vectorial y producto cartesiano. A continuación listamos una función en lenguaje C para calcular convoluciones en 3D. Los nombres de variables image3d y matrix3d son tipos definidos en algún archivo include (.h). /********************************************************** Subroutine for calculating the 3D convolution between the input image sequence and the linear FIR filter impulse response. (linear FIR filter output calculation) The filter is not recursive. Odd filter window dimensions are assumed, to ensure symmetry. Parameters a: input image sequence b: output image sequence Ll, N1, M1: start coordinates (frame, row, column) L2, N2, M2: end coordinates (frame, row, column) hcoe: FIR filter impulse response 3D matrix LW, NW, MW FIR filter window dimensions (frames, rows, columns) (NOTE: they must be odd numbers) **********************************************************/ int conv3( image3d a, image3d b, matrix3d hcoef, int L1, int N1, int L2, int N2, int M2, int LW, int NW, int MW) { LW2=LW/2; NW2=NW/2; MW2=MW/2; Lmin=U+LW2; Lmax=L2-LW2; Nmin=N1+NW2; Nmax=N2-NW2; Mmin=Ml+MW2; Mmax=M2-MW2; /* Calculation of the output image sequence */ for (z=Lmin; z<Lmax; z++) /* frames */ for (y=Nmin; y<Nmax; y++) /* rows */ for (x=Mmin; x<Mmax; x++) /* columns */ { for (k=O, zz=z+LW2; k<LW; k++, zz--) for (j=O, yy=y+NW2; j<NW; j++, yy--) for (i=O, xx=x+MW2; i<MW; i++, xx--) b[z][y][x]+=a[zz][yy][xx]*hcoef[k][j][i]; } } /*** endof conv3() ***/ Jorge A. Márquez Flores - Instrumentación y Señales -CCADET-UNAM © Copyright 2006