La idea del filtro de vecindad es muy simple, se recorre una imagen fuente con una Frame Iterator obteniéndose un Frame para cada pixel de la imagen.Para cada uno de estos frames se evalúa una función de vecindad : Pixel = f ( Frame ) obteníendose el correspondiente pixel de la imagen destino.
Este esquema puede representar un número muy importante
de filtros simplemente con elegir la función de vecindad adecuada.
Un caso particular muy usual es un filtro lineal, para nosotros este caso
se reduce a seleccionar una función de vecindad lineal.
Un problema que surge naturalmente aquí es el
decidir como rellenar el borde de la imagen, es necesario extrapolar pixeles
cuando la vantana ( Frame ) está en el borde. Pero este problema
lo resuelve el propio Frame Iterator, ya que este tiene una estrategia
de extrapolación asociada y sabe lo que poner en el borde.
En resumen la clase bicotiNeighbourFilter que hace le filtrado se relaciona con objetos:
Creamos el nucleo ( kernel ) para la función lineal ( 2D en este caso ) :
bicotiFrame< float > * ptr_ker;
ptr_ker = new bicotiFrame2DInternal< float >( 0, 3 );
Lo creamos
lleno de ceros.
Supongamos
que le hemos seteado los valores deseados al kernel de la función.
Creamos la función lineal :
bicotiNeighbourFunction< float > * ptr_fun;
ptr_fun = bicotiNeighbourFunctionLinear< float >( ptr_ker );
Creamos el filtro :
bicotiNeighbourFilter< float > filter( ptr_ima_dest, ptr_ima_src, 3 , ptr_fun );
Creo la estrategia de extrapolación "cíclica" :
bicotiImageExtrapolationStrategy< float > * ptr_strat;
ptr_strat = new bicotiImageExtrapolationStrategyCiclic< float >;
Se la asigno
al filtro :
filter.SetExtrapolationStrategy( ptr_strat );
y luego filtro :
filter.Apply( );
Todo este preoceso
es bastante complicado debido a la gran flexibilidad que permite, sin embargo
esto puede
hacerse más sencillamente usando la fachada
de NeighbourFilter.
Ver los detalles de la clase en :
bicotiNeighbourFilter