CODIGO GEOFACEDETECT ● Variables globales a crear fuera de los métodos para su uso en todo el programa. int dist; IplImage* frame = 0; const int MAX_COUNT = 20; int count = 0; CvCapture* capture = 0; int p_fijaX,p_fijaY; ● Método con el que calcular lel cambio de coordenadas del primer punto(count==1). void movimiento1(int count, double P1, double P2) { if (count == 1) { origx = (int)P1; origy = (int)P2; rotate = 1; motion2(p_fijaX,p_fijaY); printf("\n%d, %d, %d",count, origx, origy); } else { rotate = 0; } } ● Método con el que en función de la distancia entre P1 y P2(la distancia entre los puntos) realice el aumento o reducción de los músculos requeridos. void movimiento(double P1, double P2) { int Y1;int Y2; int resultY; Y1=(int)P1; Y2=(int)P2; resultY= Y2-Y1; // // // printf("\nY1= %i",Y1); printf("\nY2= %i",Y2); printf("\nD= %i",distancia); printf("\nY= %i",resultY); for(m=0;m < 2;m++){ if(resultY>distancia){ face->muscle[m]->mstat += 0.1 ; activate_muscle ( face, face->muscle[m]->head, face->muscle[m]->tail, face->muscle[m]->fs, face->muscle[m]->fe, face->muscle[m]->zone, 0.03 ) ; glutPostRedisplay(); } if(resultY<distancia){ face->muscle[m]->mstat -= 0.1 ; activate_muscle ( face, face->muscle[m]->head, face->muscle[m]->tail, face->muscle[m]->fs, face->muscle[m]->fe, face->muscle[m]->zone, -0.03 ) ; glutPostRedisplay(); }} } ● Método con el calcular la rotación del “geoface” en base a los calculo obtenidos con “movimiento1”. void motion2 ( int x, int y ) { if (rotate) { spinyface = ( spinyface + ((x - origx)/10) ) % 360 ; spinxface = ( spinxface + ((y - origy)/10) ) % 360 ; origx = x; origy = y; glutPostRedisplay(); } } ● Método que será llamado por glutIdleFunc, que es llamado todo el rato gracias al glutMainLoop(), en el que se refresca la imagen capturada por la cámara y se actualiza la posición de los puntos en cada frame tomado. void prIdle() { int i, k, c; double PY1,PY2,PX1,PX2; frame = cvQueryFrame( capture ); if( !image ) { image = cvCreateImage( cvGetSize(frame), 8, 3 ); image->origin = frame->origin; grey = cvCreateImage( cvGetSize(frame), 8, 1 ); prev_grey = cvCreateImage( cvGetSize(frame), 8, 1 ); pyramid = cvCreateImage( cvGetSize(frame), 8, 1 ); prev_pyramid = cvCreateImage( cvGetSize(frame), 8, 1 ); points[0] = (CvPoint2D32f*)cvAlloc(MAX_COUNT*sizeof(points[0][0])); points[1] = (CvPoint2D32f*)cvAlloc(MAX_COUNT*sizeof(points[0][0])); status = (char*)cvAlloc(MAX_COUNT); flags = 0; } cvCopy( frame, image, 0 ); cvCvtColor( image, grey, CV_BGR2GRAY ); if( night_mode ) cvZero( image ); if( count > 0 ) { cvCalcOpticalFlowPyrLK( prev_grey, grey, prev_pyramid, pyramid, points[0], points[1], count, cvSize(win_size,win_size), 3, status, 0, cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,20,0.03), flags ); flags |= CV_LKFLOW_PYR_A_READY; for( i = k = 0; i < count; i++ ) { if( add_remove_pt ) { double dx = pt.x - points[1][i].x; double dy = pt.y - points[1][i].y; if( dx*dx + dy*dy <= 25 ) { add_remove_pt = 0; continue; } } if( !status[i] ) continue; points[1][k++] = points[1][i]; cvCircle( image, cvPointFrom32f(points[1][i]), 5, CV_RGB(255,0,255), -1, 8,0); PX1=points[1][0].x; PY1=points[1][0].y; PX2=points[1][1].x; PY2=points[1][1].y; movimiento1(count,PX1,PY1); } count = k;} if( add_remove_pt && count==0 && count < MAX_COUNT) { points[1][count++] = cvPointTo32f(pt); printf("punto nuevo %i\n",count); pt1=cvPoint(pt.x,pt.y); cvFindCornerSubPix( grey, points[1] + count - 1, 1, cvSize(win_size,win_size), cvSize(-1,-1), cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,20,0.03)); add_remove_pt = 0; p_fijaX= (int)points[1][0].x; p_fijaY= (int)points[1][0].y; } if( add_remove_pt && count==1 && count < MAX_COUNT ) { points[1][count++] = cvPointTo32f(pt); printf("punto nuevo %i\n",count); pt2=cvPoint(pt.x,pt.y); cvFindCornerSubPix( grey, points[1] + count - 1, 1, cvSize(win_size,win_size), cvSize(-1,-1), cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,20,0.03)); add_remove_pt = 0; dist=points[1][1].x-points[1][0].x;//capturar la distancia automaticamente printf("D= %d",dist); } // if(count==2) movimiento(PX1,PX2); CV_SWAP( prev_grey, grey, swap_temp ); CV_SWAP( prev_pyramid, pyramid, swap_temp ); CV_SWAP( points[0], points[1], swap_points ); cvShowImage( "LkDemo", image ); c = cvWaitKey(50); } ● Método main en el que se realiza la llamada a todos lo métodos mencionados antes, observar las llamada a glutIdleFunc(prIdle), y de donde parte el programa, realizando la activación de la cámara y la activación del “geoface”. void main ( int argc, char** argv ) { int i; //camara if( argc == 1 || (argc == 2 && strlen(argv[1]) == 1 && isdigit(argv[1][0]))) capture = cvCaptureFromCAM( argc == 2 ? argv[1][0] - '0' : 0 ); if( !capture ) { fprintf(stderr,"No puedo comenzar, no hay camara...\n"); } // // messCam(); printf("Indica distancia entre los puntos: \n"); scanf("%d",&distancia); cvNamedWindow( "LkDemo", 0 ); cvSetMouseCallback( "LkDemo", on_mouse, 0); glutInitWindowSize ( 400, 600 ) ; glutInit(&argc, argv); for(i=1; i<argc; i++) { if(!strcmp(argv[i], "-v")) { verbose = 1;} } glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_MULTISAMPLE); glutCreateWindow ( "geoface" ) ; myinit (); faceinit (); glutIdleFunc(prIdle); glutMouseFunc(mouse); glutMotionFunc(motion); glutKeyboardFunc ( Key ) ; glutSpecialFunc(special); glutReshapeFunc ( myReshape ) ; glutDisplayFunc(display); make_menus(); glutMainLoop() ; } #ifdef _EiC main(1,"lkdemo.c"); #endif