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




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