bicotiDexelHistogram

Figura 2.2.1
 bicotiDexel
             bicotiDexelRegion
             bicotiDexelLabeling
             bicotiDexelHistogram
             bicotiDexelStatistical
             bicotiDexelCurve
                         bicotiDexelCurveOpen
                         bicotiDexelCurveClosed
 

     Clases

bicotiDexelHistogram
HistoInfo
bicotiPixelAttributeSelector
bicotiPixelOperatorUnary

     Templates Clases

CoordType
ColotType
PixelType


class bicotiDexelHistogram
                 < class CoorType , class ColorType, class PixelType = ColorType >



 Public Methods

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 > * )



bicotiDexelHistogram ( bicotiImageImplementation< PixelType > * ptr_image,
                                               bicotiPixelAttributeSelector< ColorType, PixelType > * ptr_att_sel )

        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.



void SetImageImplementation( bicotiImageImplementation< PixelType > *)

        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.



void 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 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( );



void UpdateDexel ( )

        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.



void First ( )

        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.



void Next ( )

        Mueve el "iterador interno" al siguiente punto de la lista.



bool IsDone ( )

        Devuelve true si el "iterador interno" llegó al último lugar de la lista.



unsigned GetCurrentPointsNumber ( )

        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 ).

Figura 2.2.1.6.

Si hago :

         points = histograma.GetCurrentPointsNumber( );

obtengo points = 4, pues hay cuatro puntos con nivel 3, que es el nodo apuntado por el iterador.



ColorType GetCurrentColor ( )

        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.



void SelfFit ( )

        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.



void ModifyPixels ( bicotiPixelOperatorUnary< ColorType > *  ptr_op )

        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.