aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pdp_opencv_floodfill-help.pd102
-rw-r--r--pdp_opencv_floodfill.c393
2 files changed, 316 insertions, 179 deletions
diff --git a/pdp_opencv_floodfill-help.pd b/pdp_opencv_floodfill-help.pd
index f8dc2db..8aa3a5f 100644
--- a/pdp_opencv_floodfill-help.pd
+++ b/pdp_opencv_floodfill-help.pd
@@ -1,20 +1,82 @@
-#N canvas 0 0 521 599 10;
-#X obj 101 158 pdp_xv;
-#X msg 101 -138 open /dev/video0;
-#X obj 101 57 pdp_v4l2;
-#X msg 207 60 set;
-#X floatatom 273 102 5 0 0 0 - - -;
-#X text 317 103 number of frames to take as average bg;
-#X obj 191 224 pdp_xv;
-#X floatatom 363 168 5 0 0 0 - - -;
-#X text 407 169 number of frames to take as average bg;
-#X obj 191 165 pdp_opencv_floodfill;
-#X obj 101 99 pdp_opencv_threshold;
-#X connect 1 0 2 0;
-#X connect 2 0 10 0;
-#X connect 3 0 10 0;
-#X connect 4 0 10 2;
-#X connect 7 0 9 1;
-#X connect 9 0 6 0;
-#X connect 10 0 0 0;
-#X connect 10 0 9 0;
+#N canvas 461 101 826 623 10;
+#X msg 91 -56 open /dev/video0;
+#X obj 109 41 pdp_v4l2;
+#X obj 104 390 pdp_xv;
+#X obj 104 279 pdp_opencv_floodfill;
+#X obj 109 -6 metro 40;
+#X text 102 489 used in tracking algorithms as an object selector;
+#X text 102 502 Written by Lluis Gomez i Bigorda ( lluis@artefacte.org
+);
+#X text 102 516 and Yves Degoyon ( ydegoyon@gmail.com );
+#X floatatom 270 240 5 0 0 0 - - -;
+#X floatatom 277 260 5 0 0 0 - - -;
+#X msg 110 -37 bang;
+#X msg 206 -54 open /dev/video0;
+#X obj 216 -4 metro 40;
+#X msg 217 -35 bang;
+#X obj 216 32 pdp_v4l;
+#X msg 213 70 mark \$1 \$2;
+#X obj 104 417 route press;
+#X msg 260 219 color \$1;
+#X obj 322 220 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0
+1;
+#X text 348 218 activate color mode ( default : on );
+#X msg 154 389 cursor 1;
+#X msg 249 144 fillcolor 1 255 0 123;
+#X text 387 145 fillcolor of nth component ( 1 < n < 10 );
+#X text 226 389 <-- click in the video window on the shape/component
+you want to mark;
+#X text 288 56 mark %x %y : mark a component;
+#X text 288 68 ( 0 <= %x <= 1 );
+#X text 289 79 ( 0 <= %y <= 1 );
+#X obj 221 307 route 0 1 2 3 4 5 6 7 8 9;
+#X floatatom 222 352 5 0 0 0 - - -;
+#X floatatom 258 353 5 0 0 0 - - -;
+#X floatatom 294 353 5 0 0 0 - - -;
+#X floatatom 330 353 5 0 0 0 - - -;
+#X obj 222 330 unpack f f f f;
+#X text 224 369 X;
+#X text 261 369 Y;
+#X text 293 370 Width;
+#X text 331 370 Height;
+#X msg 228 98 delete 1;
+#X msg 242 120 clear;
+#X text 288 98 delete a component ( 1 <= index <= 10 );
+#X text 291 120 delete all components;
+#X text 380 308 detected components;
+#X text 311 239 outbound tolerance ( default 20 );
+#X text 317 259 inbound tolerance ( default 20 );
+#X msg 256 170 connectivty 4;
+#X msg 258 193 connectivty 8;
+#X text 350 181 set connectivity ( default 4 );
+#X text 101 466 pdp_opencv_floodfill : mark image components with a
+specific color;
+#X connect 0 0 3 0;
+#X connect 1 0 3 0;
+#X connect 2 0 16 0;
+#X connect 3 0 2 0;
+#X connect 3 0 20 0;
+#X connect 3 1 27 0;
+#X connect 4 0 1 0;
+#X connect 8 0 3 1;
+#X connect 9 0 3 2;
+#X connect 10 0 4 0;
+#X connect 11 0 14 0;
+#X connect 12 0 14 0;
+#X connect 13 0 12 0;
+#X connect 14 0 3 0;
+#X connect 15 0 3 0;
+#X connect 16 0 15 0;
+#X connect 17 0 3 0;
+#X connect 18 0 17 0;
+#X connect 20 0 2 0;
+#X connect 21 0 3 0;
+#X connect 27 0 32 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 37 0 3 0;
+#X connect 38 0 3 0;
+#X connect 44 0 3 0;
+#X connect 45 0 3 0;
diff --git a/pdp_opencv_floodfill.c b/pdp_opencv_floodfill.c
index 864e41c..7e697ca 100644
--- a/pdp_opencv_floodfill.c
+++ b/pdp_opencv_floodfill.c
@@ -31,7 +31,7 @@
#include "cv.h"
#endif
-
+#define MAX_COMPONENTS 10
typedef struct pdp_opencv_floodfill_struct
{
@@ -39,6 +39,8 @@ typedef struct pdp_opencv_floodfill_struct
t_float x_f;
t_outlet *x_outlet0;
+ t_outlet *x_outlet1;
+ t_atom x_list[5];
int x_packet0;
int x_packet1;
int x_dropped;
@@ -50,20 +52,22 @@ typedef struct pdp_opencv_floodfill_struct
int x_infosok;
- int up_diff;
- int lo_diff;
- int ffill_case;
- int connectivity;
- int is_color;
- int is_mask;
- int new_mask_val;
+ int x_up;
+ int x_lo;
+ int x_connectivity;
+ int x_color;
+
+ // tracked components
+ int x_xcomp[MAX_COMPONENTS];
+ int x_ycomp[MAX_COMPONENTS];
- // The output and temporary images
+ // fill color
+ int x_r[MAX_COMPONENTS];
+ int x_g[MAX_COMPONENTS];
+ int x_b[MAX_COMPONENTS];
- IplImage* color_img0;
- IplImage* mask;
+ // opencv data
IplImage* color_img;
- IplImage* gray_img0;
IplImage* gray_img;
} t_pdp_opencv_floodfill;
@@ -72,39 +76,31 @@ typedef struct pdp_opencv_floodfill_struct
static void pdp_opencv_floodfill_process_rgb(t_pdp_opencv_floodfill *x)
{
- t_pdp *header = pdp_packet_header(x->x_packet0);
- 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;
-
+ t_pdp *header = pdp_packet_header(x->x_packet0);
+ 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;
+ CvConnectedComp comp;
+ int flags = x->x_connectivity + ( 255 << 8 ) + CV_FLOODFILL_FIXED_RANGE;
if ((x->x_width != (t_int)header->info.image.width) ||
(x->x_height != (t_int)header->info.image.height))
{
- post("pdp_opencv_floodfill :: resizing plugins");
-
- //cv_freeplugins(x);
-
- x->x_width = header->info.image.width;
- x->x_height = header->info.image.height;
- x->x_size = x->x_width*x->x_height;
+ post("pdp_opencv_floodfill :: resizing plugins");
+
+ x->x_width = header->info.image.width;
+ x->x_height = header->info.image.height;
+ x->x_size = x->x_width*x->x_height;
- //Destroy cv_images
- cvReleaseImage( &x->color_img );
- cvReleaseImage( &x->color_img0 );
- cvReleaseImage( &x->mask );
- cvReleaseImage( &x->gray_img );
- cvReleaseImage( &x->gray_img0 );
-
+ //Destroy cv_images
+ cvReleaseImage( &x->color_img );
+ cvReleaseImage( &x->gray_img );
- //Create cv_images
- x->color_img0 = cvCreateImage( cvSize(x->x_width,x->x_height), 8, 3 );
- x->color_img = cvCreateImage( cvSize(x->x_width,x->x_height), 8, 3 );
- x->gray_img0 = cvCreateImage( cvSize(x->x_width, x->x_height), 8, 1 );
- x->gray_img = cvCreateImage( cvSize(x->x_width, x->x_height), 8, 1 );
- x->mask = cvCreateImage( cvSize(x->x_width + 2, x->x_height + 2), 8, 1 );
+ //Create cv_images
+ x->color_img = cvCreateImage( cvSize(x->x_width,x->x_height), 8, 3 );
+ x->gray_img = cvCreateImage( cvSize(x->x_width, x->x_height), 8, 1 );
}
newheader->info.image.encoding = header->info.image.encoding;
@@ -112,88 +108,57 @@ static void pdp_opencv_floodfill_process_rgb(t_pdp_opencv_floodfill *x)
newheader->info.image.height = x->x_height;
memcpy( newdata, data, x->x_size*3 );
- // FEM UNA COPIA DEL PACKET A x->grey->imageData ... http://www.cs.iit.edu/~agam/cs512/lect-notes/opencv-intro/opencv-intro.html aqui veiem la estructura de IplImage
memcpy( x->color_img->imageData, data, x->x_size*3 );
-
- cvCvtColor(x->color_img, x->gray_img, CV_BGR2GRAY);
-
-
- int px = 0;
- int py = 0;
- int biggestNum=0,biggestLocX=0,biggestLocY=0;
- int haveOne=0;
- CvPixelPosition8u sil;
- int stride = x->gray_img->widthStep;
- unsigned char * pI = (unsigned char *)x->gray_img->imageData;
- CV_INIT_PIXEL_POS(sil, pI, x->gray_img->widthStep, cvSize(x->gray_img->width, x->gray_img->height), 0, 0,IPL_ORIGIN_TL);
- CvPoint xy;
- CvPoint seed = cvPoint(px,py);
- int lo = x->ffill_case == 0 ? 0 : x->lo_diff;
- int up = x->ffill_case == 0 ? 0 : x->up_diff;
- int flags = x->connectivity + (x->new_mask_val << 8) +
- (x->ffill_case == 1 ? CV_FLOODFILL_FIXED_RANGE : 0);
- CvConnectedComp comp;
- int min_area_size = 200;
-
- for(py=0; py<x->gray_img->height; py++)
- {
- for(px=0; px<x->gray_img->width; px++)
- {
- if(*(sil.currline + sil.x) != 0) // check if used yet
- {
- xy.x = px;
- xy.y = py;
- cvFloodFill ( x->gray_img, xy, cvRealScalar(100), cvRealScalar(lo), cvRealScalar(up), &comp, flags, NULL );
- // if size is too small remove that region
- // Also, keep only the biggest region!!!
- if( ((int)(comp.area)<min_area_size) || ((int)(comp.area)<biggestNum) )
- {
- // remove it
- //cvFloodFill ( x->gray_img, xy, cvRealScalar(0), cvRealScalar(lo), cvRealScalar(up), &comp, flags, NULL );
- } else { // for keeping just the largest
- // remove previous max
- if(haveOne)
- {
- xy.x = biggestLocX;
- xy.y = biggestLocY;
- //cvFloodFill ( x->gray_img, xy, cvRealScalar(0), cvRealScalar(lo), cvRealScalar(up), &comp, flags, NULL );
- } else haveOne=1;
- biggestNum=(int)(comp.area);
- biggestLocX=px;
- biggestLocY=py;
- }
- }
- CV_MOVE_RIGHT_WRAP(sil, 1);
- }
- CV_MOVE_DOWN(sil, 1);
- }
- if(haveOne)
- {
- xy.x = biggestLocX;
- xy.y = biggestLocY;
- //cvFloodFill ( x->gray_img, xy, cvRealScalar(255), cvRealScalar(lo), cvRealScalar(up), &comp, flags, NULL );
- }
-
-
-
- //CvScalar brightness = cvRealScalar(255);
- //cvFloodFill( x->color_img, seed, CV_RGB(255,255,255), CV_RGB(lo,lo,lo),
- // CV_RGB(up,up,up), &comp, flags, NULL );
-
- cvCvtColor(x->gray_img, x->color_img, CV_GRAY2BGR);
+ if ( !x->x_color )
+ {
+ cvCvtColor(x->color_img, x->gray_img, CV_BGR2GRAY);
+ }
+
+ // mark recognized components
+ for ( i=0; i<MAX_COMPONENTS; i++ )
+ {
+ if ( x->x_xcomp[i] != -1 )
+ {
+ if ( x->x_color )
+ {
+ CvPoint seed = cvPoint(x->x_xcomp[i],x->x_ycomp[i]);
+ CvScalar color = CV_RGB( x->x_r[i], x->x_g[i], x->x_b[i] );
+ cvFloodFill( x->color_img, seed, color, CV_RGB( x->x_lo, x->x_lo, x->x_lo ),
+ CV_RGB( x->x_up, x->x_up, x->x_up ), &comp, flags, NULL );
+ SETFLOAT(&x->x_list[0], i);
+ SETFLOAT(&x->x_list[1], comp.rect.x);
+ SETFLOAT(&x->x_list[2], comp.rect.y);
+ SETFLOAT(&x->x_list[3], comp.rect.width);
+ SETFLOAT(&x->x_list[4], comp.rect.height);
+ outlet_list( x->x_outlet1, 0, 5, x->x_list );
+ }
+ else
+ {
+ CvPoint seed = cvPoint(x->x_xcomp[i],x->x_ycomp[i]);
+ CvScalar brightness = cvRealScalar((x->x_r[i]*2 + x->x_g[i]*7 + x->x_b[i] + 5)/10);
+ cvFloodFill( x->gray_img, seed, brightness, cvRealScalar(x->x_lo),
+ cvRealScalar(x->x_up), &comp, flags, NULL );
+ SETFLOAT(&x->x_list[0], i);
+ SETFLOAT(&x->x_list[1], comp.rect.x);
+ SETFLOAT(&x->x_list[2], comp.rect.y);
+ SETFLOAT(&x->x_list[3], comp.rect.width);
+ SETFLOAT(&x->x_list[4], comp.rect.height);
+ outlet_list( x->x_outlet1, 0, 5, x->x_list );
+ }
+ }
+ }
+
+ if ( !x->x_color )
+ {
+ cvCvtColor(x->gray_img, x->color_img, CV_GRAY2RGB);
+ }
memcpy( newdata, x->color_img->imageData, x->x_size*3 );
- //printf("%g pixels were repainted\n", comp.area );
return;
}
-static void pdp_opencv_floodfill_diff(t_pdp_opencv_floodfill *x, t_floatarg f)
-{
- if ((f==1)||(f==3)||(f==5)||(f==7)) x->up_diff = (int)f;
-}
-
static void pdp_opencv_floodfill_sendpacket(t_pdp_opencv_floodfill *x)
{
/* release the packet */
@@ -206,34 +171,27 @@ static void pdp_opencv_floodfill_sendpacket(t_pdp_opencv_floodfill *x)
static void pdp_opencv_floodfill_process(t_pdp_opencv_floodfill *x)
{
- int encoding;
- t_pdp *header = 0;
- char *parname;
- unsigned pi;
- int partype;
- float pardefault;
- t_atom plist[2];
- t_atom tlist[2];
- t_atom vlist[2];
-
- /* check if image data packets are compatible */
- if ( (header = pdp_packet_header(x->x_packet0))
- && (PDP_BITMAP == header->type)){
+ int encoding;
+ t_pdp *header = 0;
+
+ /* check if image data packets are compatible */
+ if ( (header = pdp_packet_header(x->x_packet0))
+ && (PDP_BITMAP == header->type)){
- /* pdp_opencv_floodfill_process inputs and write into active inlet */
- switch(pdp_packet_header(x->x_packet0)->info.image.encoding){
+ /* pdp_opencv_floodfill_process inputs and write into active inlet */
+ switch(pdp_packet_header(x->x_packet0)->info.image.encoding){
- case PDP_BITMAP_RGB:
+ case PDP_BITMAP_RGB:
x->x_packet1 = pdp_packet_clone_rw(x->x_packet0);
pdp_queue_add(x, pdp_opencv_floodfill_process_rgb, pdp_opencv_floodfill_sendpacket, &x->x_queue_id);
- break;
+ break;
- default:
- /* don't know the type, so dont pdp_opencv_floodfill_process */
- break;
-
- }
- }
+ default:
+ /* don't know the type, so dont pdp_opencv_floodfill_process */
+ break;
+
+ }
+ }
}
@@ -257,28 +215,137 @@ static void pdp_opencv_floodfill_free(t_pdp_opencv_floodfill *x)
pdp_queue_finish(x->x_queue_id);
pdp_packet_mark_unused(x->x_packet0);
- //cv_freeplugins(x);
- //Destroy cv_images
- cvReleaseImage( &x->color_img );
- cvReleaseImage( &x->color_img0 );
- cvReleaseImage( &x->mask );
- cvReleaseImage( &x->gray_img );
- cvReleaseImage( &x->gray_img0 );
+ //Destroy cv_images
+ cvReleaseImage( &x->color_img );
+ cvReleaseImage( &x->gray_img );
}
-t_class *pdp_opencv_floodfill_class;
+static void pdp_opencv_floodfill_up_diff(t_pdp_opencv_floodfill *x, t_floatarg fupdiff )
+{
+ if ( ( (int)fupdiff >= 0 ) && ( (int)fupdiff <= 255 ) )
+ {
+ x->x_up = (int)fupdiff;
+ }
+}
+
+static void pdp_opencv_floodfill_lo_diff(t_pdp_opencv_floodfill *x, t_floatarg flodiff )
+{
+ if ( ( (int)flodiff >= 0 ) && ( (int)flodiff <= 255 ) )
+ {
+ x->x_lo = (int)flodiff;
+ }
+}
+
+static void pdp_opencv_floodfill_color(t_pdp_opencv_floodfill *x, t_floatarg fcolor )
+{
+ if ( ( (int)fcolor == 0 ) || ( (int)fcolor == 1 ) )
+ {
+ x->x_color = (int)fcolor;
+ }
+}
+
+static void pdp_opencv_floodfill_fillcolor(t_pdp_opencv_floodfill *x, t_floatarg findex, t_floatarg fr, t_floatarg fg, t_floatarg fb )
+{
+ if ( ( (int)findex <= 0 ) || ( (int)findex > MAX_COMPONENTS ) )
+ {
+ post( "pdp_opencv_floodfill : wrong color index : %d", (int)findex );
+ return;
+ }
+
+ if ( ( (int)fr >= 0 ) || ( (int)fr <= 255 ) )
+ {
+ x->x_r[(int)findex-1] = (int)fr;
+ }
+
+ if ( ( (int)fg >= 0 ) || ( (int)fg <= 255 ) )
+ {
+ x->x_g[(int)findex-1] = (int)fg;
+ }
+ if ( ( (int)fb >= 0 ) || ( (int)fb <= 255 ) )
+ {
+ x->x_b[(int)findex-1] = (int)fb;
+ }
+
+}
+
+static void pdp_opencv_floodfill_mark(t_pdp_opencv_floodfill *x, t_floatarg fperx, t_floatarg fpery )
+{
+ int i;
+ int inserted;
+
+ if ( ( fperx < 0.0 ) || ( fperx > 1.0 ) || ( fpery < 0.0 ) || ( fpery > 1.0 ) )
+ {
+ return;
+ }
+
+ inserted = 0;
+ for ( i=0; i<MAX_COMPONENTS; i++)
+ {
+ if ( x->x_xcomp[i] == -1 )
+ {
+ x->x_xcomp[i] = (int)(fperx*x->x_width);
+ x->x_ycomp[i] = (int)(fpery*x->x_height);
+ post( "pdp_opencv_floodfill : inserted point (%d,%d)", x->x_xcomp[i], x->x_ycomp[i] );
+ inserted = 1;
+ break;
+ }
+ }
+ if ( !inserted )
+ {
+ post( "pdp_opencv_floodfill : max components reached" );
+ }
+}
+
+static void pdp_opencv_floodfill_delete(t_pdp_opencv_floodfill *x, t_floatarg findex )
+{
+ int i;
+
+ if ( ( findex < 1.0 ) || ( findex > 10 ) )
+ {
+ return;
+ }
+
+ x->x_xcomp[(int)findex-1] = -1;
+ x->x_ycomp[(int)findex-1] = -1;
+}
+
+static void pdp_opencv_floodfill_connectivity(t_pdp_opencv_floodfill *x, t_floatarg fconnectivity )
+{
+ int i;
+
+ if ( ( fconnectivity != 4.0 ) && ( fconnectivity != 8.0 ) )
+ {
+ return;
+ }
+
+ x->x_connectivity = (int)fconnectivity;
+}
+
+static void pdp_opencv_floodfill_clear(t_pdp_opencv_floodfill *x )
+{
+ int i;
+
+ for ( i=0; i<MAX_COMPONENTS; i++)
+ {
+ x->x_xcomp[i] = -1;
+ x->x_ycomp[i] = -1;
+ }
+}
+
+t_class *pdp_opencv_floodfill_class;
void *pdp_opencv_floodfill_new(t_floatarg f)
{
- int i;
+ int i;
t_pdp_opencv_floodfill *x = (t_pdp_opencv_floodfill *)pd_new(pdp_opencv_floodfill_class);
inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("lo_diff"));
inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("up_diff"));
x->x_outlet0 = outlet_new(&x->x_obj, &s_anything);
+ x->x_outlet1 = outlet_new(&x->x_obj, &s_anything);
x->x_packet0 = -1;
x->x_packet1 = -1;
@@ -290,21 +357,23 @@ void *pdp_opencv_floodfill_new(t_floatarg f)
x->x_infosok = 0;
- x->ffill_case = 1;
- x->lo_diff = 20;
- x->up_diff = 20;
- x->connectivity = 4;
- x->is_color = 1;
- x->is_mask = 0;
- x->new_mask_val = 255;
+ x->x_lo = 20;
+ x->x_up = 20;
+ x->x_connectivity = 4;
+ x->x_color = 1;
+
+ for ( i=0; i<MAX_COMPONENTS; i++)
+ {
+ x->x_xcomp[i] = -1;
+ x->x_ycomp[i] = -1;
+ x->x_r[i] = rand() & 255;
+ x->x_g[i] = rand() & 255;
+ x->x_b[i] = rand() & 255;
+ }
- x->color_img0 = cvCreateImage( cvSize(x->x_width,x->x_height), 8, 3 );
x->color_img = cvCreateImage( cvSize(x->x_width,x->x_height), 8, 3 );
- x->mask = cvCreateImage( cvSize(x->x_width + 2, x->x_height + 2), 8, 1 );
- x->gray_img0 = cvCreateImage( cvSize(x->x_width, x->x_height), 8, 1 );
x->gray_img = cvCreateImage( cvSize(x->x_width, x->x_height), 8, 1 );
-
return (void *)x;
}
@@ -318,13 +387,19 @@ extern "C"
void pdp_opencv_floodfill_setup(void)
{
- post( " pdp_opencv_floodfill");
+ post( " pdp_opencv_floodfill");
pdp_opencv_floodfill_class = class_new(gensym("pdp_opencv_floodfill"), (t_newmethod)pdp_opencv_floodfill_new,
- (t_method)pdp_opencv_floodfill_free, sizeof(t_pdp_opencv_floodfill), 0, A_DEFFLOAT, A_NULL);
+ (t_method)pdp_opencv_floodfill_free, sizeof(t_pdp_opencv_floodfill), 0, A_DEFFLOAT, A_NULL);
class_addmethod(pdp_opencv_floodfill_class, (t_method)pdp_opencv_floodfill_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL);
- //class_addmethod(pdp_opencv_floodfill_class, (t_method)pdp_opencv_floodfill_up_diff, gensym("up_diff"), A_FLOAT, A_NULL );
- //class_addmethod(pdp_opencv_floodfill_class, (t_method)pdp_opencv_floodfill_lo_diff, gensym("lo_diff"), A_FLOAT, A_NULL );
+ class_addmethod(pdp_opencv_floodfill_class, (t_method)pdp_opencv_floodfill_color, gensym("color"), A_DEFFLOAT, A_NULL);
+ class_addmethod(pdp_opencv_floodfill_class, (t_method)pdp_opencv_floodfill_fillcolor, gensym("fillcolor"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_NULL);
+ class_addmethod(pdp_opencv_floodfill_class, (t_method)pdp_opencv_floodfill_mark, gensym("mark"), A_DEFFLOAT, A_DEFFLOAT, A_NULL);
+ class_addmethod(pdp_opencv_floodfill_class, (t_method)pdp_opencv_floodfill_delete, gensym("delete"), A_DEFFLOAT, A_NULL);
+ class_addmethod(pdp_opencv_floodfill_class, (t_method)pdp_opencv_floodfill_connectivity, gensym("connectivity"), A_DEFFLOAT, A_NULL);
+ class_addmethod(pdp_opencv_floodfill_class, (t_method)pdp_opencv_floodfill_clear, gensym("clear"), A_NULL);
+ class_addmethod(pdp_opencv_floodfill_class, (t_method)pdp_opencv_floodfill_up_diff, gensym("up_diff"), A_FLOAT, A_NULL );
+ class_addmethod(pdp_opencv_floodfill_class, (t_method)pdp_opencv_floodfill_lo_diff, gensym("lo_diff"), A_FLOAT, A_NULL );
}