martes, 9 de febrero de 2010

POLIGONOS

Para hacer el estudio de las imganes, lo primero que tenemos que hacer es delimitar las zonas donde se pueden aparcar, para realizar esto he dibujado un rectángulo donde si se puede aparcar.
Las funciones que he estudiado para son las siguientes como siempre de mas fácil y más dificil...


// Dibujar un cuadro con líneas rojas, de 1 de ancho entre (100,100) y (200,200)
cvRectangle(imgactual, cvPoint(100,100), cvPoint(200,200), cvScalar(255,0,0), 1);
// Dibujar un círculo en (100.100) con un radio de 20. Utilice las líneas verdes de ancho 1
cvCircle(img, cvPoint(100,100), 20, cvScalar(0,255,0), 1);
// Dibujar una línea roja de 1 de ancho entre (100,100) y (200,200)
cvLine(img, cvPoint(100,100), cvPoint(200,200), cvScalar(0,0,255), 1);


Una vez probadas estas funciones, no cumplian los requisitos porque no necesitaba un simple rectangulo sino un poligono, he pasado a la siguiente funcion con la que podemos conseguir cualquier poligono.

CvPoint curve1[]={310,240,400,240,310,135,270,135};
CvPoint* curveArr[1]={curve1};
int nCurvePts[1]={4};
int nCurves=1;
int isCurveClosed=1;
 
cvPolyLine(img,curveArr,nCurvePts,nCurves,isCurveClosed,cvScalar(0,255,255),1);

El resultado es el siguiente:

Los ejemplos para hacer los poligonos están sacados de:

VUELTA AL TRABAJO

Aqui estoy despues de mucho, pero que mucho tiempo, terminando asunto pendientes. Si aunque no os lo creais voy a continuar trabajando en el PFC.
Ahora mismo me estoy volviendo a poner al dia.
Pronto tendreis noticias mias, porque mis "vacaciones" han terminado.

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;

martes, 28 de abril de 2009

ESCALA DE GRISES

El siguiente paso para desarrollar el proyecto es averiguar si existe movimiento en las imágenes que recibimos o no. El primer paso que vamos a dar es convertir, las imágenes dadas en escala de grises. Para conseguir la hacer esto lo hemos realizado de dos maneras:

He accedido a las características de la imagen. Las imágenes tienen unas características, por ejemplo, dado un tipo de datos iplImage (img) las características de la altura y al anchura vienen definidas como img->width y como img->height.

He recorrido pixel a pixel la imagen con dos bucles anidados, he ido cambiando el color que muestra este por el gris. Para conseguir el gris he hallado la media de los 3 canales.

void RGB2GRAY(IplImage *img){
int i,j;
double media;
//printf("%d\n",img->height);
//printf("%d\n",img->width);
for(i=0;iheight;i++){
for(j=0;jwidth; j++ ){
CvScalar s;
s=cvGet2D(img,i,j); // obtenemos el valor en el píxel (i,j)
//printf("B=%f, G=%f, R=%f\n",s.val[0],s.val[1],s.val[2]);
media=(s.val[0]+s.val[1]+s.val[2])/3;
s.val[0]=media;
s.val[1]=media;
s.val[2]=media;
cvSet2D(img,i,j,s);
}
}
};

Otra manera para resolver esto es con la función predefinida por opencv cvcvtcolor.
Uso de la conversión OpenCV:

cvCvtColor(cimg,gimg,CV_BGR2GRAY);
El uso de un directo de la conversión:
for(i=0;iheight;i++) for(j=0;jwidth;j++)
gimgA[i][j]= (uchar) (cimgA [i] [j]. b * 0,114 +
cimgA[i][j].g*0.587 + cimgA[i][j].r*0.299);
Convertir entre espacios de color:
cvCvtColor(src,dst,code); / / src -> dst
code = CV_2
/ = RGB, BGR, GRAY, HSV, YCrCb, XYZ, Lab, Luv, HLS
por ejemplo: CV_BGR2GRAY, CV_BGR2HSV, CV_BGR2Lab

int main (int argc, char **argv){
CvCapture* capture = 0;
IplImage* img = 0;
IplImage* gray;
int num=0;

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

printf("Capture from camera\n");
capture = cvCaptureFromCAM(0);
if(!capture){
printf( "Can't initialize video capturing\n\n" );
return -1;
}
img=cvQueryFrame( capture );
gray = cvCreateImage(cvSize(img->width, img->height),IPL_DEPTH_8U,1);
for(;;){
img=cvQueryFrame( capture );
if (!img)
break;

cvShowImage( "Video", img );
//RGB2GRAY(img);
cvCvtColor(img, gray, CV_BGR2GRAY);
cvShowImage ("Gris",gray);
cvWaitKey(1);
num++;
if (num==100){
cvReleaseCapture(&capture);
return 0;
}
}
cvDestroyAllWindows();
return 0;
}

miércoles, 22 de abril de 2009

Mostra Video

FUNCIONES UTILIZDAS:
cvCaptureFromAVI
CvCapture* cvCaptureFromAVI( const char* filename );
filename: Nombre del archivo AVI.
La función cvCaptureFromAVI asigna y inicializa la estructura CvCapture para leer la secuencia de vídeo desde el archivo de AVI especificado.
Después de que el asignado estructura ya no se utiliza más que deben ser puestos en libertad por cvReleaseCapture función.
cvGrabFrame
int cvGrabFrame (* CvCapture captura);
La función cvGrabFrame grava el frame de la cámara o AVI. El frame gravado se almacena internamente. El propósito de esta función es gravar el marco rápido lo que es importante para la sincronización en el caso de la lectura de varias cámaras simultáneamente. Para conseguir el acceso frame se debe llamar a cvRetrieveFrame.
-------------------------------- CODIGO -----------------------------------
----------------------------------------------------------

#include
#include
#include
#include
int main (int argc, char **argv){
CvCapture *capture;
IplImage *img = 0;
int i=0,c;
capture = cvCaptureFromAVI("videoo.avi");
if(!cvGrabFrame(capture)){ // capture a frame
printf("Could not grab a frame\n");
printf("%p\n",capture);
getchar();
exit(-1);
}
cvNamedWindow( "VideoCaptura",1);
for(i=0;i<900;i++){
cvGrabFrame(capture);
img=cvRetrieveFrame(capture); // retrieve the captured frame
cvShowImage("VideoCaptura",img);
c = cvWaitKey(20);
}
cvQueryFrame(capture); // this call is necessary to get correct
// capture properties
int frameH = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT);
int frameW = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH);
int fps = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_FPS);
int numFrames = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_COUNT);
printf("\nFrame size= %i x %i FPS= %i Frame number= %i",frameW,frameH, fps, numFrames);
//Releasing the capture source:
cvReleaseCapture(&capture);
getchar();
//cvReleaseImage(&img);
cvDestroyWindow("VideoCaptura");
return 0;
}
Pd: Podria de donde he sacado el codigo pero no me acuerdo

SOLUCION: Para mostrar video

Después de darme de tortazos con una pared una y otra vez, abriendo un vídeo. Sólo me planteaba una cosa, pero si he copiado un código de alguien que le funciona?¿? A un compañero mio le funciona este código?¿? QUE PASA?¿?
Bueno por aburrimiento y desesperación encontré un foro de opencv en español, y me pregunté si era a la única cenutria que no podía abrir el vídeo. ¡¡¡Pues NO solo más de uno y de dos!!!
LA SOLUCIÓN INSTALAR UNOS SIMPLES Y MISEROS CODECD...
Con la boca abierta me dejo la solución pero funcionó

Foro Opencv en español:
http://tech.groups.yahoo.com/group/OpenCVenEspanol/

Instalación de codec ffdshow:
http://www.free-codecs.com/FFDShow_download.htm

ABRIR WEBCAM

Después haber escrito la ultima entrada del blog, decidí continuar con lo que funcionaba y "rayarme" con lo que no funcionaba, por eso volvimos a instalar la biblioteca 1.1.

El primer programita que hice fue abrir la webcam y mostrar 1OO frames en una ventana, para que esto funcione he utilizado de opencv las siguientes librerias:

cvNameWindow: crea la ventana
int cvNamedWindow (const char * name, int flags CV_WINDOW_AUTOSIZE =);
name: Nombre de la ventana que se utiliza como identificador de la ventana y aparece en el titulo de la ventana.
flags: caracteristicas de la ventana.
Creado ventanas son mencionados por sus nombres. Si la ventana con ese nombre ya existe, la función no hace nada.
---------------------------------------------------------------------------------- cvDestroyWindow Destruye una ventana
void cvDestroyWindow (const char * name);
name: Nombre de la ventana, para ser destruidos.
----------------------------------------------------------------------------------
cvWaitKey Espera a que se pulsa una tecla
int cvWaitKey (int delay = 0);
delay: retraso en milisegundos
Espera a que se pulse un tecla indefinidamente. Devuelve el código de la tecla pulsada o -1 si no se presiona una tecla en el tiempo especificado.
----------------------------------------------------------------------------------
cvShowImage Muestra la imagen en la ventana especificada
void cvShowImage( const char* name, const CvArr* image );
name: Nombre de la ventana.
imagen: Imagen que se muestra.
La función cvShowImage muestra la imagen en la ventana especificada. Si la ventana se ha creado con CV_WINDOW_AUTOSIZE entonces la imagen se muestra con su tamaño original, de lo contrario la imagen se escala para ajustarse a la ventana.
-----------------------------------------------------------------------------------
CvCapture Estructura de la captura de vídeo
typedef struct CvCapture CvCapture;
La estructura CvCapture no tiene interfaz pública y sólo se utiliza como parámetro para la captura de funciones de vídeo.
-----------------------------------------------------------------------------------
cvCaptureFromCAM
Asigna CvCapture estructura y se une a la cámara de vídeo
CvCapture* cvCaptureFromCAM( int index );
index índice de la cámara que se va a utilizara, si sólo hay una cámara o no importa que cámara se va a utilizar, se puede poner -1.
Cuando no se valla a utilizar mas estructura CvCapture debe ser libertada por la funcion cv ReleaseCapture.
------------------------------------------------------------------------------------
cvReleaseCapture
libera la estructura Capture, se utiliza la estructura es llamada con un ccvCaptureFromAVI o cvCaptureFromCAM.
--------------------------------------------------------------------------------------
cvQueryFrame
Grava y devuelve un cuadro de la cámara o AVI.
IplImage* cvQueryFrame( CvCapture* capture );
capture captura
CvCapture proviene de la cámara o el archivo AVI.
La función cvQueryFrame
grava un fotograma de la cámara o AVI y devuelve el puntero a la imagen. En realidad esta función pide sucesivamente cvGrabFrame y cvRetrieveFrame. La imagen devuelta no debe ser liberado por el usuario.

-----------------------CODIGO----------------------
-----------------------------------------


#include
#include
#include
#include
int main (int argc, char **argv){
CvCapture* capture = 0;
IplImage* frame = 0;
int nframes=0;
cvNamedWindow( "VideoCaptura", 1 );
printf("Capture from camera\n");
capture = cvCaptureFromCAM(0);
if(!capture){
printf( "Can't initialize video capturing\n\n" );
return -1;
}
for(;;){
printf("%d\n",nframes);
frame=cvQueryFrame( capture );
if (!frame)
break;
cvShowImage( "VideoCaptura", frame );
cvWaitKey(1);
nframes++;
if (nframes==100){
cvReleaseCapture(&capture);
return 0;
}
}
cvDestroyWindow("VideoCaptura");
return 0;
}