El siguiente es el fragmento de código a estudiar:
#include <actor_image_2D_double_qt.hpp> typedef bicotiActorImage2DDoubleQT ImaT; void main( int argc, char ** argv ) { ImaT ima1; ima1.BuildMapper(); ima1.GetMapper()->BuildDeviceFile( "imagen.jpg" ); ima1.GetMapper()->BuildMapperJPEGIJG(); ima1.GetMapper()->Read(); ima1.DestroyMapper(); ImaT :: HomologousFactory factory; ImaT :: EventLoopManager event_loop( argc, argv ); ima1.GetActor()->SetSize( ima1.GetImplementation()->GetX0Size(), ima1.GetImplementation()->GetX1Size() ); ima1.GetActor()->SetMainActor( true ); factory.CreateHomologous( ima1.GetActor() ); event_loop.Start(); ima1.BuildOperatorUnary(); ima1.GetOperatorUnary()->Addition( 10 ); ima1.GetActor()->SetVisible( true ); ima1.GetActor()->RefreshImage(); event_loop.Start(); ima1.GetOperatorUnary()->Product( 3 ); ima1.GetActor()->SetVisible( true ); ima1.GetActor()->RefreshImage(); event_loop.Start(); ima1.GetOperatorUnary()->Logarithm(); ima1.GetOperatorUnary()->Product( 35 ); ima1.GetActor()->SetVisible( true ); ima1.GetActor()->RefreshImage(); event_loop.Start(); ima1.DestroyOperatorUnary(); ImaT ima2; ima2.BuildMapper(); ima2.GetMapper()->BuildDeviceFile( "imagen.jpg" ); ima2.GetMapper()->BuildMapperJPEGIJG(); ima2.GetMapper()->Read(); ima2.DestroyMapper(); ima2.BuildOperatorMultiple(); ima2.GetOperatorMultiple()->Append( ima1.GetImplementation() ); ima2.GetOperatorMultiple()->Product(); ima2.DestroyOperatorMultiple(); ima2.BuildOperatorUnary(); ima2.GetOperatorUnary()->Product( 1.0/255 ); ima2.GetActor()->SetMainActor( true ); ima2.GetActor()->SetSize( ima2.GetImplementation()->GetX0Size(), ima2.GetImplementation()->GetX1Size() ); factory.CreateHomologous( ima2.GetActor() ); event_loop.Start(); };
El primer bloque de código al igual que los ejmplos
previos carga sobre una imagen de pixel double, la imagen del archivo
imagen.jpg.
En el segundo bloque se crea un factory y un event
loop, se fijan las dimensiones del actor (en este caso la ventana de
visualización) para que coincidan con las de la imagen. Se fija
el actor como actor principal, de esta forma al cerrar la ventana, además
de hacer invisible al actor, se detiene el loop de eventos, volviendo la
aplicación a su curso secuencial.
Una vez cerrada la ventana, se construye una fachada
para operaciones de la imagen en si misma y se suma 10 a todos los pixeles
de esta. Se vuelve a hacer visible el actor, se refrescan los cambios en
el homólogo y se vuelve a lanzar el loop de eventos.
Sumando 10 a la original
En la imagen anterior se ve la saturación en algunos de los pixeles, especialmente en la esquina inferior izquierda. Cerrando la ventana nuevamente, se multiplican todos los pixeles por 3 y se refrescan los cambios, para ver la imagen inferior ahora completamente saturada.
Imagen de prueba
En tercer lugar se aplica el logaritmo a cada pixel. Esto reduce demasiado el brillo de la imagen y en consecuencia se multiplica toda por 35 para volver a recuperarlo. Es interesante destacar que de haber usado pixels unsigned char, el resultado tendría un puñado de niveles de gris debido a la discretización de los niveles.
Imagen de prueba
Seguidamente volvemos a leer la imagen ahora sobre ima2, se normalizan los niveles de gris, se multiplican ima1 e ima2 volcando el resultado en ima2. Mostramos ima2 y esperamos que la ventana sea cerrada para terminar la aplicación.
Imagen de prueba