Procesamiento de imagenes, reconocer colores.

#1
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


Código:
// 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);
}
 
Última edición por un moderador:
#2
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
 
#3
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
 
#4
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.
 
#6
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.
 
#8
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

Exorcista & Moderador eventual
#9
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.
 
#10
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
 
#12
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
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
...
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)
 
#13
" 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.
 
#15
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
 
#17
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
 
#19
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
 
#20
... 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.
 

Temas similares

Arriba