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

MotionVCR.cpp

Go to the documentation of this file.
00001 /* ---------------------------------------------------------------------------
00002     Phission : 
00003         Realtime Vision Processing System
00004     
00005     Copyright (C) 2003 Philip D.S. Thoren (pthoren@cs.uml.edu)
00006     University of Massachusetts at Lowell,
00007     Laboratory for Artificial Intelligence and Robotics
00008     
00009     This file is part of Phission.
00010 
00011  ---------------------------------------------------------------------------*/
00012 #include <phission.h>
00013 #include <time.h>
00014 #if !defined(WIN32)
00015     #include <sys/time.h>
00016 #else
00017     #define localtime_r(x,y) localtime(x)
00018     #define ctime_r(x,y) ctime(x)
00019 #endif
00020 #include <MotionVCR.h>
00021 
00022 /* ------------------------------------------------------------------------ */
00023 int glbl_disable_displays = 0;
00024 
00025 /* ------------------------------------------------------------------------ */
00026 void usage()
00027 {
00028     printf("\n\nUsage:\n");
00029     printf("\t--help            Display usage\n");
00030     printf("\t--nodisplay       Disable the allocation, opening or any use of a display.\n");
00031     printf("\t--test <value>    Loops <value> times before closing\n");
00032     printf("\n\n");
00033 
00034     exit(1);
00035 }
00036 
00037 /* ------------------------------------------------------------------------ */
00038 int main(int argc, char *argv[] )
00039 {
00040     phFUNCTION("main")
00041 
00042     char            *capture_path   = NULL;
00043     int             channel         = 0;
00044     
00045 #define MEDIUM() 0
00046 #define SLOW() 0
00047 
00048     int32_t record_seconds  = 5; /* save ten seconds @ fps */
00049 #if MEDIUM()
00050     int32_t fps             = 15; /* number of frames in a second */
00051     int     sleeptime       = 6666; /* us */
00052 #elif SLOW()
00053     int32_t fps             = 5; /* number of frames in a second */
00054     int     sleeptime       = 20000; /* us */
00055 #else
00056     int32_t fps             = 30; /* number of frames in a second */
00057     int     sleeptime       = 0; /* us */
00058 #endif
00059     
00060     char               *filename_prefix     = "record/img";
00061     char                filename[512];
00062     char                timestamp_string[512];
00063 
00064     int32_t             frame_index         = 0;
00065 
00066     struct tm          *current_time        = NULL;
00067     time_t              timep               = 0;
00068     time_t              last_time           = 0;
00069     struct tm           result;
00070 
00071     char                ctime_buf[255];
00072 
00073     uint32_t            capture_image_count = 0;
00074 
00075     phImage             image;
00076 
00077     int                 port                = 22345;
00078     
00079     unsigned int        i                   = 0;
00080 
00081     unsigned int        nDisplays           = 1; /* set to 3 to monitor pipeline and mask */
00082     char                title[255];
00083     phDisplayInterface  **display           = NULL;
00084     phDisplayInterface  *monitor_display    = NULL;
00085     int                 monitor_opened      = 0;
00086 
00087     uint32_t            width               = 640;
00088     uint32_t            height              = 480;
00089 
00090     int32_t             minimum_blob_size   = 25;
00091 
00092     int                 save_ppm            = 0;
00093     int                 save_jpeg           = 1;
00094 
00095     FILE               *logfile             = NULL;
00096     char               *logfilename         = "motion.log";
00097 
00098     
00099 #if defined(PH_HAVE_VFW)
00100     VFWSource           *capture        = new VFWSource();
00101 #elif defined(PH_HAVE_V4L)
00102     V4LCapture          *capture        = new V4LCapture();
00103 #endif
00104     NetDisplay          *netdisplay     = new NetDisplay();
00105     
00106     phPipeline          *pipeline       = new phPipeline();
00107 
00108     phColor             incolor_limit   = phColorGREY8_new(255);
00109     phColor             threshold_limit = phColorGREY8_new(20);
00110     phColor             outcolor_limit  = phColorRGB24_new(255,0,0);
00111     phBlobData          blob_data;
00112     blob_Filter         *blob           = new blob_Filter();
00113     
00114     gaussianBlur_Filter *gauss          = new gaussianBlur_Filter();
00115     convert_Filter      *convert        = new convert_Filter(phImageGREY8);
00116     ddimage_Filter      *ddimage        = new ddimage_Filter(15,/* threshold: 0-255 */
00117                                                               0, /* pixel-count: */
00118                                                               3  /* stride */
00119                                                             );
00120     mask_Filter         *mask           = new mask_Filter(10,0.03,0.0001);
00121 
00122     /* Remove the code below when using this code as an example.
00123      * 
00124      * This just checks whether "--test" has been specified with
00125      * a time value argument. It's for testing all the examples
00126      * without the need for human intervention. */
00127     int             test            = 0;
00128     int             count           = 0;
00129 
00130     /* Utility class to ease the starting and stopping of displays, captures and
00131      * pipelines */
00132     phSystem            system;
00133 
00134     phArgTable      *arg_parser = new phArgTable();
00135    
00136     /* Setup and parse all the arguments */
00137     rc = arg_parser->add("--test",&test,phARG_INT);
00138     phCHECK_RC(rc,NULL,"arg_parser->add");
00139     
00140     rc = arg_parser->add("--port",&port,phARG_INT);
00141     phCHECK_RC(rc,NULL,"arg_parser->add");
00142     
00143     rc = arg_parser->add("--nodisplay",&glbl_disable_displays,phARG_BOOL);
00144     phCHECK_RC(rc,NULL,"arg_parser->add");
00145     
00146     rc = arg_parser->add("--help",(void *)&usage,phARG_FUNC);
00147     phCHECK_RC(rc,NULL,"arg_parser->add");
00148     
00149     rc = arg_parser->add("--path",&capture_path,phARG_CHAR);
00150     phCHECK_RC(rc,NULL,"arg_parser->add");
00151 
00152     rc = arg_parser->add("--channel",&channel,phARG_INT);
00153     phCHECK_RC(rc,NULL,"arg_parser->add");
00154     
00155     rc = arg_parser->parse(argc,argv);
00156     phCHECK_RC(rc,NULL,"arg_parser->parse");
00157 
00158     count = test;
00159     
00160     if (glbl_disable_displays) nDisplays = 0;
00161     
00162     /* <>) Setup the capture device parameters */
00163     capture->set(width,height,capture_path);
00164     capture->setFormat(phImageGREY8);
00165 #if 1
00166     capture->setChannel(channel);
00167     capture->setColor(35535);
00168     capture->setHue(34000);
00169     capture->setBrightness(48000);
00170     capture->setContrast(45000);
00171 #else
00172     capture->setChannel(channel);
00173     capture->setBrightness(28000);
00174     capture->setContrast(28000);
00175 #endif
00176 
00177     logfile = fopen(logfilename,"a+");
00178     phCHECK_PTR(logfile,"fopen","fopen failed to open %s",logfilename);
00179 
00180     phPRINT("\nRecording motion:\n");
00181     phPRINT("\timage size           : %u x %u\n",width,height   );
00182     phPRINT("\tminimum blob size    : %d\n", minimum_blob_size  );
00183     phPRINT("\trecord interval      : %d\n", record_seconds     );
00184     phPRINT("\tframes / second      : %d\n", fps                );
00185     phPRINT("\tMotion mask values\n");
00186     phPRINT("\t  threshold          : %5f\n", mask->getThreshold());
00187     phPRINT("\t  mask               : %5f\n", mask->getMaskRate());
00188     phPRINT("\t  unmask             : %5f\n", mask->getUnmaskRate());
00189 
00190     fprintf(logfile,"\nRecording motion:\n");
00191     fprintf(logfile,"\timage size           : %u x %u\n",width,height   );
00192     fprintf(logfile,"\tminimum blob size    : %d\n", minimum_blob_size  );
00193     fprintf(logfile,"\trecord interval      : %d\n", record_seconds     );
00194     fprintf(logfile,"\tframes / second      : %d\n", fps                );
00195     fprintf(logfile,"\tMotion mask values\n");
00196     fprintf(logfile,"\t  threshold          : %5f\n", mask->getThreshold());
00197     fprintf(logfile,"\t  mask               : %5f\n", mask->getMaskRate());
00198     fprintf(logfile,"\t  unmask             : %5f\n", mask->getUnmaskRate());
00199                     
00200     fflush(logfile);
00201     
00202     rc = system.addCapture(capture);
00203     phPRINT_RC(rc,NULL,"system.addCapture(capture)");
00204         
00205     display = new phDisplayInterface *[nDisplays];
00206     phCHECK_NULLPTR(display,"new","new phDisplayInterface *[nDisplays];");
00207     
00208     for (i = 0; i < nDisplays; i++ )
00209     {
00210         sprintf(title,"MotionVCR[%u]",i);
00211         
00212 #if defined(PH_HAVE_X11)
00213         display[i] = new X11Display(width,height,title);
00214 #elif defined(PH_HAVE_GDI)
00215         display[i] = new GDIDisplay(width,height,title);
00216 #endif
00217 
00218         display[i]->move(25 + (width * i), 100);
00219         
00220         rc = system.addDisplay(display[i]);
00221         phPRINT_RC(rc,NULL,"system.addDisplay(display[i:%d])",i);
00222     }
00223     
00224     rc = netdisplay->setLiveSourceInput(capture->getLiveSourceOutput());
00225     phCHECK_RC(rc,NULL,"net->setInput(capture)");
00226 
00227     rc = netdisplay->setPort(port);
00228     phCHECK_RC(rc,NULL,"netdisplay->setPort(%d)",port);    
00229 
00230     rc = system.add(netdisplay);
00231     phCHECK_RC(rc,NULL,"system.add(netdisplay)");
00232     
00233     rc = system.addPipeline(pipeline);
00234     phPRINT_RC(rc,NULL,"system.addPipeline(pipeline)");
00235     
00236 
00237     /* <> Attach the displays to the live sources */
00238     /* Capture -> (b)phPipeline -> (a)Processed Output Display */
00239     
00240     /* <> Attach the Pipeline output image to the display so the
00241      * display updates when a processing has been completed
00242      * for each loop */
00243     if (nDisplays > 0)
00244     {
00245         monitor_display = display[0];
00246         display[0]->setLiveSourceInput(capture->getLiveSourceOutput());
00247     }
00248     if (nDisplays > 1)
00249         display[1]->setLiveSourceInput(pipeline->getLiveSourceOutput());
00250     if (nDisplays > 2)
00251         display[2]->setLiveSourceInput(mask->getMaskImage());
00252     
00253     rc = image.connect(capture->getLiveSourceOutput());
00254     phPRINT_RC(rc,NULL,"image.connect(capture->output)");
00255             
00256     /* <> Attach the capture image to the live source input of the
00257      * Pipeline so processing is done automatically once the 
00258      * pipeline is started. */
00259     pipeline->setLiveSourceInput(capture->getLiveSourceOutput());
00260     
00261     /* <> Add the filter(s) into the pipeline in the order they will 
00262      * be used */
00263     pipeline->add(gauss);
00264     pipeline->add(convert);
00265     pipeline->add(ddimage);
00266     pipeline->add(mask);
00267     
00268     blob->set(&incolor_limit,&threshold_limit,1,&outcolor_limit,1,1);
00269     pipeline->add(blob);
00270 
00271     rc = blob_data.connect(blob->getLiveBlobOutput());
00272     phPRINT_RC(rc,NULL,"blob_data.connect()");
00273 
00274     /* <> Startup the system */
00275     rc = system.startup();
00276     phPRINT_RC(rc,NULL,"system.startup()");
00277     
00278     /* <> Keep going until all the windows are closed */
00279     while ((system.displaysActive() > 0) || 
00280            (system.capturesActive() > 0))
00281     {
00282         /* Yielding is optional. This gives up the thread's timeslice
00283          * to prevent slow response in other threads. It consumes more
00284          * CPU cycles than sleeping. Use it instead of sleeping if
00285          * this loop is processing anything */
00286         //phYield();
00287         
00288         if ((rc = blob_data.update(phLiveObjectNOWAIT)) == phLiveObjectUPDATED)
00289         {
00290             //blob_data.print_data(minimum_blob_size);
00291             if (blob_data.getTotalBlobs(minimum_blob_size))
00292             {
00293                 time(&timep);
00294                 current_time = localtime_r(&timep,&result);
00295                 
00296                 phPRINT("Motion Start @ %s", ctime_r(&timep,ctime_buf));
00297                 fprintf(logfile,"Motion Start @ %s", ctime_r(&timep,ctime_buf));
00298                         
00299                 if ((monitor_display != NULL) && 
00300                     (!(monitor_display->isOpen())) &&
00301                     (monitor_opened == 0))
00302                 {
00303                     monitor_opened = 1;
00304                     monitor_display->open();
00305                 }
00306                 
00307                 capture_image_count = fps * record_seconds;
00308             }
00309         } 
00310         else
00311         {
00312             phPRINT_RC(rc,NULL,"blob_data.update()");
00313         }
00314 
00315         /* We're going to capture some number of frames ... */
00316         if (capture_image_count > 0)
00317         {
00318             /* Get the latest image */
00319             rc = image.update(phLiveObjectNOWAIT);
00320             phPRINT_RC(rc,NULL,"image.update()");
00321     
00322             if (rc == phLiveObjectUPDATED)
00323             {
00324                 /* decrement the total frames to capture */
00325                 capture_image_count--;
00326 
00327                 if (capture_image_count == 0)
00328                 {
00329                     phPRINT("Motion Stop @ %s", ctime_r(&timep,ctime_buf));
00330                     fprintf(logfile,"Motion Stop @ %s", ctime_r(&timep,ctime_buf));
00331 
00332                     if (monitor_display != NULL)
00333                     {
00334                         monitor_opened = 0;
00335                         monitor_display->close();
00336                     }
00337                 }
00338             
00339                 /* Get the current time for the filename and timestamp */
00340                 time(&timep);
00341  
00342                 /* create the time structure so we can get individual
00343                    fields */
00344                 current_time = localtime_r(&timep,&result);            
00345     
00346                 /* Print the time fields into the string buffer */
00347                 sprintf(timestamp_string,
00348                     "%04d_%02d_%02d_%02d:%02d:%02d",
00349                     current_time->tm_year+1900,
00350                     current_time->tm_mon,
00351                     current_time->tm_mday,
00352                     current_time->tm_hour,
00353                     current_time->tm_min,
00354                     current_time->tm_sec);
00355     
00356                 /* Check to see if the timestamp has changed since the 
00357                  * last frame */
00358                 if (((int64_t)difftime(timep,last_time)) > 0)
00359                 {
00360                     /*
00361                     phPRINT("%lld:%0.6lf:%d:%d\n",
00362                             (int64_t)difftime(timep,last_time),
00363                             difftime(timep,last_time),
00364                             (int32_t)timep,
00365                             (int32_t)last_time);
00366                      */
00367                     last_time = timep;
00368                     frame_index = 0;
00369                 }
00370                 /* If the timestamp hasn't changed than this is the <frame_count>th
00371                    frame in the current second */
00372                 else
00373                 {
00374                     frame_index++;
00375                 }
00376 
00377                 if (save_ppm)
00378                 {
00379                     /* Create the filename for PPM*/
00380                     sprintf(filename,
00381                         "%s_%s_%09d.ppm",
00382                         filename_prefix,
00383                         timestamp_string,
00384                         frame_index);
00385                     for (i = 0; (filename[i] != '\0') && (i < 512); i++ )
00386                         if (filename[i] == ':') filename[i] = '_';
00387 
00388                     /* save the image */
00389                     rc = image.save(filename);
00390                     phPRINT_RC(rc,NULL,"image.save(%s)",filename);
00391                 }
00392 
00393                 if (save_jpeg)
00394                 {
00395                     /* Create the filename for JPG */
00396                     sprintf(filename,
00397                         "%s_%s_%09d.jpg",
00398                         filename_prefix,
00399                         timestamp_string,
00400                         frame_index);
00401                     for (i = 0; (filename[i] != '\0') && (i < 512); i++ )
00402                         if (filename[i] == ':') filename[i] = '_';
00403     
00404                     /* save the image */
00405                     rc = image.save(filename);
00406                     phPRINT_RC(rc,NULL,"image.save(%s)",filename);
00407                 }
00408 
00409                 if (sleeptime > 0)
00410                     phSleep(sleeptime);
00411                 else
00412                     phYield();
00413             }
00414             else
00415             {
00416                 phYield();
00417             }
00418         }
00419         
00420         /* Remove this if block when using this code as an example */
00421         /* Set the loop control value to end the loop when testing */
00422         if (test > 0)
00423         { 
00424             test--;
00425             if (test == 0)
00426             {
00427                 rc = system.shutdown();
00428                 phPRINT_RC(rc,NULL,"system.shutdown()");
00429             }
00430         }
00431         fflush(logfile);
00432     }
00433     /* <> Shutdown the system */
00434     rc = system.shutdown();
00435     phPRINT_RC(rc,NULL,"system.shutdown()");
00436 
00437 error:
00438     if (logfile != NULL) fclose(logfile);
00439 
00440     rc = blob_data.disconnect();
00441     phPRINT_RC(rc,NULL,"blob_data.disconnect()");
00442     
00443     for (i = 0; (i < nDisplays) && (display != NULL); i++)
00444     {
00445         phDelete(display[i]);
00446     }
00447   
00448     phDeleteArray(display);
00449 
00450     phDelete(capture);
00451     /*    
00452     phDelete(sub);
00453     phDelete(add);
00454     phDelete(convert);
00455     phDelete(threshold);
00456     phDelete(mean);
00457     phDelete(gauss);
00458     */
00459     phDelete(convert);
00460     phDelete(ddimage);
00461     phDelete(blob);
00462   
00463     phDelete(pipeline);
00464 
00465     phFree(capture_path);
00466     phDelete(arg_parser);
00467 
00468     return phSUCCESS;
00469 }




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:06 2007 for phission by  doxygen 1.4.4