Visor de imágenes en OpenCv. Hilos en Linux.

Estoy realizando un visor de imágenes en OpenCv, y una de las cosas que quiero lograr es rapidez, que no tenga que esperar entra cambio y cambio de imagen. El problema surge en que la mayoría de fotos que tengo están entorno a las 2 – 3 Mb, por lo cual, lo que estoy implementando es cargar en paralelo a la representación de la primera imagen, un máximo de 4 más. Para ello empleo los hilos:

– De momento la técnica empleada consiste en cargar en memoria un archivo generado mediante una llamada al sistema, y que guarda los paths de todas las imágenes

system("ls *.JPG  >>  ~tmpfiles.txt");

A continuación creo un array de identificadores de hilos:

pthread_t hilos[4];  

También preparo los datos guardandolos en un array de estructuras que contienen el puntero a la IplImage, que será lo que se rellene en el hilo, y el path de una imágen, que es la entrada del hilo.

	pthread_create(&hilos[0], NULL, &thread, &datosi[0]);
	pthread_create(&hilos[1], NULL, &thread, &datosi[1]);
	pthread_create(&hilos[2], NULL, &thread, &datosi[2]);
	pthread_create(&hilos[3], NULL, &thread, &datosi[3]);

Hay que fijarse que a la función pthread_create, se le pasa, la dirección del identificador del hilo, la dirección de la función paralela, en este caso thread, y la dirección de la estructura de datos. Esto es así porque thread es una función de tipo, puntero a void, que recibe también un puntero a void como argumento

void *thread(void *direccion_datos)

Dentro de la función, para poder hacer uso de la estructura de datos debemos hacer un cast, primero definimos un puntero a una estructura de tipo datos_para_hilo (que contiene el IplImage* y el path, como dije antes) y a continuación hacemos el cast para que C++ sepa que tamaño hay que asignar.

	datos_para_hilo *mi_dato;
	mi_dato = (datos_para_hilo *) direccion_datos;

La forma de usar los datos es la típica, modificando los datos, en la estructura de la que hace uso el main:

	mi_dato->img = cvLoadImage (path);
	cout << "Ancho: " << mi_dato->img->width << endl;

Por último, antes de hacer uso de los datos, deberemos esperar a que cada hilo acabe, como tenía los identificadores de los hilos en un array, puedo hacer esto

for(int i = 0 ; i < 4 ; i++)
{
        //Esperamos la finalización de cada hilo
	pthread_join(hilos[i],NULL);                                  
 
       //Los hilos modificaron los datos de datosi    
 	cvShowImage (datosi[i].cadenas, datosi[i].img);	  
	char tecla = cvWaitKey (0);
       //Hay bastantes más opciones quitadas para el post
	switch(tecla)                    
	{
		case 27 : exit(0);
		          break;
	}
  	cvDestroyWindow(datosi[i].cadenas);	 
}

13/10/2009
He subido la versión de desarrollo 0.1 a mi repositorio.
Ya tengo la versión bastante avanzada en cuanto a los hilos, ya no falla al lanzar varios a la vez, y no tiene memory leaks, que era una cosa que si se producían..
Queda pendiente lanzar los hilos mientras se visualiza la imagen 2, porque de momento carga 4 imágenes por vez y se nota.

14/10/2009
Precargo 4 imágenes, y a continuacion la que se va visualizando voy sustituyendola por otro hilo en ejecución… ahora va mucho mejor que antes.
Carga todas las imágenes.
No falla al cargar imágenes que no existen (De hecho no las carga, hago un stats antes)
He comentado bien el código.

Anuncios
  1. Deja un comentario

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

w

Conectando a %s

A %d blogueros les gusta esto: