From 7403eca640c47e995f079ece8dac6496c6cd2496 Mon Sep 17 00:00:00 2001 From: "N.N." Date: Fri, 6 Aug 2010 21:08:18 +0000 Subject: improved contours numbering svn path=/trunk/externals/pdp_opencv/; revision=13761 --- pdp_opencv_contours_boundingrect-help.pd | 188 ++++++++++++++++--------------- pdp_opencv_contours_boundingrect.cc | 182 ++++++++++++++++++------------ pdp_opencv_contours_convexhull-help.pd | 2 +- pdp_opencv_knear-help.pd | 18 +-- 4 files changed, 222 insertions(+), 168 deletions(-) diff --git a/pdp_opencv_contours_boundingrect-help.pd b/pdp_opencv_contours_boundingrect-help.pd index cf06aec..57e7ecd 100644 --- a/pdp_opencv_contours_boundingrect-help.pd +++ b/pdp_opencv_contours_boundingrect-help.pd @@ -1,4 +1,4 @@ -#N canvas 683 49 737 767 10; +#N canvas 699 74 737 767 10; #X obj 41 -82 cnv 15 621 223 empty empty empty 20 12 0 14 -260097 -66577 0; #X msg 148 -25 open /dev/dv1394/0; @@ -7,12 +7,6 @@ #X obj 73 -25 metro 40; #X msg 191 41 norm PAL; #X msg 161 4 close; -#X obj 281 -44 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 -1; -#X obj 281 -17 metro 40; -#X msg 371 10 close; -#X obj 301 81 pdp_v4l; -#X msg 358 -22 open /dev/video0; #X obj 482 -42 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1; #X obj 482 -15 metro 40; @@ -22,22 +16,22 @@ #X obj 40 194 cnv 15 621 400 empty empty empty 20 12 0 14 -258113 -66577 0; #X text 71 -79 FIRST OF ALL SETUP YOUR CAMERA; -#X floatatom 194 474 5 0 0 0 - - -; -#X floatatom 229 474 5 0 0 0 - - -; -#X floatatom 266 474 5 0 0 0 - - -; -#X floatatom 300 474 5 0 0 0 - - -; -#X obj 194 447 unpack 0 0 0 0 0; -#X obj 194 420 route 0 1 2 3 4; -#X floatatom 239 344 5 0 0 0 - - -; -#X floatatom 292 357 5 0 0 0 - - -; -#X obj 91 374 pdp_opencv_contours_boundingrect; -#X text 344 474 Xorigin Yorigin Width Height; -#X floatatom 214 524 5 0 0 0 - - -; -#X floatatom 249 524 5 0 0 0 - - -; -#X floatatom 286 524 5 0 0 0 - - -; -#X floatatom 320 524 5 0 0 0 - - -; -#X obj 211 499 unpack 0 0 0 0 0; -#X text 364 524 Xorigin Yorigin Width Height; +#X floatatom 187 535 5 0 0 0 - - -; +#X floatatom 222 535 5 0 0 0 - - -; +#X floatatom 259 535 5 0 0 0 - - -; +#X floatatom 293 535 5 0 0 0 - - -; +#X obj 187 508 unpack 0 0 0 0 0; +#X obj 187 481 route 0 1 2 3 4; +#X floatatom 245 378 5 0 0 0 - - -; +#X floatatom 298 391 5 0 0 0 - - -; +#X obj 99 431 pdp_opencv_contours_boundingrect; +#X text 180 560 Xorigin Yorigin Width Height; +#X floatatom 361 553 5 0 0 0 - - -; +#X floatatom 396 553 5 0 0 0 - - -; +#X floatatom 433 553 5 0 0 0 - - -; +#X floatatom 467 553 5 0 0 0 - - -; +#X obj 358 528 unpack 0 0 0 0 0; +#X text 340 573 Xorigin Yorigin Width Height; #X obj 91 601 pdp_xv; #X obj 41 148 cnv 15 621 40 empty empty empty 20 12 0 14 -260801 -66577 0; @@ -58,22 +52,16 @@ white areas in the input image \, it's important to set max/min values of the areas you want to detect to filter non interesting noise or areas \, also sometimes you will need to use pdp_opencv_morphology to transform the contours of the shapes to be analyzed..; -#X floatatom 289 394 5 0 0 0 - - -; -#X text 328 395 Number of detected contours; -#X floatatom 241 572 5 0 0 0 - - -; -#X floatatom 276 572 5 0 0 0 - - -; -#X floatatom 313 572 5 0 0 0 - - -; -#X floatatom 347 572 5 0 0 0 - - -; -#X obj 240 549 unpack 0 0 0 0 0; -#X text 391 572 Xorigin Yorigin Width Height; -#X text 297 425 For each contour detected; -#X text 297 412 We have the contours sorted bottom to top and left +#X floatatom 297 451 5 0 0 0 - - -; +#X text 336 452 Number of detected contours; +#X text 290 486 For each contour detected; +#X text 290 473 We have the contours sorted bottom to top and left to right; #X text 42 -273 It is useful as a motion tracker if you have well isolated silouets of the objects you want to track.; -#X text 275 341 minimal area in pixels to be detected (default 10x10) +#X text 281 375 minimal area in pixels to be detected (default 10x10) ; -#X text 329 358 maximal area in pixels to be detected (default 320x240) +#X text 335 392 maximal area in pixels to be detected (default 320x240) ; #X msg 123 196 mode \$1; #X obj 184 197 hradio 15 1 0 4 empty empty empty 0 -8 0 10 -262144 @@ -88,7 +76,6 @@ silouets of the objects you want to track.; #X floatatom 249 242 5 0 0 0 - - -; #X floatatom 283 262 5 0 0 0 - - -; #X msg 194 260 ftolerance \$1; -#X text 292 241 maximum move of a countour ( default 10 ); #X text 318 261 frame tolerance for identification ( default 5 ); #X obj 92 75 pdp_ieee1394; #X msg 211 280 nightmode \$1; @@ -104,57 +91,82 @@ silouets of the objects you want to track.; #X text 330 321 draw the detected contours ( default : off ); #X text 324 281 hide original image ( default : off ); #X text 44 -99 comments to lluisgomez@hanger.org; -#X connect 1 0 69 0; +#X msg 257 346 clear; +#X text 296 347 clear all markers; +#X obj 91 116 pdp_scale 320 240; +#X text 292 241 maximum move of a countour ( default 50 ); +#X msg 463 53 bang; +#X obj 282 115 pdp_qt; +#X obj 315 51 metro 40; +#X msg 315 23 bang; +#X msg 356 23 stop; +#X obj 282 -25 openpanel; +#X msg 282 0 open \$1; +#X msg 316 78 loop \$1; +#X obj 396 78 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 +1; +#X obj 385 51 loadbang; +#X text 337 -1 playing a video file; +#X obj 342 116 hsl 128 15 0 500 0 0 empty empty empty -2 -8 0 10 -262144 +-1 -1 0 1; +#X obj 284 -48 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 +-1 -1; +#X connect 1 0 57 0; #X connect 2 0 3 0; -#X connect 3 0 69 0; -#X connect 4 0 69 0; -#X connect 5 0 69 0; +#X connect 3 0 57 0; +#X connect 4 0 57 0; +#X connect 5 0 57 0; #X connect 6 0 7 0; -#X connect 7 0 9 0; -#X connect 8 0 9 0; -#X connect 9 0 62 0; -#X connect 10 0 9 0; -#X connect 11 0 12 0; -#X connect 12 0 15 0; -#X connect 13 0 15 0; -#X connect 14 0 15 0; -#X connect 15 0 62 0; -#X connect 22 0 18 0; -#X connect 22 1 19 0; -#X connect 22 2 20 0; -#X connect 22 3 21 0; -#X connect 23 0 22 0; -#X connect 23 1 32 0; -#X connect 23 2 49 0; -#X connect 24 0 26 1; -#X connect 25 0 26 2; -#X connect 26 0 34 0; -#X connect 26 1 23 0; -#X connect 26 2 43 0; -#X connect 32 0 28 0; -#X connect 32 1 29 0; -#X connect 32 2 30 0; -#X connect 32 3 31 0; -#X connect 36 0 62 2; -#X connect 38 0 15 0; -#X connect 39 0 38 0; -#X connect 49 0 45 0; -#X connect 49 1 46 0; -#X connect 49 2 47 0; -#X connect 49 3 48 0; -#X connect 56 0 26 0; -#X connect 57 0 56 0; -#X connect 59 0 61 0; -#X connect 61 0 26 0; -#X connect 62 0 26 0; -#X connect 63 0 26 0; -#X connect 64 0 63 0; -#X connect 65 0 66 0; -#X connect 66 0 26 0; -#X connect 69 0 62 0; -#X connect 70 0 26 0; -#X connect 71 0 70 0; -#X connect 72 0 74 0; -#X connect 73 0 76 0; -#X connect 74 0 26 0; -#X connect 76 0 26 0; +#X connect 7 0 10 0; +#X connect 8 0 10 0; +#X connect 9 0 10 0; +#X connect 10 0 70 0; +#X connect 17 0 13 0; +#X connect 17 1 14 0; +#X connect 17 2 15 0; +#X connect 17 3 16 0; +#X connect 18 0 17 0; +#X connect 18 1 27 0; +#X connect 19 0 21 1; +#X connect 20 0 21 2; +#X connect 21 0 29 0; +#X connect 21 1 18 0; +#X connect 21 2 38 0; +#X connect 27 0 23 0; +#X connect 27 1 24 0; +#X connect 27 2 25 0; +#X connect 27 3 26 0; +#X connect 31 0 51 2; +#X connect 33 0 10 0; +#X connect 34 0 33 0; +#X connect 45 0 21 0; +#X connect 46 0 45 0; +#X connect 48 0 50 0; +#X connect 50 0 21 0; +#X connect 51 0 21 0; +#X connect 52 0 21 0; +#X connect 53 0 52 0; +#X connect 54 0 55 0; +#X connect 55 0 21 0; +#X connect 57 0 70 0; +#X connect 58 0 21 0; +#X connect 59 0 58 0; +#X connect 60 0 62 0; +#X connect 61 0 64 0; +#X connect 62 0 21 0; +#X connect 64 0 21 0; +#X connect 68 0 21 0; +#X connect 70 0 51 0; +#X connect 72 0 10 0; +#X connect 73 0 70 0; +#X connect 74 0 73 0; +#X connect 75 0 74 0; +#X connect 76 0 74 0; +#X connect 77 0 78 0; +#X connect 78 0 73 0; +#X connect 79 0 73 0; +#X connect 80 0 79 0; +#X connect 81 0 80 0; +#X connect 81 0 75 0; +#X connect 83 0 73 1; +#X connect 84 0 77 0; diff --git a/pdp_opencv_contours_boundingrect.cc b/pdp_opencv_contours_boundingrect.cc index c8b747d..97aa06d 100755 --- a/pdp_opencv_contours_boundingrect.cc +++ b/pdp_opencv_contours_boundingrect.cc @@ -32,7 +32,7 @@ #include "cv.h" #endif -#define MAX_MARKERS 100 +#define MAX_MARKERS 500 typedef struct pdp_opencv_contours_boundingrect_struct { @@ -47,8 +47,10 @@ typedef struct pdp_opencv_contours_boundingrect_struct int x_packet1; int x_dropped; int x_queue_id; - int x_xmark[MAX_MARKERS]; - int x_ymark[MAX_MARKERS]; + float x_xmark[MAX_MARKERS]; + float x_ymark[MAX_MARKERS]; + int x_wmark[MAX_MARKERS]; + int x_hmark[MAX_MARKERS]; int x_found[MAX_MARKERS]; int x_ftolerance; int x_mmove; @@ -73,7 +75,9 @@ typedef struct pdp_opencv_contours_boundingrect_struct } t_pdp_opencv_contours_boundingrect; -static int pdp_opencv_contours_boundingrect_mark(t_pdp_opencv_contours_boundingrect *x, t_floatarg fx, t_floatarg fy ) +static void pdp_opencv_contours_boundingrect_delete(t_pdp_opencv_contours_boundingrect *x, t_floatarg findex ); + +static int pdp_opencv_contours_boundingrect_mark(t_pdp_opencv_contours_boundingrect *x, t_floatarg fx, t_floatarg fy, t_floatarg fw, t_floatarg fh ) { int i; @@ -86,8 +90,10 @@ static int pdp_opencv_contours_boundingrect_mark(t_pdp_opencv_contours_boundingr { if ( x->x_xmark[i] == -1 ) { - x->x_xmark[i] = (int)fx; - x->x_ymark[i] = (int)fy; + x->x_xmark[i] = (float)(fx+(fw/2)); + x->x_ymark[i] = (float)(fy+(fh/2)); + x->x_wmark[i] = (int)fw; + x->x_hmark[i] = (int)fh; x->x_found[i] = x->x_ftolerance; return i; } @@ -104,8 +110,10 @@ static void pdp_opencv_contours_boundingrect_process_rgb(t_pdp_opencv_contours_b t_pdp *newheader = pdp_packet_header(x->x_packet1); short int *newdata = (short int *)pdp_packet_data(x->x_packet1); char tindex[4]; - int i = 0; // Indicator of cycles. + int count = 0; // Counter of contours int im = 0; // Indicator of markers. + int oi = 0; // Indicator of markers. + float dist, odist; // Distances if ((x->x_width != (t_int)header->info.image.width) || (x->x_height != (t_int)header->info.image.height)) @@ -142,6 +150,7 @@ static void pdp_opencv_contours_boundingrect_process_rgb(t_pdp_opencv_contours_b cvCvtColor(x->image, x->gray, CV_BGR2GRAY); CvSeq* contours; + CvSeq* pcontours; CvMemStorage* stor02; stor02 = cvCreateMemStorage(0); @@ -183,67 +192,95 @@ static void pdp_opencv_contours_boundingrect_process_rgb(t_pdp_opencv_contours_b } } - for( ; contours != 0; contours = contours->h_next ) + // draw old contours + for ( im=0; imtotal; // This is number point in contour - CvRect rect; - int oi, found; - - rect = cvContourBoundingRect( contours, 1); - if ( ( (rect.width*rect.height) > x->minarea ) && ( (rect.width*rect.height) < x->maxarea ) ) { - - found = 0; - oi = -1; - for ( im=0; imx_xmark[im] ) < x->x_mmove ) && ( abs( rect.y - x->x_ymark[im] ) < x->x_mmove ) ) - { - oi=im; - found=1; - x->x_found[im] = x->x_ftolerance; - x->x_xmark[im] = rect.x; - x->x_ymark[im] = rect.y; - break; - } - } - // new object detected - if ( !found ) - { - oi = pdp_opencv_contours_boundingrect_mark(x, rect.x, rect.y ); - } - - if ( x->x_draw ) - { - cvRectangle( x->cnt_img, cvPoint(rect.x,rect.y), cvPoint(rect.x+rect.width,rect.y+rect.height), CV_RGB(255,0,0), 2, 8 , 0 ); - sprintf( tindex, "%d", oi ); - cvPutText( x->cnt_img, tindex, cvPoint(rect.x,rect.y), &x->font, CV_RGB(255,255,255)); - } - - if ( x->x_show ) - { - cvDrawContours( x->cnt_img, contours, CV_RGB(255,255,255), CV_RGB(255,255,255), 0, 1, 8, cvPoint(0,0) ); - } - - SETFLOAT(&x->rlist[0], oi); - SETFLOAT(&x->rlist[1], rect.x); - SETFLOAT(&x->rlist[2], rect.y); - SETFLOAT(&x->rlist[3], rect.width); - SETFLOAT(&x->rlist[4], rect.height); - - outlet_list( x->x_dataout, 0, 5, x->rlist ); - i++; - } + cvRectangle( x->cnt_img, cvPoint((int)(x->x_xmark[im]-x->x_wmark[im]/2),(int)(x->x_ymark[im]-x->x_hmark[im]/2)), + cvPoint((int)(x->x_xmark[im]+x->x_wmark[im]/2),(int)(x->x_ymark[im]+x->x_hmark[im]/2)), CV_RGB(0,0,255), 2, 8, 0 ); + sprintf( tindex, "%d", im ); + cvPutText( x->cnt_img, tindex, cvPoint(x->x_xmark[im],x->x_ymark[im]), &x->font, CV_RGB(0,0,255)); } - outlet_float( x->x_countout, i ); - // delete lost objects - for ( im=0; imh_next ) { - if ( x->x_found[im] < 0 ) + CvRect rect; + + oi=-1; + dist=(x->x_width>x->x_height)?x->x_width:x->x_height; + + rect = cvContourBoundingRect( pcontours, 1); + + if ( ( (rect.width*rect.height) > x->minarea ) && ( (rect.width*rect.height) < x->maxarea ) ) + { + for ( im=0; imx_xmark[im] == -1 ) continue; // no contours + + odist=sqrt( pow( ((float)rect.x+rect.width/2)-x->x_xmark[im], 2 ) + pow( ((float)rect.y+rect.height/2)-x->x_ymark[im], 2 ) ); + + // search for the closest known contour + // that is likely to be this one + if ( odist < x->x_mmove ) + { + if ( odist < dist ) + { + oi=im; + x->x_xmark[oi] = (float)(rect.x+rect.width/2); + x->x_ymark[oi] = (float)(rect.y+rect.height/2); + x->x_wmark[oi] = (int)rect.width; + x->x_hmark[oi] = (int)rect.height; + x->x_found[oi] = x->x_ftolerance; + dist=odist; + } + } + } + + if ( oi==-1 ) + { + oi = pdp_opencv_contours_boundingrect_mark(x, rect.x, rect.y, rect.width, rect.height ); + // post( "new contour : %d (%f,%f)", oi, x->x_xmark[oi], x->x_ymark[oi] ); + } + else + { + // post( "contour found : %d", oi ); + } + + if ( x->x_draw ) + { + cvRectangle( x->cnt_img, cvPoint(rect.x,rect.y), cvPoint(rect.x+rect.width,rect.y+rect.height), CV_RGB(255,0,0), 2, 8, 0 ); + sprintf( tindex, "%d", oi ); + cvPutText( x->cnt_img, tindex, cvPoint(x->x_xmark[oi],x->x_ymark[oi]), &x->font, CV_RGB(0,255,0)); + } + + if ( x->x_show ) + { + cvDrawContours( x->cnt_img, pcontours, CV_RGB(255,255,255), CV_RGB(255,255,255), 0, 1, 8, cvPoint(0,0) ); + } + + SETFLOAT(&x->rlist[0], oi); + SETFLOAT(&x->rlist[1], rect.x); + SETFLOAT(&x->rlist[2], rect.y); + SETFLOAT(&x->rlist[3], rect.width); + SETFLOAT(&x->rlist[4], rect.height); + + outlet_list( x->x_dataout, 0, 5, x->rlist ); + count++; + } + } + + outlet_float( x->x_countout, count ); + + // delete lost objects + for ( im=0; imx_found[im] <= 0 ) { x->x_xmark[im] = -1.0; x->x_ymark[im] = -1,0; + x->x_wmark[im] = -1,0; + x->x_hmark[im] = -1,0; x->x_found[im] = x->x_ftolerance; SETFLOAT(&x->rlist[0], im); SETFLOAT(&x->rlist[1], -1.0); @@ -252,13 +289,13 @@ static void pdp_opencv_contours_boundingrect_process_rgb(t_pdp_opencv_contours_b SETFLOAT(&x->rlist[4], 0.0); outlet_list( x->x_dataout, 0, 5, x->rlist ); } - } + } - cvReleaseMemStorage( &stor02 ); + cvReleaseMemStorage( &stor02 ); - memcpy( newdata, x->cnt_img->imageData, x->x_size*3 ); + memcpy( newdata, x->cnt_img->imageData, x->x_size*3 ); - return; + return; } static void pdp_opencv_contours_boundingrect_minarea(t_pdp_opencv_contours_boundingrect *x, t_floatarg f) @@ -363,13 +400,15 @@ static void pdp_opencv_contours_boundingrect_delete(t_pdp_opencv_contours_boundi { int i; - if ( ( findex < 1.0 ) || ( findex > MAX_MARKERS ) ) + if ( ( findex < 0. ) || ( findex >= MAX_MARKERS ) ) { return; } - x->x_xmark[(int)findex-1] = -1; - x->x_ymark[(int)findex-1] = -1; + x->x_xmark[(int)findex] = -1; + x->x_ymark[(int)findex] = -1; + x->x_wmark[(int)findex] = -1; + x->x_hmark[(int)findex] = -1; } static void pdp_opencv_contours_boundingrect_clear(t_pdp_opencv_contours_boundingrect *x ) @@ -380,6 +419,8 @@ static void pdp_opencv_contours_boundingrect_clear(t_pdp_opencv_contours_boundin { x->x_xmark[i] = -1; x->x_ymark[i] = -1; + x->x_wmark[i] = -1; + x->x_hmark[i] = -1; x->x_found[i] = x->x_ftolerance; } } @@ -482,7 +523,7 @@ void *pdp_opencv_contours_boundingrect_new(t_floatarg f) x->maxarea = 320*240; x->x_ftolerance = 5; - x->x_mmove = 10; + x->x_mmove = 100; x->x_cmode = CV_RETR_LIST; x->x_cmethod = CV_CHAIN_APPROX_SIMPLE; @@ -497,7 +538,8 @@ void *pdp_opencv_contours_boundingrect_new(t_floatarg f) // initialize font cvInitFont( &x->font, CV_FONT_HERSHEY_PLAIN, 1.0, 1.0, 0, 1, 8 ); - //contours = 0; + pdp_opencv_contours_boundingrect_clear(x); + return (void *)x; } diff --git a/pdp_opencv_contours_convexhull-help.pd b/pdp_opencv_contours_convexhull-help.pd index 2edeff5..ced3044 100644 --- a/pdp_opencv_contours_convexhull-help.pd +++ b/pdp_opencv_contours_convexhull-help.pd @@ -1,4 +1,4 @@ -#N canvas 503 58 737 767 10; +#N canvas 507 74 737 767 10; #X obj 41 -82 cnv 15 621 223 empty empty empty 20 12 0 14 -260097 -66577 0; #X obj 281 -41 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 diff --git a/pdp_opencv_knear-help.pd b/pdp_opencv_knear-help.pd index 2337557..b719a01 100755 --- a/pdp_opencv_knear-help.pd +++ b/pdp_opencv_knear-help.pd @@ -1,4 +1,4 @@ -#N canvas 267 49 833 785 10; +#N canvas 271 56 833 785 10; #X obj -16 -15 cnv 15 700 350 empty empty empty 20 12 0 14 -260097 -66577 0; #X obj 212 0 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1 @@ -72,11 +72,11 @@ #X text 125 360 Compare the incoming frame to the patterns; #X text 216 415 Load a new set of patterns from a directory; #X text 217 427 All patterns should be of the same size; -#X msg 101 410 load ../plus 50; #X obj 20 462 pdp_opencv_knear plus 50; #X text -13 -99 based on "basic OCR with Open CV tutorial"; #X text -12 -75 The algorithm is internally based on k-nearest classifiers \, hence the name.; +#X msg 101 412 load ./plus 50; #X connect 1 0 2 0; #X connect 2 0 7 0; #X connect 5 0 4 0; @@ -87,7 +87,7 @@ #X connect 11 0 10 0; #X connect 11 0 39 0; #X connect 12 0 38 0; -#X connect 12 0 48 0; +#X connect 12 0 47 0; #X connect 17 0 32 0; #X connect 18 0 23 0; #X connect 19 0 18 0; @@ -102,7 +102,7 @@ #X connect 26 0 28 0; #X connect 27 0 22 0; #X connect 28 0 21 0; -#X connect 30 0 48 0; +#X connect 30 0 47 0; #X connect 32 0 8 0; #X connect 32 0 9 0; #X connect 32 0 30 0; @@ -112,8 +112,8 @@ #X connect 38 0 36 0; #X connect 39 0 32 0; #X connect 40 0 32 0; -#X connect 43 0 48 0; -#X connect 47 0 48 0; -#X connect 48 0 4 0; -#X connect 48 0 5 0; -#X connect 48 1 6 0; +#X connect 43 0 47 0; +#X connect 47 0 4 0; +#X connect 47 0 5 0; +#X connect 47 1 6 0; +#X connect 50 0 47 0; -- cgit v1.2.1