martes, 5 de mayo de 2009

SUSTRACCION DE FONDO - Resta de imagenes

Para detectar el movimiento de los coches tenemos que hacer una serie de operaciones con las imágenes ya hemos convertido las imágenes a grises ahora lo que vamos a hacer es dada una imagen inicial (o casi inicial) le vamos a ir restando las imágenes que capturamos paso a paso, con esto conseguimos la diferencia entre la imagen inicial y la imagen actual, y podremos ver si se ha producido o no un movimiento. SUSTRACCION DE FONDO

Para facilitar la visulizacion de esto umbralizaremos la imagen, es decir, la pasaremos ha binario, conseguiremos una secuencia de imágenes que mostraremos en una ventana en blanco y negro.
Las funciones de opencvl que hemos utilizado en para realizar esto, además de las explicadas en post anteriores, las que he utilizado son:

cvAbsDiff(gray,grayactual,res)
Conseguimos la resta de la imágenes en valor absoluto las 3 imágenes tienes que tener las mismas características, a la imagen inicial (img), además, sólo tienen un canal (son grises)

IplImage*gray;
gray = cvCreateImage(cvSize(img->width, img->height),img->depth,1);

Antes para realizar la resta utilizaba la función cvSub, pero esta no hacia el valor absoluto de las imágenes y podía ser un problema más adelante.

cvThreshold(img,binary,64,255,CV_THRESH_BINARY)

Con esto umbralizamos la imagen, la pasamos a binario.
Uno de los problemas que tenemos con este metodo es que nos encontramos ”Ruido” en las imágenes que obtenemos, por tanto lo siguiente que tenemos que realizar es una gaussiana o algo así de las imágenes obtenidas…

void cvThreshold (const CvArr* src, CvArr* dst, double threshold, double maxValue, int thresholdType)
•Umbraliza la imagen según el método dado en thresholdType. y el umbral es threshold.
•P.ej., CV_THRESH_BINARY para binarizar:
à C(x,y):= si A(x,y) > threshold entonces maxValue sino 0

---------------------------------------- C O D I G O -------------------------------------------

void ToGray (IplImage* img,IplImage *gray){
cvCvtColor(img, gray, CV_BGR2GRAY);
};

void ToBinary (IplImage* img,IplImage *binary){
cvThreshold(img,binary,64,255,CV_THRESH_BINARY);
};

int main (int argc, char **argv){
CvCapture* capture;
IplImage* img;
IplImage* imgactual;
IplImage* gray, * grayactual;
IplImage* res;
IplImage* binary;
int i;

cvNamedWindow("Gris",1);
cvNamedWindow ("Binario",1);

printf("Capture from camera\n");
//capture = cvCaptureFromCAM(0);

capture = cvCaptureFromAVI("uni17.avi");
if(!cvGrabFrame(capture)){
printf( "Can't initialize video capturing\n\n" );
return -1;
}
/* if(!capture){
printf( "Can't initialize video capturing\n\n" );
return -1;
}*/
for (i=0;i<20;i++){ img="cvRetrieveFrame(capture);" i="0;i<20;i++)" img =" cvQueryFrame(" gray =" cvCreateImage(cvSize(img-">width, img->height),img->depth,1);
ToGray(img,gray);

res = cvCreateImage(cvSize(img->width, img->height),img->depth,1);
imgactual=cvCreateImage(cvSize(img->width, img->height),img->depth,img->nChannels);
grayactual = cvCreateImage(cvSize(img->width, img->height),img->depth,1);
binary = cvCreateImage(cvSize(img->width, img->height),img->depth,1);

for(;;){
imgactual=cvQueryFrame(capture);
if (!imgactual)
break;
ToGray(imgactual,grayactual);
cvAbsDiff(gray,grayactual,res);
ToBinary(res,binary);
cvShowImage("Gris", grayactual);
cvShowImage ("Binario",binary);
cvWaitKey(1);
//cvWaitKey(20);
}
cvDestroyAllWindows();
return 0;

2 comentarios:

  1. Estoy deseando que además de utilizar el repertorio de operaciones y funciones de OpenCV te implementes algo a bajo nivel... cambiando los colores de las imágenes, delimitando regiones en la imagen, extrayendo colores de esas regiones,... Ánimo

    ResponderEliminar
  2. ¿qué hacemos con este proyecto?, ¿lo descartamos?

    ResponderEliminar