bicotiDexelHistogram
HistoInfo
bicotiPixelAttributeSelector
bicotiPixelOperatorUnary
Templates Clases
CoordType
ColotType
PixelType
class bicotiDexelHistogram
< class CoorType , class ColorType, class PixelType = ColorType >
bicotiDexelHistogram
( bicotiImageImplementation< PixelType > *, bicotiPixelAttributeSelector<
ColorType, PixelType > * )
void
SetImageImplementation( bicotiImageImplementation<
PixelType > * )
void
UpdateImageImplementation ( )
void
UpdateDexel ( )
void
First ( )
void
Next ( )
bool
IsDone ( )
unsigned
GetCurrentPointsNumber ( )
ColorType
GetCurrentColor ( )
void
SelfFit ( )
voidModifyPixels
( bicotiPixelOperatorUnary< ColorType > * )
Constructor
del Dexel.
Los parámetros
que le paso son :
ptr_image -- puntero a la imagen a la que se asocia el dexel.
ptr_att_sel -- puntero al seleccionador de atributo por el cual agrupo
los pixeles.
Por ejemplo, si quiero crear un histograma para una imagen 2D 10 x 10 de enteros.
bicotiImageImplementation<int> * ptr_image;
ptr_image = new bicotiImageImplementation<int>( 0, 10 , 10 );
Creo el attribute
selector None, que toma como atributo el propio color. Es el caso más
usual
en una imagen
monocromática.
bicotiPixelAttributeSelector< int >* ptr_att_sel;
ptr_att_sel = new bicotiPixelAttributeSelectorNone< int >;
Ahora puedo crear el Dexel.
bicotiDexelHistogram<
bicotiCoordinate2D<INTEGER>, int >
histogram( ptr_image, ptr_att_sel );
El primer
template es el tipo de coordenadas que se guardan y el segundo el tipo
del atributo.
En este caso
ColorType = PixelType = int. El atributo es del mismo tipo que el pixel,
por lo que no
es necesario
explicitar el tercer template.
Un ejemplo
más complejo podría ser cuando quiero hacer un histogram
del verde en una imagen
RGB de enteros.
bicotiImageImplementation< bicotiRGB<int> > * ptr_image;
ptr_image = new bicotiImageImplementation<int>( def_pix, 10 , 10 );
El selector de atributos es el que selecciona el verde.
bicotiPixelAttributeSelector< int >* ptr_att_sel;
ptr_att_sel = new bicotiPixelAttributeSelectorGreen< int >;
Ahora puedo crear el Dexel.
bicotiDexelHistogram<
bicotiCoordinate2D<INTEGER>, int , bicotiRGB< int >>
histogram( ptr_image, ptr_att_sel );
En este caso
bicotiCoordinate2D< INTEGER > es una imagen 2D
ColorType = int.
PixelType = bicotiRGB< int >.
Ver ejemplos para casos más complejos.
Esta es una función común a todos los Dexels. Se declara virtual en bicotiDexel y se implementa en las clases derivadas. Ver SetImageImplementation en bicotiDexel.
Esta función permite asignar la referencia a una imagen luego de construido el dexel. Tiene sentido para algunos dexels que se pueden construir sin referencia y luego asignarla. No tiene mucho sentido para el histograma.
Esta
es una función común a todos los Dexels. Se declara virtual
en bicotiDexel y se implementa en las clases derivadas. Ver UpdateImageImplementation
en bicotiDexel.
Muchos algoritmos
modifican el histograma y reflejan esos cambios sobre la imagen. Esta función
permite hacer la actualización.
Si modifico el histograma de una imagen, los cambios no se veran reflejados hasta que no haga :
histograma.UpdateImageImplementation( );
Esta es una función común a todos los Dexels. Se declara virtual en bicotiDexel y se implementa en las clases derivadas.Ver UpdateDexel en bicotiDexel.
Si se hace un cambio en la imagen, el dexel no se modificará automáticamente, debo llamar a esta función para que el dexel se reconstruya.
El histograma
es una lista, por lo que es razonable que tenga algunas funciones para
iterar sobre ella.
Esta función ubica al "iterador interno" en el
primer lugar de la lista.
Mueve el "iterador interno" al siguiente punto de la lista.
Devuelve true si el "iterador interno" llegó al último lugar de la lista.
Devuelve el número de pixeles de la imagen que tienen el atributo actualmente apuntado por el iterador.
Por ejemplo si el histogrma es como se muestra en la figura 2.2.1.6, donde la imagen es 2D de enteros y el atributo es el nivel de gris ( el valor del pixel ).
Si hago :
points = histograma.GetCurrentPointsNumber( );
obtengo points = 4, pues hay cuatro puntos con nivel 3, que es el nodo apuntado por el iterador.
Devuelve el valor del atributo actualmente apuntado por el iterador.
En el ejemplo de la figura 2.2.1.6. Si hago :
nivel = histograma.GetCurrentColor( );
obtengo nivel = 3, que es el nivel de gris actualmente apuntado.
Con estas funciones puedo recorrer el histograma y obtener
el atributo y la cantidad de pixeles que tiene dicho atributo para cada
nodo.
Basta con hacer un loop del tipo :
for ( histograma.First(
) ; ! histograma.IsDone( ) ; histograma.Next( ) )
{ atributo = histograma.GetCurrentColor( );
frecuencia = histograma.GetCurrentPointsNumber( ); }
Ver ejemplos para más detalles.
Cuando
se modifica el histograma, es muy probable que quede desordenado o que
algunos nodos con el mismo atributo aparezcan repetidos. Esta función
permite reordenarlo y eliminar estas distorsiones, de alguna forma se puede
decir que se reconstruye el histograma, pero sin mirar a la imagen.
El conveniente hacer un SelfFit siempre que se hizo una
modificación en el histograma.
Esta
función le aplica el operador apuntado por ptr_op a cada uno de
los puntos de la lista.
Se recalcula cada nuevo atributo como : att_nuevo
= ( * ptr_op ) ( att_actual )
con lo que tendré un histograma diferente al original.
Para ver los cambios en la imagen hay que hacer una actualización
con la función UpdateImageImplementation.
Un ejemplo sencillo sería por ejemplo multiplicar
por dos a cada atributo. Es una forma extraña de multiplicar a la
imagen por un escalar pero sirve par ilustrar el uso.
Suponiendo que tengo un dexelhistogram para una imagen
2D de enteros con el nivel de gris como atributo, histogram.
Creo el operador de multiplicación ( por 2 ):
bicotiPixelOperatorUnary<int>
* ptr_op;
ptr_op
= bicotiPixelOperatorUnaryProduct<int>( 2 );
Luego multiplico:
histogram.ModifyPixels(
ptr_op );
histogram.SelfFit(
);
Es conveniente hacer un SelfFit para eliminar distorsiones,
aunque es claro que en este caso no es necesario.
Luego hay que actualizar la imagen.
histogram.UpdateImageImplementation( );
Ver ejemplos para casos más complejos.