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

EffectsTest.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 <EffectsTest.h>
00013 #include <stdio.h>
00014 #include <phission.h>
00015 
00016 /* ------------------------------------------------------------------------ */
00017 int glbl_disable_displays = 0;
00018 int glbl_preload_images = 1;
00019 
00020 /* ------------------------------------------------------------------------ */
00021 int usage()
00022 {
00023     printf("\n\n\tUsage:\n");
00024     printf("\t\t\t--delay <delay value in microseconds>\tdelay between frame updates\n");
00025     printf("\t\t\t--fps <fps>\t\tframes per second speed for the displaying of the video.\n");
00026     printf("\t\t\t--loop <value>\tloop the video <value> times; -1 for infinity\n");
00027     printf("\t\t\t--help\t\t\tdisplay usage\n");
00028     printf("\t\t\t--nodisplay\tdisable the allocation, opening or any use of a display.\n");
00029     printf("\t\t\t--test <value>\tload 'value' number of frames/files/images\n");
00030     printf("\t\t\t--file <avi_data_file>\t\t\tavi source (required)\n");
00031     printf("\n\n");
00032     exit(1);
00033 }
00034 
00035 
00036 /* ------------------------------------------------------------------------ */
00037 class phEffectsThread : public phThread
00038 {
00039 private:
00040     phImage *m_input[2];
00041     uint32_t m_input_count;
00042     
00043     float   m_alpha;
00044 
00045     uint32_t m_output_format;
00046     phImage *m_output;
00047 
00048     uint8_t *m_buf;
00049     uint32_t m_buf_size;
00050 
00051 protected:
00052     int run();
00053     int wakeup();
00054 
00055 public:
00056     phEffectsThread( phLiveObject *one, phLiveObject *two, uint32_t output_format );
00057     ~phEffectsThread();
00058 
00059     int mosaic_images( phImage *one, phImage *two, phImage *out);
00060     int overlay_images( phImage *one, phImage *two, phImage *out );
00061 
00062     phLiveObject *getLiveSourceOutput() { return this->m_output; };
00063 };
00064 
00065 /* ------------------------------------------------------------------------ */
00066 phEffectsThread::phEffectsThread( phLiveObject *one, 
00067                                 phLiveObject *two, 
00068                                 uint32_t output_format )
00069 {
00070     phFUNCTION("phEffectsThread::phEffectsThread")
00071     int locked = 0;
00072 
00073     phTHIS_LOOSE_LOCK(locked);
00074     
00075     this->setName("phEffectsThread");
00076     this->m_input[0] = (phImage *)one;
00077     this->m_input[1] = (phImage *)two;
00078     this->m_input_count = 2;
00079 
00080     this->m_alpha = 0.00;
00081 
00082     this->m_output_format = output_format;
00083 
00084     this->m_output = new phImage();
00085 
00086     this->m_buf = NULL;
00087     this->m_buf_size = 0;
00088 
00089     phTHIS_LOOSE_UNLOCK(locked);
00090 }
00091 
00092 /* ------------------------------------------------------------------------ */
00093 phEffectsThread::~phEffectsThread()
00094 {
00095     phFree(this->m_buf);
00096     this->m_buf_size = 0;
00097     phDelete(this->m_output);
00098 }
00099 
00100 /* ------------------------------------------------------------------------ */
00101 int phEffectsThread::mosaic_images( phImage *one, phImage *two, phImage *out )
00102 {
00103     phFUNCTION("phEffectsThread::mosaic_images")
00104     int locked = 0;
00105     uint8_t *ptr[2];
00106     uint32_t height[2];
00107     uint32_t width[2];
00108     uint32_t offset;
00109     uint32_t output_height = 0;
00110     uint32_t output_width = 0;
00111 
00112     uint32_t i = 0;
00113     uint32_t j = 0;
00114 
00115     uint32_t depth = 0;
00116 
00117     if ((one == NULL) ||
00118         (two == NULL) ||
00119         (one->isNull()) || 
00120         (two->isNull()))
00121     {
00122         return phFAIL;
00123     }
00124     
00125     phTHIS_LOCK(locked);
00126 
00127     /* Convert the input images to one color space */
00128     rc = one->convert(this->m_output_format);
00129     phPRINT_RC(rc,NULL,"one->convert(%s)",
00130             phImageFormatToString(this->m_output_format));
00131     
00132     rc = two->convert(this->m_output_format);
00133     phPRINT_RC(rc,NULL,"two->convert(%s)",
00134             phImageFormatToString(this->m_output_format));
00135    
00136     /* Make sure our buffer is large enough */ 
00137     phDALLOC_RESIZE(this->m_buf,
00138                     this->m_buf_size,
00139                     one->getSize() + two->getSize(),
00140                     uint8_t );
00141     
00142     depth = phImageFormatToDepth(this->m_output_format);
00143     
00144     /* Get the pointers to the image only after the conversions */
00145     ptr[0] = (uint8_t*)one->getImage();
00146     ptr[1] = (uint8_t*)two->getImage();
00147   
00148     height[0] = one->getHeight();
00149     height[1] = two->getHeight();
00150 
00151     width[0] = one->getWidth();
00152     width[1] = two->getWidth();
00153 
00154     output_height = (height[0] > height[1] ? height[0] : height[1]);
00155     output_width = width[0] + width[1];
00156 
00157     offset = 0;
00158     for (j = 0; j < this->m_input_count; j++)
00159     {
00160         for (i = 0; i < height[j]; i++ )
00161         {
00162             phMemcpy(&(this->m_buf[((i * output_width) + offset) * depth]),
00163                      &(ptr[j][i * width[j] * depth]),
00164                      width[j] * depth);
00165         }
00166         offset += width[j];
00167     }
00168 
00169     rc = out->setImage(output_width,
00170                        output_height,
00171                        this->m_output_format,
00172                        this->m_buf_size,
00173                        this->m_buf);
00174     phCHECK_RC(rc,NULL,"out->setImage");
00175     
00176     phTHIS_UNLOCK(locked);
00177 
00178     return phSUCCESS;
00179 error:
00180 
00181     phTHIS_ERROR_UNLOCK(locked);
00182     
00183     return phFAIL;
00184 }
00185 
00186 /* ------------------------------------------------------------------------ */
00187 int phEffectsThread::overlay_images( phImage *one, phImage *two, phImage *out )
00188 {
00189     phFUNCTION("phEffectsThread::mosaic_images")
00190     int locked = 0;
00191     
00192     float alpha = this->m_alpha;
00193     float alphainv = 1.0 - alpha;
00194     
00195     float tmp = 0;
00196     uint8_t *outptr = NULL;
00197     uint8_t *ptr[2];
00198     uint32_t height[2];
00199     uint32_t width[2];
00200     uint32_t offset;
00201     uint32_t output_height = 0;
00202     uint32_t output_width = 0;
00203 
00204     uint32_t i = 0;
00205     uint32_t j = 0;
00206 
00207     uint32_t depth = 0;
00208     uint32_t limit = 0;
00209 
00210     if ((one == NULL) ||
00211         (two == NULL) ||
00212         (one->isNull()) || 
00213         (two->isNull()))
00214     {
00215         return phFAIL;
00216     }
00217     
00218     phTHIS_LOCK(locked);
00219 
00220     /* Convert the input images to one color space */
00221     rc = one->convert(this->m_output_format);
00222     phPRINT_RC(rc,NULL,"one->convert(%s)",
00223             phImageFormatToString(this->m_output_format));
00224     
00225     rc = two->convert(this->m_output_format);
00226     phPRINT_RC(rc,NULL,"two->convert(%s)",
00227             phImageFormatToString(this->m_output_format));
00228    
00229     rc = two->resize(one->getWidth(),one->getHeight());
00230     phPRINT_RC(rc,NULL,"two->resize");
00231    
00232     /* Make sure our buffer is large enough */ 
00233     phDALLOC_RESIZE(this->m_buf,
00234                     this->m_buf_size,
00235                     one->getSize(),
00236                     uint8_t );
00237     
00238     depth = phImageFormatToDepth(this->m_output_format);
00239     
00240     /* Get the pointers to the image only after the conversions */
00241     ptr[0] = (uint8_t*)one->getImage();
00242     ptr[1] = (uint8_t*)two->getImage();
00243   
00244     height[0] = one->getHeight();
00245     height[1] = two->getHeight();
00246 
00247     width[0] = one->getWidth();
00248     width[1] = two->getWidth();
00249 
00250     output_width = one->getWidth();
00251     output_height = one->getHeight();
00252    
00253     limit = one->getWidth() * one->getHeight() * depth;
00254     outptr = this->m_buf;
00255     
00256     for (j = 0; j < limit; j++)
00257     {
00258         tmp = ((*ptr[0]) * alphainv) + ((*ptr[1]) * alpha);
00259         if (tmp < 0) tmp = 0;
00260         *outptr = (uint8_t)(tmp > 255 ? 255 : tmp);
00261         outptr++;
00262         ptr[0]++;
00263         ptr[1]++;
00264     }
00265 
00266     rc = out->setImage(output_width,
00267                        output_height,
00268                        this->m_output_format,
00269                        this->m_buf_size,
00270                        this->m_buf);
00271     phCHECK_RC(rc,NULL,"out->setImage");
00272     
00273     phTHIS_UNLOCK(locked);
00274 
00275     return phSUCCESS;
00276 error:
00277 
00278     phTHIS_ERROR_UNLOCK(locked);
00279     
00280     return phFAIL;
00281 }
00282 
00283 /* ------------------------------------------------------------------------ */
00284 int phEffectsThread::run()
00285 {   
00286     phFUNCTION("phEffectsThread::run") 
00287     phImage local_copy[2];
00288     uint32_t i = 0;
00289     uint32_t counter = 0;
00290     int32_t  direction = 1;
00291     
00292     for (i = 0; i < 2; i++ )
00293     {
00294         rc = local_copy[i].connect(this->m_input[i]);
00295         phCHECK_RC(rc,NULL,"this->local_copy[%d].connect(%p)",i,this->m_input[i]);
00296     }
00297     
00298     rc = this->signal_running();
00299     phCHECK_RC(rc,NULL,"this->signal_running");
00300    
00301     while (this->isRunning())
00302     {    
00303         for (i = 0; i < 2; i++ )
00304         {
00305             rc = local_copy[i].update();
00306             phPRINT_RC(rc,NULL,"this->local_copy[%d].update()",i);
00307         }
00308 #if 0
00309         rc = this->mosaic_images(&(local_copy[0]),&(local_copy[1]),this->m_output);
00310         phPRINT_RC(rc,NULL,"this->mosaic_images");
00311 #else
00312         rc = this->overlay_images(&(local_copy[0]),&(local_copy[1]),this->m_output);
00313         phPRINT_RC(rc,NULL,"this->mosaic_images");
00314 #endif
00315 
00316         if (counter == 0)
00317         {
00318             if (this->m_alpha >= 1.00)
00319                 direction = -1;
00320             if (this->m_alpha <= 0.00)
00321                 direction = 1;
00322                 
00323             this->m_alpha += 0.1 * direction;
00324             counter = 0;
00325         }
00326         else
00327         {
00328             counter++;
00329         }
00330     }
00331 
00332     for (i = 0; i < 2; i++ )
00333     {
00334         rc = local_copy[i].disconnect();
00335         phPRINT_RC(rc,NULL,"this->local_copy[%d].disconnect()",i);
00336     }
00337     
00338     return phSUCCESS;
00339 error:
00340     rc = this->signal_error();
00341     phPRINT_RC(rc,NULL,"this->signal_error");
00342 
00343     return phFAIL;
00344 }
00345 
00346 /* ------------------------------------------------------------------------ */
00347 int phEffectsThread::wakeup()
00348 {
00349     phFUNCTION("phEffectsThread::wakeup")
00350     uint32_t i = 0;
00351     
00352     for (i = 0; i < 2; i++ )
00353     {
00354         rc = this->m_input[i]->wakeup_clients();
00355         phCHECK_RC(rc,NULL,"this->m_input[%d]->wakeup_clients();",i);
00356     }
00357     
00358     return phSUCCESS;
00359 error:
00360     return phFAIL;
00361 }
00362 
00363 /* ------------------------------------------------------------------------ */
00364 int main(int argc, char *argv[] )
00365 {
00366     phFUNCTION("main")
00367 
00368     int             displaysOpen= 1;
00369     
00370     unsigned int    i           = 0;
00371     unsigned int    image_count = 50;
00372     char*           filename = NULL;
00373 
00374     phDisplayInterface *display = NULL;
00375 
00376     int             delay           = 0;
00377     int             fps             = 0;
00378     int             loop            = 0;
00379 
00380     /* Utility class to ease the starting and stopping of displays, captures and
00381      * pipelines */
00382     phSystem        system;
00383     phAvcodecSource *capture    = new phAvcodecSource();
00384     V4LCapture      *capture2   = new V4LCapture();
00385 
00386     phEffectsThread  mosaic(capture->getOutput(),
00387                            capture2->getOutput(),
00388                            phImageRGBA32);
00389    
00390     /* Remove the code below when using this code as an example.
00391      * 
00392      * This just checks whether "--test" has been specified with
00393      * a time value argument. It's for testing all the examples
00394      * without the need for human intervention. */
00395     int             test = 0;
00396 
00397     phArgTable      *arg_parser = new phArgTable();
00398 
00399     /* Setup and parse all the arguments */
00400     rc = arg_parser->add("--delay", &delay, phARG_INT);
00401     phCHECK_RC(rc, NULL, "arg_parser->add");
00402     rc = arg_parser->add("--fps", &fps, phARG_INT);
00403     phCHECK_RC(rc, NULL, "arg_parser->add");
00404     rc = arg_parser->add("--file", &filename, phARG_CHAR);
00405     phCHECK_RC(rc, NULL, "arg_parser->add");
00406     rc = arg_parser->add("--test", &test, phARG_INT);
00407     phCHECK_RC(rc,NULL,"arg_parser->add");
00408     rc = arg_parser->add("--nodisplay", (void *)&glbl_disable_displays, phARG_BOOL);
00409     phCHECK_RC(rc,NULL,"arg_parser->add");
00410     rc = arg_parser->add("--loop",&loop, phARG_INT);
00411     phCHECK_RC(rc,NULL,"arg_parser->add");
00412     rc = arg_parser->add("--help",(void *)&usage, phARG_FUNC);
00413     phCHECK_RC(rc,NULL,"arg_parser->add");
00414     
00415     rc = arg_parser->parse(argc,argv);
00416     phCHECK_RC(rc,NULL,"arg_parser->parse");
00417 
00418     if (filename == NULL)
00419     {
00420         phCHECK_PTR(filename,NULL,"filename not given");
00421     }
00422 
00423     capture->setDelay(delay);
00424     if (fps)
00425         capture->setFps(fps);
00426     capture->setLoop(loop);
00427     capture->setFormat(phImageRGB24);
00428     
00429     rc = capture->setPath(filename);
00430     phCHECK_RC(rc,NULL,"capture->setPath(%s)",filename);
00431   
00432     rc = system.add(capture);
00433     phCHECK_RC(rc,NULL,"system.add(capture:%p)",capture);
00434     
00435     /* Set up the capture parameters */
00436     capture2->set        ( 320, 240, "/dev/video0" );
00437     capture2->setChannel ( 1 );
00438     capture2->setFormat  ( phImageRGB24 );
00439 
00440     rc = system.add(capture2);
00441     phCHECK_RC(rc,NULL,"system.add(capture2:%p)",capture2);
00442 
00443     /* TODO: init capture */
00444     if (glbl_disable_displays == 0)
00445     {
00446 #if 0
00447         display = new X11Display(capture->getWidth(),
00448                                  capture->getHeight(),
00449                                  "phAvcodecSourceTest");
00450         phCHECK_PTR(display,"new","new X11Display failed.");
00451         
00452         display->setLiveSourceInput(capture->getLiveSourceOutput());
00453 #else
00454         display = new X11Display(160,120,
00455                                  "EffectsTest");
00456         phCHECK_PTR(display,"new","new X11Display failed.");
00457         
00458         display->setLiveSourceInput(mosaic.getLiveSourceOutput());
00459 #endif
00460         rc = system.addDisplay(display);
00461     }
00462 
00463     rc = system.add(&mosaic);
00464     phCHECK_RC(rc,NULL,"system.add(&mosaic)");
00465 
00466     /* startup */
00467     rc = system.startup();
00468     phPRINT_RC(rc,NULL,"system.startup()");
00469     
00470     // now loop continuously for as long as we have a display open and a frame available from the avi file
00471     while ((displaysOpen) && (system.capturesActive()))
00472     {
00473         if (glbl_disable_displays == 0)
00474         {
00475             displaysOpen = 0;
00476             if (system.displaysOpen())
00477             {
00478                 displaysOpen = 1;
00479             }
00480         }
00481 
00482         /* Remove this if block when using this code as an example */
00483         /* Set the loop control value to end the loop when testing */
00484         if (test > 0)
00485         { 
00486             /* loop once through for this test */
00487             if (i == (image_count - 1))
00488             {
00489                 displaysOpen = 0;
00490             }
00491         }
00492 
00493         phMSleep(100);
00494     }
00495     
00496  error:
00497     rc = system.shutdown();
00498     phPRINT_RC(rc,NULL,"system.shutdown()");
00499     
00500     phDelete(display);
00501     phDelete(capture);
00502     phDelete(capture2);
00503 
00504     // free up the filename string allocation
00505     phFree(filename);
00506 
00507     phDelete(arg_parser);
00508 
00509     return phSUCCESS;
00510 }




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