Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

GraphSegmentation.cpp

Go to the documentation of this file.
00001 /* ------------------------------------------------------------------------- *
00002  * Copyright (C) Philip D.S. Thoren
00003  * Graph based segmentation application.
00004  * 05/27/2007
00005  *
00006  * This program does graph based segmentation on files or a live feed.
00007  *
00008  * If you change this, add your copyrights and comments for what you changed.
00009  *
00010  * ------------------------------------------------------------------------- */
00011 #include <phission.h>
00012 #include <graphSegmentation_Filter.h>
00013 //#include <convert_Filter.h>
00014 
00015 /* ------------------------------------------------------------------------- */
00016 /* I need to make this code here part of Phission, this just makes the code
00017  * easier to work with if the portable stuff is renamed to a common name */
00018 #if defined(PH_HAVE_X11)
00019     #define phDisplay X11Display
00020 #elif defined(PH_HAVE_GDI)
00021     #define phDisplay GDIDisplay
00022 #endif
00023 
00024 #if 1
00025     #define phCapture phAvcodecSource
00026     #define default_path "NearManatee.avi"
00027 #else
00028 #if defined(PH_HAVE_V4L)
00029     #define phCapture V4LCapture
00030     #define default_path "/dev/video1"
00031 #else
00032     #define phCapture VFWSource
00033     #define default_path "0"
00034 #endif
00035 #endif
00036 
00037 /* ------------------------------------------------------------------------ */
00038 /* Global variables */
00039 int             glbl_disable_displays       =   0;
00040 int             glbl_print_blobs            =   0;
00041 int             glbl_save_images            =   0;
00042 
00043 /* image reading variables */
00044 int             glbl_use_images             =   0;
00045 uint32_t        glbl_input_total            =   2;
00046 char           *glbl_prefix                 =NULL;
00047 char           *glbl_extension              =NULL;
00048 
00049 /* Capture variables */
00050 char           *glbl_path                   =NULL;
00051 int             glbl_channel                =   0;
00052 int32_t         glbl_width                  = 320;
00053 int32_t         glbl_height                 = 240;
00054 
00055 /* ------------------------------------------------------------------------ */
00056 void usage()
00057 {
00058     printf("\n\nUsage:\n");
00059     printf("\t--help                    Display usage\n");
00060     printf("\t--nodisplay               Disable the allocation, opening or any use of a display.\n");
00061     printf("\t--save                    Save pipeline output images (0 by default)\n");
00062     printf("\t--nimages <total>         Filename format: <prefix>_%%04d.ppm (2 by default).\n");
00063     printf("\t--prefix <prefix>         Use images. (<prefix> = image by default)\n");
00064     printf("\t--ext <extension>         The input image file extension (default: ppm\n");
00065     printf("\t--printdata               Print the blob data\n");
00066     printf("\t-w <width>                Width of the input data. (default: 320).\n");
00067     printf("\t-h <height>               Height of the input data. (default: 240).\n");
00068     printf("\n\n");
00069     exit(1);
00070 }
00071 
00072 /* ------------------------------------------------------------------------ */
00073 int parse_command_line( int argc, char *argv[] )
00074 {
00075     phFUNCTION("parse_command_line")
00076 
00077     phArgTable          *arg_parser     = new phArgTable();
00078 
00079     /* <> Setup all the command line options to the parser */
00080     rc = arg_parser->add("-w",&glbl_width, phARG_INT32);
00081     phCHECK_RC(rc,NULL,"arg_parser->add");
00082 
00083     rc = arg_parser->add("-h",&glbl_height, phARG_INT32);
00084     phCHECK_RC(rc,NULL,"arg_parser->add");
00085 
00086     rc = arg_parser->add("--prefix",&glbl_prefix, phARG_CHAR);
00087     phCHECK_RC(rc,NULL,"arg_parser->add");
00088 
00089     rc = arg_parser->add("--ext",&glbl_extension, phARG_CHAR);
00090     phCHECK_RC(rc,NULL,"arg_parser->add");
00091 
00092     rc = arg_parser->add("--nimages",&glbl_input_total, phARG_UINT);
00093     phCHECK_RC(rc,NULL,"arg_parser->add");
00094 
00095     rc = arg_parser->add("--save",&glbl_save_images, phARG_BOOL);
00096     phCHECK_RC(rc,NULL,"arg_parser->add");
00097 
00098     rc = arg_parser->add("--printdata",&glbl_print_blobs, phARG_BOOL);
00099     phCHECK_RC(rc,NULL,"arg_parser->add");
00100 
00101     rc = arg_parser->add("--nodisplay",&glbl_disable_displays, phARG_BOOL);
00102     phCHECK_RC(rc,NULL,"arg_parser->add");
00103 
00104     rc = arg_parser->add("--help",(void *)&usage, phARG_FUNC);
00105     phCHECK_RC(rc,NULL,"arg_parser->add");
00106 
00107     rc = arg_parser->add("--path",&glbl_path,phARG_CHAR);
00108     phCHECK_RC(rc,NULL,"arg_parser->add");
00109 
00110     rc = arg_parser->add("--channel",&glbl_channel,phARG_INT);
00111     phCHECK_RC(rc,NULL,"arg_parser->add");
00112 
00113     /* <> Parse */
00114     rc = arg_parser->parse(argc,argv);
00115     phCHECK_RC(rc,NULL,"arg_parser->parse");
00116 
00117     /* <> Do error checking and variable default setup */
00118 
00119     phDelete(arg_parser);
00120 
00121     return phSUCCESS;
00122 error:
00123     phDelete(arg_parser);
00124 
00125     return phFAIL;
00126 }
00127 
00128 /* ------------------------------------------------------------------------ */
00129 void next_image( char      *prefix,
00130                  char      *ext,
00131                  int        total,
00132                  uint32_t  *index,
00133                  phImage   *image )
00134 {
00135     phFUNCTION("next_image")
00136     char filename[255];
00137 
00138     snprintf(filename,255,"%s%010u.%s",prefix,*index,ext);
00139 
00140     if (strcmp(ext,"ppm") != 0)
00141     {
00142         image->disableNotify();
00143 
00144         rc = image->load(filename);
00145         phPRINT_RC(rc,NULL,"image->load(%s)",filename);
00146 
00147         image->enableNotify();
00148 
00149         image->convert(phImageRGB24);
00150     }
00151     else
00152     {
00153         rc = image->load(filename);
00154         phPRINT_RC(rc,NULL,"image->load(%s)",filename);
00155     }
00156     *index = (*index + 1) % total;
00157 }
00158 
00159 /* ------------------------------------------------------------------------- */
00160 int main (int argc, char *argv[] )
00161 {
00162     phFUNCTION("main")
00163 
00164     int i = 0;
00165     int done = 0;
00166 
00167     /* Declare ------------------------------------------------------------- */
00168     phSystem                   *system              = NULL;
00169     phDisplayInterface         *display             = NULL;
00170     phDisplayInterface         *pipeline_display    = NULL;
00171     phImageCapture             *capture             = NULL;
00172     phPipeline                 *pipeline            = NULL;
00173     graphSegmentation_Filter   *graphSegment        = NULL;
00174     gaussian3x3_Filter         *gauss               = NULL;
00175     meanNxN_Filter             *mean                = NULL;
00176     
00177     phLiveObject               *input_source        = NULL;
00178     phImage                    *input_image         = NULL;
00179     uint32_t                    input_index         = 0;
00180     char                       *input_ext           = "ppm";
00181     char                        output_filename[255];
00182     uint32_t                    output_index        = 0;
00183     phImage                    *output_image        = NULL;
00184 
00185     /* resize when reading in larger images */
00186     resize_Filter               *resize             = new resize_Filter(320,240);
00187     
00188     /* Enhance the borders around the edges of objects to get better 
00189      * graph segmentation */
00190     const int           canny_low           = 80;
00191     const int           canny_high          = 200;
00192     subtract_Filter    *sub      = new subtract_Filter(2,1,2);
00193     cv_canny_Filter    *canny    = new cv_canny_Filter(canny_low,canny_high);
00194     
00195     /* greyscale threshold */
00196     convert_Filter              *convert_grey       = new convert_Filter(phImageGREY8);
00197     threshold_Filter            *grey_thresh        = new threshold_Filter(0,225);
00198     
00199     convert_Filter              *convert_rgb24      = new convert_Filter(phImageRGB24);
00200     
00201     /* red green blue threshold */
00202     threshold_Filter            *r_thresh           = new threshold_Filter(0,225);
00203     threshold_Filter            *g_thresh           = new threshold_Filter(1,225);
00204     threshold_Filter            *b_thresh           = new threshold_Filter(2,225);
00205     
00206     /* nearest neighbor blobbing on the graph segmentation output */
00207     blob_Filter                *blob                = NULL ;
00208     phBlobData                 *blob_data           = NULL ;
00209     phColor low_thresh  = phColorArray32_new(0,0,0,0);
00210     phColor high_thresh = phColorArray32_new(0,0,0,0);
00211     phColor loop_thresh = phColorArray32_new(0,0,0,0);
00212     
00213     /* blobbing the white lines */
00214     blob_Filter *blob_white     = NULL;
00215     phBlobData  *white_blobs    = NULL;
00216     phColor     white_color     = phColorRGB24_new(235,235,235);
00217     phColor     white_thresh    = phColorRGB24_new(20,20,20);
00218     phColor     outcolor        = phColorRGB24_new(255,0,255);
00219             
00220     /* HSV stuff */
00221     convert_Filter      *convert        = new convert_Filter(phImageHSV24);
00222     hsvthreshold_Filter *hsvthreshold   = new hsvthreshold_Filter( 0,1,0,255,70,255,0,255,55); 
00223 
00224     uint32_t                    minsize             = 10;
00225 
00226 
00227     phPROGRESS("Program started.\n");
00228 
00229     /* Parse the command line ---------------------------------------------- */
00230     rc = parse_command_line(argc, argv );
00231     phCHECK_RC(rc,NULL,"parse_command_line");
00232 
00233     if (glbl_extension != NULL)
00234     {
00235         input_ext = glbl_extension;
00236     }
00237 
00238     /* Allocate ------------------------------------------------------------ */
00239     system              = new phSystem();
00240     pipeline            = new phPipeline();
00241     graphSegment        = new graphSegmentation_Filter(minsize,450,1);
00242     gauss               = new gaussian3x3_Filter();
00243     mean                = new meanNxN_Filter(5);
00244 
00245     /* Blob filter for the graph based segmentation */
00246     blob = new blob_Filter();
00247     blob_data = new phBlobData();
00248     blob_data->connect(blob->getLiveBlobOutput());
00249     blob->setName("blob");
00250     blob->setDrawRects(1);
00251     blob->setColorBlobs(1);
00252     blob->setNeighborBlob(1);
00253     blob->setColorMinSize(minsize);
00254     
00255     blob->setThresholds(low_thresh, high_thresh, loop_thresh);
00256 
00257     /* blob_white just the white objects */
00258     blob_white = new blob_Filter();
00259     white_blobs = new phBlobData();
00260     white_blobs->connect(blob_white->getLiveBlobOutput());
00261     blob_white->setName("blob_white");
00262     blob_white->setDrawRects(1);
00263     blob_white->setColorBlobs(1);
00264     blob_white->setNeighborBlob(0);
00265     blob_white->setColorMinSize(minsize);
00266     blob_white->setOutcolor(outcolor);
00267 
00268     blob_white->addColor(white_color,white_thresh);
00269 
00270     //hsv_thresh = new hsvthreshold_Filter(0, 0, 0, 100, 50, 50, 140, 100, 100); //TODO ranges of green?
00271 
00272     /* live data */
00273     if (glbl_prefix == NULL)
00274     {
00275         capture         = new phCapture();
00276         ((phAvcodecSource *)capture)->setFps(80);
00277         ((phAvcodecSource *)capture)->setLoop(1);
00278 
00279         input_source    = capture->getOutput();
00280     }
00281     /* Data being loaded from files */
00282     else
00283     {
00284         input_image     = new phImage();
00285         input_source    = input_image;
00286     }
00287 
00288     output_image    = new phImage();
00289 
00290     /* Don't allocate displays if we're not using them */
00291     if (!glbl_disable_displays)
00292     {
00293         display             = new phDisplay( glbl_width, glbl_height,"Capture" );
00294         pipeline_display    = new phDisplay( glbl_width, glbl_height,"Pipeline" );
00295     }
00296 
00297     /* Connect ------------------------------------------------------------- */
00298     pipeline->setInput          ( input_source );
00299 
00300     /* Don't connect displays if we're not using them */
00301     if (!glbl_disable_displays)
00302     {
00303         display->setInput           ( input_source );
00304         //display->setInput(resize->getLiveSourceOutput());
00305         pipeline_display->setInput  ( pipeline->getOutput() );
00306     }
00307 
00308     output_image->connect(pipeline->getOutput());
00309 
00310     /* Tell the system about it all --------------------------------------- */
00311     if (capture != NULL)
00312     {
00313         system->add(capture);
00314     }
00315 
00316     /* Don't add displays if we're not using them */
00317     if (!glbl_disable_displays)
00318     {
00319         system->add(display);
00320         system->add(pipeline_display);
00321     }
00322 
00323     system->add(pipeline);
00324 
00325     /* Calibrate / Setup -------------------------------------------------- */
00326     if (capture != NULL)
00327     {
00328         capture->set(glbl_width,glbl_height,glbl_path);
00329         if (glbl_path == NULL)
00330         {
00331             capture->setPath((char *)default_path);
00332         }
00333         capture->setChannel(glbl_channel);
00334     }
00335 
00336     /* Don't adjust/setup displays if we're not using them */
00337     if (!glbl_disable_displays)
00338     {
00339         display->move(0,0);
00340         pipeline_display->move(glbl_width + 50,0);
00341     }
00342 
00343     /* Setup the pipeline ------------------------------------------------- */
00344     pipeline->add(convert_rgb24);
00345     //pipeline->add(gauss);
00346     //pipeline->add(mean);
00347     //pipeline->add(convert_grey);
00348     //pipeline->add(resize); /* resize large images to smaller */
00349 #if 0 
00350     pipeline->add(r_thresh);
00351     pipeline->add(g_thresh);
00352     pipeline->add(b_thresh);
00353 #endif
00354     
00355 #if 0
00356     pipeline->add(sub);
00357     pipeline->add(canny);
00358     pipeline->add(sub);
00359 #endif
00360     
00361 #if 0
00362     pipeline->add(convert_grey);
00363     pipeline->add(grey_thresh);
00364 #endif
00365     
00366 #if 1
00367     pipeline->add(graphSegment);
00368 #endif
00369 
00370 #if 0
00371     pipeline->add(convert);
00372     pipeline->add(hsvthreshold); // added hsv_crap.
00373 #endif
00374 
00375 #if 0
00376     pipeline->add(blob);
00377 #endif
00378     pipeline->add(blob_white);
00379 
00380     
00381     pipeline->enableTiming();
00382 
00383     /* Start -------------------------------------------------------------- */
00384     system->startup();
00385 
00386     if (!glbl_disable_displays)
00387         done = 1;
00388     while ((system->displaysOpen() > 0) || (!done))
00389     {
00390         /* ----------------------------------------------------------------- */
00391         /* Load an image to segment */
00392         if (glbl_prefix != NULL)
00393         {
00394             next_image( glbl_prefix,
00395                         input_ext,
00396                         glbl_input_total,
00397                         &input_index,
00398                         input_image );
00399             phMSleep(1000);
00400         }
00401 
00402         /* ----------------------------------------------------------------- */
00403         if (glbl_save_images)
00404         {
00405             snprintf(output_filename,255,
00406                     "images/input/graphSegmentation_%04u.ppm",
00407                     output_index);
00408             input_image->save(output_filename);
00409         }
00410 
00411         /* ----------------------------------------------------------------- */
00412         /* Throttle the loop to wait for the pipeline to complete */
00413         if ((glbl_prefix != NULL) || 0)
00414         {
00415             output_image->update();
00416         }
00417         /* if we're saving images, get the frames to save */
00418         if (glbl_save_images)
00419         {
00420             /* Update blob image */
00421             snprintf(output_filename,255,
00422                      "images/output/graphSegmentation_%04u.ppm",
00423                      output_index);
00424 
00425             output_image->save(output_filename);
00426 
00427             output_index++;
00428         }
00429 
00430 #if 0
00431         /* graph segmenation blobbing */
00432         rc = blob_data->update();
00433         if ((rc == phLiveObjectUPDATED) &&
00434             (blob_data->getTotalBlobs(minsize)))
00435         {
00436             blob_data->print_data(minsize); //TODO get the data!  not print!?!?
00437         }
00438 #endif
00439 
00440         rc = white_blobs->update();
00441         if ((rc == phLiveObjectUPDATED) &&
00442             (white_blobs->getTotalBlobs(minsize)))
00443         {
00444             white_blobs->print_data(minsize); //TODO get the data!  not print!?!?
00445         }
00446         
00447         phPRINT("-> %d (%d of %d)\n", pipeline->runtime().getMilliseconds(),
00448                 input_index, glbl_input_total );
00449 
00450         /* Shutdown if we're saving */
00451         /* When input_index == 0, it will be the next run through the list */
00452         if (glbl_save_images && (input_index == 0))
00453         {
00454             done = 1;
00455             system->stopDisplays();
00456             continue;
00457         }
00458     }
00459 
00460     /* Stop --------------------------------------------------------------- */
00461     system->shutdown();
00462 
00463     phPRINT("Average %d\n",
00464             pipeline->averageRuntime().getMilliseconds(),
00465             input_index,
00466             glbl_input_total );
00467 
00468 error:
00469     /* Cleanup ------------------------------------------------------------ */
00470     phDelete(resize);
00471     phDelete(convert_grey);
00472     phDelete(grey_thresh);
00473     phDelete(convert_rgb24);
00474     phDelete(r_thresh);
00475     phDelete(g_thresh);
00476     phDelete(b_thresh);
00477     phDelete(convert);
00478     phDelete(hsvthreshold);
00479     phDelete(gauss);
00480     phDelete(mean);
00481     phDelete(blob_white);
00482     phDelete(white_blobs);
00483     phDelete(canny);
00484     phDelete(sub);
00485     phDelete(output_image);
00486     phDelete(input_image);
00487     phDelete(graphSegment);
00488     phDelete(pipeline);
00489     phDelete(capture);
00490     phDelete(display);
00491     phDelete(pipeline_display);
00492     phDelete(system);
00493     phDelete(blob);
00494     phDelete(blob_data);
00495 
00496     phFree(glbl_prefix);
00497     phFree(glbl_path);
00498     phFree(glbl_extension);
00499 
00500     phPROGRESS("Program finished.\n");
00501 
00502     return phSUCCESS;
00503 }
00504 
00505 
00506 




Copyright (C) 2002 - 2007 Philip D.S. Thoren ( pthoren@users.sourceforge.net )
University Of Massachusetts at Lowell
Robotics Lab
SourceForge.net Logo

Generated on Sat Jun 16 02:44:05 2007 for phission by  doxygen 1.4.4