Archivos para 15 septiembre 2009

Protegido: Servidor de versiones

Este contenido está protegido por contraseña. Para verlo introduce tu contraseña a continuación:

Anuncios

Deja un comentario

Detección de bordes

La detección de bordes se basa en los cambios de intensidad entre un pixel y su vecindario.
Para ello empleamos un filtro de matriz. Las matrices más usadas corresponden a la matriz de Laplace y su aproximación
Una matriz de Laplace, tiene la siguiente forma:

1 1 1
1 -8 1
1 1 1

Ahora tenemos que tener en cuenta que el color blanco se corresponde a 25 y el ne  gro a 0, y tenemos algo tal que:

255 255 255 Que lo multiplicamos por la matriz 255 255 255
255 255 255 255 -2040 255
0 0 0 0 0 0

Una vez hayamos hecho esto, sumamos todos los valores, y hayamos su valor absoluto, 765 en este caso.
El cual umbralizaremos (lo normal es entre 20 y 30) y diremos que el punto denota un borde

La info la he extraido y resumido a partir de aquí:
http://vidaartificial.com/index.php?title=Una_introduccion_a_la_Vision_Artificial_%28Generation5.org%29

#include "program.h"
#include <fstream>
#include <vector>

using namespace std;

/***********************************************
        Detector de Bordes:
                                1   1   1
Aplicamos una mascara tal que:  1  -8   1
                                1   1   1

sumamos los puntos y si esta por encima de un umbral
ese punto nos mola.

OpenCv usa un puntero, lo cual nos complica un poco la cosa
mi idea es, defino la matriz del mismo tamañao, y la inicializo
y entonces ya puedo acceder dentro de un bucle for
***********************************************/

int main (int argc, char **argv)
{

 IplImage *entrada = cvLoadImage(argv[1]);              //Leemos la entrada

 int alto    = entrada->height;                         //guardamos las propiedades
 int ancho   = entrada->width;
 int canales = entrada->nChannels;

 vector <int> columna;                                   //en cada columna vamos metiendo los datos, y luego todos los metemos en una fila
 vector <vector <int> > fila;                            //Luego la fila se compone de elementos columnas
 vector <vector <vector <int> > > img_canales;           //y un conjunto de filasxcolumnas, forman un canal

for(int z = 0; z < canales; z++)
{
     for(int f = 0; f < alto ;f++)
     {
        for(int c = 0; c < ancho ; c++)              {               columna.push_back(c);              }         fila.push_back(columna);         columna.clear();      }      img_canales.push_back(fila);    fila.clear();     }     /*      AHORA QUEDA COPIAR LOS DATOS EN LA MATRIZ  El parametro widthStep, indica el número de bytes utilizados para representar cada fila de una imagen.  Una imagen de anchura 101 píxeles, de tipo byte con un widthStep igual a 104, codificará cada fila como una ristra de 104 bytes, de los cuales los 101 primeros se corresponderán con los píxeles de cada fila. ¿Y los 3 restantes, en este ejemplo? OpenCv los rellena con ‘/0′. En OpenCV, el campo widthStep siempre tiene que ser múltiplo de 4. Siempre. Así pues, una imagen (tanto en color como en escala de grises) de tipo byte con anchura de 102 píxeles tendrá un widthStep con valor 104, exactamente el mismo que para otra imagen diferente de anchura 103 ó 104. Esto es así porque la mínima cantidad de memoria que se puede reservar es de 4 bytes en algunos formatos de imagen. */  /*          este trozo de codigo invierte una imagen*/ int step      = entrada->widthStep;
uchar* data      = (uchar *)entrada->imageData;

  for(int i=0;i<alto;i++)
     for(int j=0;j<ancho;j++)
        for(int k=0;k<span 				data-mce-type="bookmark" 				id="mce_SELREST_start" 				data-mce-style="overflow:hidden;line-height:0" 				style="overflow:hidden;line-height:0" 			></span><canales;k++)
            data[i*step+j*canales+k]= 255-data[i*step+j*canales+k];

 cvNamedWindow("kk");
 cvShowImage("kk",entrada);
 cvWaitKey(0);

 return 0;
}

Deja un comentario

Sensor por distancia por ultrasonidos

Sistema de medida de distancia por medio de UltraSonidos y un AT98C51RD2

Deja un comentario

El editor de texto: Gedit

Gedit otorga una serie de plugins, que hacen que la labor de programar sea más facil:
– plugins de gedit instalables mediante aptitude
– Tema DarkMate
– Complementos:
– Auto Completion Plugin: Para auto completar usando el tabulador como en una consola linux
– Comentar código: Permite comentar bloques de código como en otros lenguajes
– Completar paréntesis.
– Espacios inteligentes
– Herramientas externas
– Sangrar lineas
– Symbol Browser: muestra las clases, funciones miembros, etc.. en un panel a la derecha
– Terminal empotrado

En ver:
– Activar ajuste de Texto
– Mostrar números de linea
– Resaltar linea actual
– Resaltar la pareja del corchete

Editor:
– Ancho del tabulador: 4
– Insertar espacios en lugar de tabuladores
– Activar sangría automática

Y he aquí una captura, no se puede observar el autocompletar, porque al pulsar capturar pantalla se borra pero para hacerse una idea vale:
Gedit

Deja un comentario

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.

Deja un comentario