diff options
-rw-r--r-- | pdp_opencv_haarcascade-help.pd | 191 | ||||
-rw-r--r-- | pdp_opencv_haarcascade.c | 68 |
2 files changed, 162 insertions, 97 deletions
diff --git a/pdp_opencv_haarcascade-help.pd b/pdp_opencv_haarcascade-help.pd index 9016e5a..089df39 100644 --- a/pdp_opencv_haarcascade-help.pd +++ b/pdp_opencv_haarcascade-help.pd @@ -1,61 +1,134 @@ -#N canvas 0 25 1247 665 10; -#X obj 157 -1 pdp_v4l2; -#X msg 225 -36 open /dev/video0; -#X obj 146 261 pdp_xv; -#X floatatom 281 325 5 0 0 0 - - -; -#X floatatom 343 324 5 0 0 0 - - -; -#X floatatom 396 324 5 0 0 0 - - -; -#X obj 278 245 route 0 1 2 3 4; -#X obj 241 57 openpanel; -#X msg 181 58 load \$1; -#X text 331 59 Load a trained cascade classifier from XML file; -#X obj 311 57 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 --1; -#X floatatom 319 114 5 0 0 0 - - -; -#X floatatom 291 179 5 0 0 0 - - -; -#X msg 198 143 mode \$1; -#X obj 259 143 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 +#N canvas 15 49 1247 801 10; +#X text -158 -9 Written by Lluis Gomez i Bigorda ( lluis@artefacte.org +); +#X obj -158 12 cnv 15 621 250 empty empty empty 20 12 0 14 -260097 +-66577 0; +#X obj 82 52 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1 +; +#X obj 82 79 metro 40; +#X msg 172 106 close; +#X obj 102 177 pdp_v4l; +#X msg 159 74 open /dev/video0; +#X obj 283 54 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 1 1; -#X msg 200 178 min_size \$1; -#X msg 196 111 min_neighbors \$1; -#X text 358 113 Minimum number (minus 1) of neighbor rectangles that -makes up an object (default 2); -#X text 331 179 Minimum window size (default 30); -#X msg 195 84 scale_factor \$1; -#X floatatom 313 84 5 0 0 0 - - -; -#X text 357 83 The factor by which the search window is scaled between -the subsequent scans (default 1.1); -#X obj 154 208 pdp_opencv_haarcascade; -#X text 284 145 Mode of operation. Currently the only flag that may -be specified is CV_HAAR_DO_CANNY_PRUNING == 0; -#X text 338 263 For each object detected; -#X text 280 341 Xcenter Ycenter Radio; -#X obj 278 296 unpack 0 0 0; -#X floatatom 341 403 5 0 0 0 - - -; -#X floatatom 403 402 5 0 0 0 - - -; -#X floatatom 456 402 5 0 0 0 - - -; -#X text 340 419 Xcenter Ycenter Radio; -#X obj 338 374 unpack 0 0 0; -#X connect 0 0 22 0; -#X connect 1 0 0 0; -#X connect 6 0 26 0; -#X connect 6 1 31 0; +#X obj 283 81 metro 40; +#X msg 364 100 close; +#X msg 360 76 open /dev/video0; +#X obj 303 179 pdp_v4l2; +#X msg 369 155 format \$1; +#X obj 370 133 hradio 15 1 0 4 empty empty empty 0 -8 0 10 -262144 +-1 -1 0; +#X obj -128 227 pdp_qt; +#X obj -95 163 metro 40; +#X msg -95 135 bang; +#X msg -54 135 stop; +#X obj -128 66 openpanel; +#X msg -128 91 open \$1; +#X msg -128 38 bang; +#X msg -94 190 loop \$1; +#X obj -14 190 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 1 +1; +#X obj -14 108 loadbang; +#X text -85 41 playing a video file; +#X text 112 50 Camera input; +#X obj -156 266 cnv 15 621 300 empty empty empty 20 12 0 14 -258113 +-66577 0; +#X obj -129 591 pdp_xv; +#X floatatom 25 511 5 0 0 0 - - -; +#X floatatom 74 512 5 0 0 0 - - -; +#X floatatom 121 510 5 0 0 0 - - -; +#X obj 21 465 route 0 1 2 3 4; +#X obj -129 418 pdp_opencv_haarcascade; +#X text 123 469 For each object detected; +#X obj 24 489 unpack 0 0 0; +#X floatatom 174 512 5 0 0 0 - - -; +#X floatatom 213 512 5 0 0 0 - - -; +#X floatatom 251 513 5 0 0 0 - - -; +#X obj 172 491 unpack 0 0 0; +#X text -158 -62 pdp_opencv_haarscasccade : object recognition based +on Haar's algorithm ( decision tree algorithm ); +#X text -159 -37 used for face detection by default; +#X floatatom -56 443 5 0 0 0 - - -; +#X text -17 443 number of objects detected; +#X msg 6 282 load \$1; +#X obj 70 282 openpanel; +#X obj 138 281 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 +-1 -1; +#X text -162 -25 ( load haarscascase_frontalface_alt.xml ); +#X text 161 292 ( default haarscascase_frontalface_alt.xml ); +#X text 470 288 don't forget this step; +#X text 471 274 <-- WARNING : if you don't see any object detected +; +#X text 163 280 load an haar's decision tree; +#X msg 25 311 mode \$1; +#X obj 83 311 hradio 15 1 0 2 empty empty empty 0 -8 0 10 -262144 -1 +-1 0; +#X msg 34 338 min_size \$1; +#X floatatom 114 340 5 0 0 0 - - -; +#X floatatom 317 512 5 0 0 0 - - -; +#X floatatom 356 512 5 0 0 0 - - -; +#X floatatom 394 513 5 0 0 0 - - -; +#X obj 315 491 unpack 0 0 0; +#X text 124 311 mode 0 or 1 ( default 0 ); +#X text 154 338 minimum size of object ( default 30 ); +#X floatatom 152 363 5 0 0 0 - - -; +#X text 190 362 minimum neighbours of object ( default 2 ); +#X msg 46 362 min_neighbors \$1; +#X floatatom 160 389 5 0 0 0 - - -; +#X text 198 388 scale used for recognition ( default 1.1 ); +#X text 315 527 Xcenter Ycenter Radius; +#X text 171 527 Xcenter Ycenter Radius; +#X text 25 527 Xcenter Ycenter Radius; +#X msg 54 388 scale_factor \$1; +#X obj -68 228 hsl 128 15 0 500 0 0 empty empty empty -2 -8 0 10 -262144 +-1 -1 0 1; +#X connect 2 0 3 0; +#X connect 3 0 5 0; +#X connect 4 0 5 0; +#X connect 5 0 32 0; +#X connect 6 0 5 0; #X connect 7 0 8 0; -#X connect 8 0 22 0; -#X connect 10 0 7 0; -#X connect 11 0 16 0; -#X connect 12 0 15 0; -#X connect 13 0 22 0; -#X connect 14 0 13 0; -#X connect 15 0 22 0; -#X connect 16 0 22 0; -#X connect 19 0 22 0; -#X connect 20 0 19 0; -#X connect 22 0 2 0; -#X connect 22 1 6 0; -#X connect 26 0 3 0; -#X connect 26 1 4 0; -#X connect 26 2 5 0; -#X connect 31 0 27 0; -#X connect 31 1 28 0; -#X connect 31 2 29 0; +#X connect 8 0 11 0; +#X connect 9 0 11 0; +#X connect 10 0 11 0; +#X connect 11 0 32 0; +#X connect 12 0 11 0; +#X connect 13 0 12 0; +#X connect 14 0 32 0; +#X connect 15 0 14 0; +#X connect 16 0 15 0; +#X connect 17 0 15 0; +#X connect 18 0 19 0; +#X connect 19 0 14 0; +#X connect 20 0 18 0; +#X connect 21 0 14 0; +#X connect 22 0 21 0; +#X connect 23 0 22 0; +#X connect 23 0 16 0; +#X connect 31 0 34 0; +#X connect 31 1 38 0; +#X connect 31 2 58 0; +#X connect 32 0 27 0; +#X connect 32 1 41 0; +#X connect 32 2 31 0; +#X connect 34 0 28 0; +#X connect 34 1 29 0; +#X connect 34 2 30 0; +#X connect 38 0 35 0; +#X connect 38 1 36 0; +#X connect 38 2 37 0; +#X connect 43 0 32 0; +#X connect 44 0 43 0; +#X connect 45 0 44 0; +#X connect 51 0 32 0; +#X connect 52 0 51 0; +#X connect 53 0 32 0; +#X connect 54 0 53 0; +#X connect 58 0 55 0; +#X connect 58 1 56 0; +#X connect 58 2 57 0; +#X connect 61 0 63 0; +#X connect 63 0 32 0; +#X connect 64 0 69 0; +#X connect 69 0 32 0; +#X connect 70 0 14 1; diff --git a/pdp_opencv_haarcascade.c b/pdp_opencv_haarcascade.c index cee9547..48382a7 100644 --- a/pdp_opencv_haarcascade.c +++ b/pdp_opencv_haarcascade.c @@ -34,13 +34,8 @@ #include "cv.h" #endif - - - - const char* default_cascade ="./haarcascade_frontalface_alt.xml"; - typedef struct pdp_opencv_haarcascade_struct { t_object x_obj; @@ -49,6 +44,7 @@ typedef struct pdp_opencv_haarcascade_struct t_outlet *x_outlet0; t_outlet *x_outlet1; t_outlet *x_dataout; + t_atom rlist[4]; int x_packet0; int x_packet1; int x_dropped; @@ -68,6 +64,7 @@ typedef struct pdp_opencv_haarcascade_struct IplImage *frame, *img; CvMemStorage* storage; CvHaarClassifierCascade* cascade; + CvFont font; } t_pdp_opencv_haarcascade; @@ -79,7 +76,7 @@ static void pdp_opencv_haarcascade_process_rgb(t_pdp_opencv_haarcascade *x) short int *data = (short int *)pdp_packet_data(x->x_packet0); t_pdp *newheader = pdp_packet_header(x->x_packet1); short int *newdata = (short int *)pdp_packet_data(x->x_packet1); - + int i; if ((x->x_width != (t_int)header->info.image.width) || (x->x_height != (t_int)header->info.image.height)) @@ -109,15 +106,12 @@ static void pdp_opencv_haarcascade_process_rgb(t_pdp_opencv_haarcascade *x) memcpy( newdata, data, x->x_size*3 ); - //cv_processframe(x, x->x_plugin, newdata); - - // FEM UNA COPIA DEL PACKET A image->imageData ... http://www.cs.iit.edu/~agam/cs512/lect-notes/opencv-intro/opencv-intro.html aqui veiem la estructura de IplImage memcpy( x->frame->imageData, data, x->x_size*3 ); - if( x->frame->origin == IPL_ORIGIN_TL ) - cvCopy( x->frame, x->img, 0 ); - else - cvFlip( x->frame, x->img, 0 ); + if( x->frame->origin == IPL_ORIGIN_TL ) + cvCopy( x->frame, x->img, 0 ); + else + cvFlip( x->frame, x->img, 0 ); static CvScalar colors[] = { @@ -134,9 +128,7 @@ static void pdp_opencv_haarcascade_process_rgb(t_pdp_opencv_haarcascade *x) double scale = 1.3; IplImage* gray = cvCreateImage( cvSize(x->img->width,x->img->height), 8, 1 ); IplImage* small_img = cvCreateImage( cvSize( cvRound (x->img->width/scale), - cvRound (x->img->height/scale)), - 8, 1 ); - int i; + cvRound (x->img->height/scale)), 8, 1 ); cvCvtColor( x->img, gray, CV_BGR2GRAY ); cvResize( gray, small_img, CV_INTER_LINEAR ); @@ -150,7 +142,12 @@ static void pdp_opencv_haarcascade_process_rgb(t_pdp_opencv_haarcascade *x) x->scale_factor, x->min_neighbors, x->mode, cvSize(x->min_size, x->min_size) ); //t = (double)cvGetTickCount() - t; //printf( "detection time = %gms\n", t/((double)cvGetTickFrequency()*1000.) ); - outlet_float(x->x_outlet1, (float)faces->total); + + if ( faces && (faces->total > 0 ) ) + outlet_float(x->x_outlet1, (float)faces->total); + else + outlet_float(x->x_outlet1, 0.0); + for( i = 0; i < (faces ? faces->total : 0); i++ ) { CvRect* r = (CvRect*)cvGetSeqElem( faces, i ); @@ -160,13 +157,15 @@ static void pdp_opencv_haarcascade_process_rgb(t_pdp_opencv_haarcascade *x) center.y = cvRound((r->y + r->height*0.5)*scale); radius = cvRound((r->width + r->height)*0.25*scale); cvCircle( x->img, center, radius, colors[i%8], 3, 8, 0 ); - - t_atom rlist[4]; - SETFLOAT(&rlist[0], i); - SETFLOAT(&rlist[1], center.x); - SETFLOAT(&rlist[2], center.y); - SETFLOAT(&rlist[3], radius); - outlet_list( x->x_dataout, 0, 4, rlist ); + char tindex[4]; + sprintf( tindex, "%d", i ); + cvPutText( x->img, tindex, center, &x->font, CV_RGB(255,255,255)); + + SETFLOAT(&x->rlist[0], i); + SETFLOAT(&x->rlist[1], center.x); + SETFLOAT(&x->rlist[2], center.y); + SETFLOAT(&x->rlist[3], radius); + outlet_list( x->x_dataout, 0, 4, x->rlist ); } } @@ -175,17 +174,10 @@ static void pdp_opencv_haarcascade_process_rgb(t_pdp_opencv_haarcascade *x) cvClearMemStorage( x->storage ); memcpy( newdata, x->img->imageData, x->x_size*3 ); - - return; } -static void pdp_opencv_haarcascade_param(t_pdp_opencv_haarcascade *x, t_floatarg f1, t_floatarg f2) -{ - -} - static void pdp_opencv_haarcascade_scale_factor(t_pdp_opencv_haarcascade *x, t_floatarg f) { if (f>1) x->scale_factor = f; @@ -208,10 +200,10 @@ static void pdp_opencv_haarcascade_min_neighbors(t_pdp_opencv_haarcascade *x, t_ static void pdp_opencv_haarcascade_load(t_pdp_opencv_haarcascade *x, t_symbol *filename) { - x->cascade = (CvHaarClassifierCascade*)cvLoad( filename->s_name, 0, 0, 0 ); + x->cascade = (CvHaarClassifierCascade*)cvLoad( filename->s_name, 0, 0, 0 ); if( !x->cascade ) { - post( "ERROR: Could not load classifier cascade from %s\n", filename->s_name ); + post( "pdp_opencv_haarcascade: ERROR: Could not load classifier cascade from %s\n", filename->s_name ); } else post( "pdp_opencv_haarcascade: Loaded classifier cascade from %s\n", filename->s_name ); } @@ -313,18 +305,18 @@ void *pdp_opencv_haarcascade_new(t_floatarg f) x->mode = 0; x->min_size = 30; - x->cascade = (CvHaarClassifierCascade*)cvLoad( default_cascade, 0, 0, 0 ); if( !x->cascade ) { - post( "ERROR: Could not load default classifier cascade\n" ); + post( "pdp_opencv_haarcascade : ERROR : Could not load default classifier cascade\n" ); } else post( "pdp_opencv_haarcascade: Loaded default classifier cascade\n" ); x->storage = cvCreateMemStorage(0); - x->frame = cvCreateImage(cvSize(x->x_width,x->x_height), IPL_DEPTH_8U, 3); - x->img = cvCreateImage(cvSize(x->frame->width,x->frame->height), IPL_DEPTH_8U, 3); - + x->frame = cvCreateImage(cvSize(x->x_width,x->x_height), IPL_DEPTH_8U, 3); + x->img = cvCreateImage(cvSize(x->frame->width,x->frame->height), IPL_DEPTH_8U, 3); + // initialize font + cvInitFont( &x->font, CV_FONT_HERSHEY_PLAIN, 1.0, 1.0, 0, 1, 8 ); return (void *)x; } |