# Procesamiento de imagenes, reconocer colores.



## felipefacundo (Mar 12, 2007)

Hola a todos, estuve leyendo y no hay ni un tema que hable sobre procesamiento de imagenes.

Alguien sabe si existe algún foro sobre este tema?

bueno para los que saben de C++, les cuento que estoy usando una dll creado por un colega (ingenieria electronica), esta dll tiene varias rutinas de procesamiento de imagenes y no puedo entender para que sirven algunos comandos o como hace para leer los bytes de rojo verde y azul de cada pixel de la imagen usando los lpbits.  

 Aqui les presento una rutina, esta rutina detecta los contornos d ela imagen toma una foto de 360*240 pixeles en formato *.BMP y le aplica un filtro teniendose como resultado la misma imagen.

Esta rutina tambien utiliza dos rutinas que están contenidas en la misma dll que son:
CargarImg(hwnd, hdc): Carga la imagen previamente guardada, por ejemplo en una ventana de visual basic.
DibImg(hdc): Presenta la imagen resultante en una ventana de visual basic.

Estas 2 funciones tambien se las agrego a continuación

Por favor si alguien tiene el tiempo de explicarme como funcionan estas rutinas se los agradecería muchisimo.
Si alguien desea el codigo entero o la dll, me la pide y se la nvio.

Gracias



```
// determinacion de contorno usando convolución
void Edge(HWND hwnd,HDC hdc) 
{
	int m[9]; //vector para almacenar valores de la matriz a convolucionar
	CargarImg(hwnd, hdc);
	hmem1 = GlobalAlloc(GHND, bm.bmWidth*bm.bmHeight);//solicitud de memoria
	lpLum = (LPBYTE)GlobalLock(hmem1);
	hmem2 = GlobalAlloc(GHND, bm.bmWidth*bm.bmHeight);//nueva solicitud de memoria
	lpAux = (LPBYTE)GlobalLock(hmem2);
	for (i=0; i<=(int)(bmi.bmiHeader.biSizeImage-3); i=i+3)
	{
		blue=lpBits[i];
		green=lpBits[i+1];
		red=lpBits[i+2];
		lum=(int)(0.3*red+0.59*green+0.11*blue);
		lpLum[i/3]=(BYTE)lum;
	}
	for (i=0;i<=(int)(bm.bmWidth*bm.bmHeight-1);i++)
	{
		if(((i)%bm.bmWidth!=0) & ((i+1)%bm.bmWidth!=0) &
			(int(i/bm.bmWidth)!=0) & (int(i/bm.bmWidth)!=(bm.bmWidth-1)))
		{
			m[0]=lpLum[i-(bm.bmWidth+1)];// se cargan lso valores
			m[1]=lpLum[i-(bm.bmWidth)];// de la submatriz de imagen
			m[2]=lpLum[i-(bm.bmWidth-1)];// que se procederá
			m[3]=lpLum[i-1];// a convolucionar
			m[4]=lpLum[i];// con la matriz de convolución
			m[5]=lpLum[i+1];//este procedimiento  se hace para toda
			m[6]=lpLum[i+(bm.bmWidth-1)];// la imagen y se desplaza
			m[7]=lpLum[i+(bm.bmWidth)];// esta matriz un pixel cada
			m[8]=lpLum[i-(bm.bmWidth+1)];// oportunidad
			// la ecuació del algoritmo es:
			lpAux[i]=(BYTE)(abs(m[4]*8-m[0]-m[1]-m[2]-m[3]-m[5]-m[6]
				-m[7]-m[8]));
		}
		else
		{
			lpAux[i]=(BYTE)0;
		}
	}
	for (i=0; i<=(int)(bmi.bmiHeader.biSizeImage-3); i=i+3)
	{
		lpBits[i]=lpAux[i/3];
		lpBits[i+1]=lpAux[i/3];
		lpBits[i+2]=lpAux[i/3];
	}
	GlobalUnlock(hmem1);
	GlobalUnlock(hmem2);
	DibImg(hdc);
}


void CargarImg(HWND hwnd, HDC hdc)
{
	GetClientRect(hwnd, &rect);
	// Obtiene dimension de la imagen a procesar,
	// no incluye bordes de ventana.
	hdcaux=CreateCompatibleDC(hdc); // crea ventana virtual
	hbm=CreateCompatibleBitmap(hdc, rect.right, rect.bottom);
	SelectObject(hdcaux, hbm);
	// Copia imagen origen de VB en ventana virtual y lo almacena en el
	// bitmap creado con hbm.
	BitBlt(hdcaux, 0, 0, rect.right, rect.bottom, hdc, 0, 0, SRCCOPY);
	// Obtine información acerca de las características del bitmap virtual
	// y las guarda en una estructura de tipo BITMAP, bm.
	//Sizeof, determina la cantidad de bytes de la estructura del BITMAP.
	GetObject(hbm, sizeof(BITMAP), &bm);
	bmi.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);//bmi
	bmi.bmiHeader.biWidth=bm.bmWidth;
	bmi.bmiHeader.biHeight=bm.bmHeight;
	bmi.bmiHeader.biPlanes=1;
	bmi.bmiHeader.biBitCount=24;// guarda el color en formato de 24 bits
	bmi.bmiHeader.biCompression=0;
	bmi.bmiHeader.biSizeImage=(bm.bmWidth*bm.bmHeight*3);
	bmi.bmiHeader.biClrUsed=0;
	bmi.bmiHeader.biClrImportant=0;
	hmem = GlobalAlloc(GHND, bmi.bmiHeader.biSizeImage);
	// Petición de memoria al sisitema para almacenar información 
	// del color de la imagen
	lpBits = (LPBYTE)GlobalLock(hmem);
	// define vactor del tamaño de memoria reservado anteriormente
	GetDIBits(hdcaux, hbm, 0, rect.bottom, lpBits, &bmi, DIB_RGB_COLORS);
	// carga en lpbits información obtenida mediante escaneo por lineas
	// de la imagen virtual en formato RGB.
}


// rutina para dibujar resultados en un mapa de bits
void DibImg(HDC hdc)
{
	hdcnew=CreateCompatibleDC(hdc);
	//crea dispositivo de contexto compatible
	hbmnew=CreateCompatibleBitmap(hdc, bm.bmWidth, bm.bmHeight);
	//crea dispositivo de contexto compatible con bitmaps
	SelectObject(hdcnew, hbmnew);
	SetDIBits(hdcnew, hbmnew, 0, bm.bmHeight, lpBits, &bmi, DIB_PAL_COLORS);
	//Copia color de un bitmap indep de dispositivo
	BitBlt(hdc, 0, 0, bm.bmWidth, bm.bmHeight, hdcnew, 0, 0, SRCCOPY);
	GlobalUnlock(hmem);
	DeleteDC(hdcnew);
	DeleteDC(hdcaux);
}
```


----------



## Perromuerto (Mar 13, 2007)

Este sitio está en la lamentablemente humanística Wikipedia en español:
http://es.wikipedia.org/wiki/Procesamiento_digital_de_imágenes

En la Wikipedia en inglés que si sirve para algo está esto:
http://en.wikipedia.org/wiki/Image_processing

Sobre los formatos de imágenes:
http://www.htmlgoodies.com/tutorials/web_graphics/article.php/3479931
http://en.wikipedia.org/wiki/Image_processing

Como nunca es bueno reinventar la rueda, sugiero la utilización de librerías
de código ya probadas:
http://directory.fsf.org/libs/image/

Saludos


----------



## MrJavo (Ago 1, 2008)

Hola como les va, estoy trabajando en un proyecto de robotica en el cual el robot tiene que reconocer colores para tomar una determinada accion. 

Tengo una vaga idea de como hacerlo, estuve pensando en la cmucam pero ni idea de como funciona. 

Si tienen alguna idea de como resolver ese problema serian de gran ayuda, tambien como que micro usarian para su desarrollo.

Gracias


----------



## DJ DRACO (Ago 2, 2008)

Yo creo q una vez que obtengas la cam o sistema receptor, deberias pensar en usar un integrado de matrizado de televisores los cuales detectan y mezclan los colores para determinadas funciones, y luego lo del micro programado pra q el robot reaccione ante la vision de colores.


----------



## pitucorto (Ago 13, 2008)

yo estoy interesado en hacer un proyecto similar, pero usando una webcam normalita de 5€... aver que sale


----------



## asherar (Ago 13, 2008)

Una forma elemental sería usar tres filtros de colores Rojo, Azul y Verde, y mandar cada componente a un fotosensor diferente. No necesitas video camara. 
Es como procesan el color los robots que manda la NASA a Marte.


----------



## picrocker (Sep 23, 2008)

y estos filtros como se construyen... seria como un sensor reflectivo... un fotodiodo y un fototransistor....


----------



## asherar (Sep 24, 2008)

Si solo querés jugar un rato, o hacer una prueba de factibilidad, probá con papel traslúcido de colores, 
como los que usábamos de chicos en el jardín de infantes. Como los que se usan en los aparatos de luces 
para discotecas.
Para hacer algo de una calidad mejor, los filtros los tendrías que pedir en una casa de fotografía. 
Si allí no tenés suerte, te queda comprarlos por internet a alguno de los proveedores 
de equipamiento científico: Melles Griott, o similares. 
Seguro que tienen catálogos en línea. 
Si no sos muy exigente con el ancho de banda de cada filtro, no deberían ser caros.


----------



## Fogonazo (Sep 24, 2008)

Kodak, Fujy y otros fabrican los filtros de vidrio coloreado "Calibrados" con los siguientes defectos:
Precio = Robo
Se realizan sobre vidrio de 0,75 mm de espesor = Delicados
Con el tiempo cambian de valor se envejecen

Otra alternativa:
Un sensor con 1 foto-diodo iluminado por reflexión por 3 led´s rojo, azul y amarillo en forma secuencial.
El voltaje obtenido sobre el foto-diodo será función de la componente reflejada en el objeto: distancia y *color*

Defectos:
Bastante complicado
Los led´s poseen frecuencias de emisión muy estrechas lo que traería aparejado un cierto nivel de incertidumbre con colores que NO estén sobre o cerca de la banda de emisión del led

Si el robotito se encuentra conectado a una PC, se puede ver de implementar un programa de análisis de la imagen obtenida por una web-cam pero si es autónomo se complica.


----------



## Luis_electronica (Sep 24, 2008)

Sugiero iluminar con luz lo más blanca posible, leer con cuatro foto transistores. Uno con filtro rojo, uno con filtro verde, uno con filtro azul, uno sin filtro.
Para cada color a reconocer, se cargan los valores de reflexión de los sensores filtrados. 
El sensor sin filtro es para compensar la progresiva pérdida de luz del emisor, el efecto día/noche (luz ambiente) o la sucuedad del vidrio de frente
La lectura se debe hacer con..... Yo la haría con un PLC ó un relé inteligente, con entradas analógicas y posibilidad de programación, ya tienen salidas digitales a bordo, que me darían las salidas procesadas


----------



## fernandoae (Sep 24, 2008)

La solucion para ustedes es un programa llamado "ROBOREALM". Saludos


----------



## asherar (Sep 24, 2008)

Fogonazo dijo:
			
		

> ...
> Otra alternativa:
> Un sensor con 1 foto-diodo iluminado por reflexión por 3 led´s rojo, azul y amarillo en forma secuencial.
> El voltaje obtenido sobre el foto-diodo será función de la componente reflejada en el objeto: distancia y *color*
> ...



Esa idea me parece más que razonable. El defecto que señalas no lo veo impasable. 
De hecho la codificación de colores en los TRC es así, cada color de la paleta se genera con las tres 
componentes RGB (Red-Green-Blue). 
Trabajando por comparación entre la muestra a analizar y la combinación simultánea de la luz de los tres leds, 
cada muestra tendrá una terna RGB que lo represente en tu sistema. 
Si esos valores no coinciden con los estándares es otra cosa, pero eso no hace inviable al método. 
Al contrario, es mucho mejor que el de los filtros.
Lo que queda por trabajar es el método de comparación de los colores: el armado con RGB y el de análisis.
Serviría saber cómo codifican el color los pixels individuales de una CCD.
En cuanto a los filtros, habria que pedir precios en otros lados.

Algunos enlaces a Melles Griott.
Curvas de transmisión de filtros
Descargas (parte)


----------



## fernandoae (Sep 24, 2008)

" la combinación simultánea de la luz de los tres leds,
cada muestra tendrá una terna RGB que lo represente en tu sistema"

Nono...simutanea no! supongamos que usas una LDR como sensor lo correcto es encender un led por vez, de ahi tomar el nivel que se refleja y luego combinar los tres valores, esto para determinar el nivel de cada color.


----------



## asherar (Sep 24, 2008)

Yo tenía en mente la forma como trabaja el pirómetro óptico.
Claro, esto es por reflexión.


----------



## Chico3001 (Sep 25, 2008)

Yo pondria un microcontrolador a analizar una imagen de una webcam... por que lo importante aqui no es velocidad ni reconocer patrones.... asi que un micro convencional de 8 bits debe ser suficiente para obtener una imagen jpg de una webcam y despues usar un algoritmo que identifique el color que estamos buscando basandose en la combinacion de colores RPG, incluso aplicando ecuaciones de distancia podemos saber que tan alejado se encuentra el color que buscamos del centro de la imagen y asi mandar correccion de coordenadas para girar el robot en la direccion correcta

El problema se complicaria si hay varios objetos del mismo color dentro del cuadro de vision de la camara, aun asi podemos discriminar los mas pequeños o memorizar todas las coordenadas encontradas por si se necesita hacer un mapeo de todos los objetos

La ventaja de este metodo es que no requiere filtros, ni luces especiales de cierta longitud de onda, cubre un area muy grande y ademas es economico por que se puede usar una webcam estandar modificada


----------



## asherar (Sep 25, 2008)

Alejandro Sherar dijo:
			
		

> Curvas de transmisión de filtros


Perdón por citarme a mí mismo, pero noten que los filtros de *vidrio coloreado* NO son pasaBANDA, sino pasaBAJOS.

Es decir que no hay tal cosa como un filtro "verde". Este deja pasar también el rojo. 






Lo mismo el filtro azul deja pasar verde y rojo. 





Los filtros quer sí pueden ser pasa banda son los *interferenciales*, por eso son caro$$$.


----------



## rodrigo.sterman (Oct 9, 2010)

hola necesitaria urgente que alguien me ayude en el tema de procesamiento de seniales...la cuestion es la siguiente necesito recibir de la pc por el puerto serie de un microcontrolador 8051f020(silabs) una imagen y poder pasarla completamente a blanco y negro para poder graficarla pixel a pixel por un plotter casero realizado para un proyecto de la universidad...! el plotter consiste solamente de un color q es negro...asi q previo al mapeo de pixeles necesito pasar la imagen a blanco y negro y luego descomponerla en pixeles para pasarla por el puerto serie al micro...la parte de pc tiene q ser en lenguaje c++ y la parte del micro debe ser en c...


ojala alguien pueda ayudarme con esto porque estoy bastante perdido con el tema de tratado de imagenes...


saludos y muchas gracias


----------



## Beamspot (Oct 16, 2010)

Busca 'floid steinberg' o algo similar en la Wikipedia. Puede que te ayude.

Como último recurso, busca 'umbralización'.


----------



## Barzalbo (Sep 9, 2011)

Hola a todos los fans de la electrónica. Yo soy estudiante de ing. civil electrónica, pero por ahora estoy recién en la base y solo se lo basico. Es por esto que quiero su ayuda.Tengo un proyecto que quiero hacer tengo la idea, pero nose como realizarlo, con que micro-controlador, si porfavor me podrian facilitar un circuito que cumpla con los siguientes requisitos:

El proyecto consiste en un aparato q al ponerlo sobre una superficie este se ponga del color de esta superficie. yo tengo vagas ideas de como realizarlo pero necesito de su ayuda, si me podrian facilitar algun circuito.

Se les agradecería mucho
Muchas gracias 
Atte Barzalbo


----------



## maezca (Sep 9, 2011)

... yo lo hice pero en arduino.. para esto usaba un ldr y un led rojo de alta luminosidad para alumbrar la superficie.. entonces ponia el ldr en la entrada analoga del arduino y leia la escala de los colores con esto arme una especie de comparador con IF (programacion) y me salia en el display del arduino el nombre del color.


----------



## Barzalbo (Sep 10, 2011)

oo dale gracias, pero una pregunta ...porque utilizas un led rojo??? puede ser blanco?.
Mi idea es que cuando reconosca el color, se prenda un led de ese mismo color. 
Saludos


----------



## tiopepe123 (Sep 10, 2011)

Puedes hacerlo de varias formas:




1.-Utilizando varios led's de colores y una LDR (Activo)

Simplemente haces una secuencia de colores con los led's y despues procesas la informacion.
Como minimo necesitarias Rojo, Verde, Azul y blanco como calibracion.

2.- Utilizando filtros (papeles de colores)    (Pasivo)
Utilizando 4 ldr, una tapada con el papel rojo, otro azul, verde y uno sin papel para calibre.


3.-Metodo espectrografico
http://sites.google.com/site/anilandro/03800-espectrometria-opt
Este es el sistema mas complejo

4.-Comprar un chip para identificar colores (poco didactico)
http://www.taosinc.com/Productfamily.aspx?id=5&SD=cs

Tienen dos modelos uno utilizando filtro y otro por espectrometria creo recordar, ojo con los encapsulados, son muy dificiles de soldar.

Se utiliza una LDR porque aunque no es muy lineal se parece bastante al ojo humano.

Recuerda que la lrd es una simple resistencia para las medidas se puede utilizar o un simple divisor de tension y mediante una red RC (resistencia y condensador)

Puedes montar un circuito muy simple utilizando un 555 para generar una onda cuadrada y medir con el ordenador la frecuencia segun la luz o conectarlo a unos auriculares para esuchar como varia la frecuencia.


----------



## Barzalbo (Sep 11, 2011)

Hola.... como recien estoy comenzando a entender la electronica nose como realizar lo que me planteaste sobre el reconocimiento de colores. Se lo que son los LDR y su funcion, pero nose como armar este circuito. yo quiero realizar el mas sencillo que en este caso yo creo que es la opcion 2 ( nose si me equivoque), pero  podrias si eres tan amable (y si no te complica) de facilitar el diagrama del circuito con los componentes y modelos de cada componente, para armarlo y ponerlo a prueba.

seria de mucha ayuda. te lo agradeceria mucho


Saludos 
Barzalbo


----------



## maezca (Sep 11, 2011)

exactamente porque uso un led rojo no lo se, lo que si lo sensores comerciales (tipo lego) lo traen asi :S


----------

