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 <FLIROverlayExample.h> 00013 #include <stdio.h> 00014 #include <math.h> 00015 #include <phission.h> 00016 00017 /* ------------------------------------------------------------------------ */ 00018 int glbl_disable_displays = 0; 00019 int glbl_save_images = 0; 00020 00021 00022 /* ------------------------------------------------------------------------ */ 00023 int usage() 00024 { 00025 printf("\n\n\tUsage:\n"); 00026 printf("\t\t\t--help\t\t\tdisplay usage\n"); 00027 printf("\t\t\t--nodisplay\tdisable the allocation, opening or any use of a display.\n"); 00028 printf("\t\t\t--saveimages\tsave the frames to file\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 class key_matte_threshold_Filter : public phFilter 00036 { 00037 private: 00038 int m_value; 00039 00040 protected: 00041 int filter(); 00042 00043 public: 00044 key_matte_threshold_Filter(int value = 0); 00045 ~key_matte_threshold_Filter(); 00046 00047 int set(int value = 0); 00048 00049 phFilter *cloneFilter(); 00050 00051 }; 00052 00053 00054 /* ---------------------------------------------------------------------- */ 00055 key_matte_threshold_Filter::key_matte_threshold_Filter(int value) : 00056 phFilter("key_matte_threshold_Filter") 00057 00058 { 00059 this->m_format = (phImageGREY8); 00060 00061 this->set(value); 00062 } 00063 00064 /* ---------------------------------------------------------------------- */ 00065 key_matte_threshold_Filter::~key_matte_threshold_Filter() 00066 { 00067 } 00068 00069 /* ------------------------------------------------------------------------ */ 00070 phFilter *key_matte_threshold_Filter::cloneFilter() 00071 { 00072 return (phFilter *)new key_matte_threshold_Filter( this->m_value 00073 ); 00074 } 00075 00076 /* ---------------------------------------------------------------------- */ 00077 int key_matte_threshold_Filter::set(int value) 00078 { 00079 this->m_value = value; 00080 00081 return phSUCCESS; 00082 } 00083 00084 /* ---------------------------------------------------------------------- */ 00085 int key_matte_threshold_Filter::filter() 00086 { 00087 phFUNCTION("key_matte_threshold_Filter::filter") 00088 00089 unsigned int row = 0; 00090 unsigned int pixel = 0; 00091 unsigned int index = 0; /* r:0 g:1 b:2 */ 00092 const uint32_t ai = 3; 00093 uint32_t pv = 0; 00094 static float scale_log_range_factor = 255 / log(255); 00095 00096 unsigned int x, y, d = 0; 00097 00098 /* Begin filter */ 00099 rc = this->m_workspaceImage->convert(phImageRGBA32); 00100 phPRINT_RC(rc,NULL,"Image->convert(outputFormat) failed."); 00101 00102 /* rc == 0 means conversion happened */ 00103 /* rc == 1 means no conversion */ 00104 if (rc == phSUCCESS) 00105 { 00106 rc = this->setFilterVars(); 00107 phPRINT_RC(rc,NULL,"setFilterVars"); 00108 } 00109 00110 for ( y = 0; y < height; y++ ) 00111 { 00112 row = y * width; 00113 for ( x = 0; x < width; x++ ) 00114 { 00115 pixel = (x+row)*depth; 00116 pv = (Image)[pixel+index]; 00117 for (d = 0; d < depth; d++) 00118 { 00119 if (d != index) (Image)[pixel+d] = 0; 00120 } 00121 00122 if (pv < this->m_value) 00123 { 00124 (Image)[pixel+ai/* alpha channel = 3 */] = 0; 00125 } 00126 else 00127 { 00128 pv -= this->m_value; 00129 //pv *= pv; 00130 pv = log(pv) * scale_log_range_factor; 00131 //pv += 100; 00132 //if (pv > 0) pv /= 255; 00133 if (pv > 255) pv = 255; 00134 (Image)[pixel+ai/* alpha channel = 3 */] = pv; /* 185 */ 00135 } 00136 } 00137 } 00138 00139 return phSUCCESS; 00140 } 00141 00142 00143 /* ------------------------------------------------------------------------ */ 00144 class invert_Filter : public phFilter 00145 { 00146 private: 00147 uint8_t *m_pixelbuf; 00148 uint32_t m_pixelbuf_size; 00149 00150 protected: 00151 int filter(); 00152 00153 public: 00154 invert_Filter(); 00155 ~invert_Filter(); 00156 00157 phFilter *cloneFilter(); 00158 00159 00160 }; 00161 00162 /* ---------------------------------------------------------------------- */ 00163 /* 00164 00165 (int channel, int value) */ 00166 /* ---------------------------------------------------------------------- */ 00167 invert_Filter::invert_Filter() : 00168 phFilter("invert_Filter") 00169 00170 { 00171 this->m_format = phImageValidFormatMask; 00172 this->m_pixelbuf = NULL; 00173 this->m_pixelbuf_size = 0; 00174 } 00175 00176 /* ---------------------------------------------------------------------- */ 00177 invert_Filter::~invert_Filter() 00178 { 00179 } 00180 00181 /* ------------------------------------------------------------------------ */ 00182 phFilter *invert_Filter::cloneFilter() 00183 { 00184 return (phFilter *)new invert_Filter(); 00185 } 00186 00187 /* ---------------------------------------------------------------------- */ 00188 int invert_Filter::filter() 00189 { 00190 phFUNCTION("invert_Filter::filter") 00191 00192 uint8_t *ptr = NULL; 00193 uint8_t *ptr2 = NULL; 00194 uint32_t pixel_half = (width * height) / 2; 00195 /* defined before being called: 00196 * width 00197 * height 00198 * depth 00199 * Image 00200 */ 00201 00202 phDALLOC(this->m_pixelbuf, 00203 this->m_pixelbuf_size, 00204 depth, 00205 uint8_t); 00206 00207 /* Begin Filter */ 00208 ptr = Image; 00209 ptr2 = Image + ((width * height * depth ) - (depth)); 00210 for (int32_t pixel = 0; pixel < pixel_half; pixel++ , ptr += depth, ptr2 -= depth) 00211 { 00212 phMemcpy(this->m_pixelbuf,ptr2,depth * sizeof(uint8_t)); 00213 phMemcpy(ptr2,ptr,depth * sizeof(uint8_t)); 00214 phMemcpy(ptr,this->m_pixelbuf,depth * sizeof(uint8_t)); 00215 } 00216 00217 /* End Filter */ 00218 00219 /* make sure to free up any space here, not including Image */ 00220 00221 return phSUCCESS; 00222 00223 /* Comment this back in if you use any macros that jump to here, ie phCHECK_RC, 00224 * or phCHECK_PTR */ 00225 00226 error: 00227 /* make sure to free up any space here, not including Image */ 00228 00229 return phFAIL; 00230 00231 } 00232 00233 00234 /* ------------------------------------------------------------------------ */ 00235 class phEffectsThread : public phThread 00236 { 00237 private: 00238 phImage *m_input[2]; 00239 uint32_t m_input_count; 00240 00241 float m_alpha; 00242 00243 uint32_t m_output_format; 00244 phImage *m_output; 00245 00246 uint8_t *m_buf; 00247 uint32_t m_buf_size; 00248 00249 protected: 00250 int run(); 00251 int wakeup(); 00252 00253 public: 00254 phEffectsThread( phLiveObject *one, phLiveObject *two, uint32_t output_format ); 00255 ~phEffectsThread(); 00256 00257 int mosaic_images( phImage *one, phImage *two, phImage *out); 00258 int overlay_images( phImage *one, phImage *two, 00259 phImage *out, 00260 int32_t move_x, 00261 int32_t move_y ); 00262 00263 phLiveObject *getLiveSourceOutput() { return this->m_output; }; 00264 }; 00265 00266 /* ------------------------------------------------------------------------ */ 00267 phEffectsThread::phEffectsThread( phLiveObject *one, 00268 phLiveObject *two, 00269 uint32_t output_format ) 00270 { 00271 phFUNCTION("phEffectsThread::phEffectsThread") 00272 int locked = 0; 00273 00274 phTHIS_LOOSE_LOCK(locked); 00275 00276 this->setName("phEffectsThread"); 00277 this->m_input[0] = (phImage *)one; 00278 this->m_input[1] = (phImage *)two; 00279 this->m_input_count = 2; 00280 00281 this->m_alpha = 0.00; 00282 00283 this->m_output_format = output_format; 00284 00285 this->m_output = new phImage(); 00286 00287 this->m_buf = NULL; 00288 this->m_buf_size = 0; 00289 00290 phTHIS_LOOSE_UNLOCK(locked); 00291 } 00292 00293 /* ------------------------------------------------------------------------ */ 00294 phEffectsThread::~phEffectsThread() 00295 { 00296 phFree(this->m_buf); 00297 this->m_buf_size = 0; 00298 phDelete(this->m_output); 00299 } 00300 00301 /* ------------------------------------------------------------------------ */ 00302 int phEffectsThread::mosaic_images( phImage *one, phImage *two, phImage *out ) 00303 { 00304 phFUNCTION("phEffectsThread::mosaic_images") 00305 int locked = 0; 00306 uint8_t *ptr[2]; 00307 uint32_t height[2]; 00308 uint32_t width[2]; 00309 uint32_t offset; 00310 uint32_t output_height = 0; 00311 uint32_t output_width = 0; 00312 00313 uint32_t i = 0; 00314 uint32_t j = 0; 00315 00316 uint32_t depth = 0; 00317 00318 if ((one == NULL) || 00319 (two == NULL) || 00320 (one->isNull()) || 00321 (two->isNull())) 00322 { 00323 return phFAIL; 00324 } 00325 00326 phTHIS_LOCK(locked); 00327 00328 /* Convert the input images to one color space */ 00329 rc = one->convert(this->m_output_format); 00330 phPRINT_RC(rc,NULL,"one->convert(%s)", 00331 phImageFormatToString(this->m_output_format)); 00332 00333 rc = two->convert(this->m_output_format); 00334 phPRINT_RC(rc,NULL,"two->convert(%s)", 00335 phImageFormatToString(this->m_output_format)); 00336 00337 /* Make sure our buffer is large enough */ 00338 phDALLOC_RESIZE(this->m_buf, 00339 this->m_buf_size, 00340 one->getSize() + two->getSize(), 00341 uint8_t ); 00342 00343 depth = phImageFormatToDepth(this->m_output_format); 00344 00345 /* Get the pointers to the image only after the conversions */ 00346 ptr[0] = (uint8_t*)one->getImage(); 00347 ptr[1] = (uint8_t*)two->getImage(); 00348 00349 height[0] = one->getHeight(); 00350 height[1] = two->getHeight(); 00351 00352 width[0] = one->getWidth(); 00353 width[1] = two->getWidth(); 00354 00355 output_height = (height[0] > height[1] ? height[0] : height[1]); 00356 output_width = width[0] + width[1]; 00357 00358 offset = 0; 00359 for (j = 0; j < this->m_input_count; j++) 00360 { 00361 for (i = 0; i < height[j]; i++ ) 00362 { 00363 phMemcpy(&(this->m_buf[((i * output_width) + offset) * depth]), 00364 &(ptr[j][i * width[j] * depth]), 00365 width[j] * depth); 00366 } 00367 offset += width[j]; 00368 } 00369 00370 rc = out->setImage(output_width, 00371 output_height, 00372 this->m_output_format, 00373 this->m_buf_size, 00374 this->m_buf); 00375 phCHECK_RC(rc,NULL,"out->setImage"); 00376 00377 phTHIS_UNLOCK(locked); 00378 00379 return phSUCCESS; 00380 error: 00381 00382 phTHIS_ERROR_UNLOCK(locked); 00383 00384 return phFAIL; 00385 } 00386 00387 /* ------------------------------------------------------------------------ */ 00388 int phEffectsThread::overlay_images( phImage *one, phImage *two, 00389 phImage *out, 00390 int32_t move_x, 00391 int32_t move_y ) 00392 { 00393 phFUNCTION("phEffectsThread::overlay_images") 00394 int locked = 0; 00395 00396 float alpha = 0.0; 00397 float alphainv = 0.0; 00398 const int32_t ai = 3; 00399 00400 float tmp = 0; 00401 uint8_t *outptr = NULL; 00402 uint8_t *ptr[2]; 00403 int32_t height[2]; 00404 int32_t width[2]; 00405 int32_t output_width = 0; 00406 int32_t output_height = 0; 00407 int32_t offset_x = 0; 00408 int32_t offset_y = 0; 00409 int32_t offset_remainder_x[2]; 00410 int32_t offset_remainder_y[2]; 00411 int32_t offset_pixel_x[2]; 00412 int32_t offset_pixel_y[2]; 00413 00414 int32_t i = 0; 00415 int32_t j = 0; 00416 int32_t d = 0; 00417 00418 uint32_t depth = 0; 00419 int32_t width_limit = 0; 00420 int32_t height_limit = 0; 00421 00422 if ((one == NULL) || (two == NULL) || (one->isNull()) || (two->isNull())) 00423 { 00424 return phFAIL; 00425 } 00426 00427 phTHIS_LOCK(locked); 00428 00429 /* Convert the input images to one color space */ 00430 rc = one->convert(this->m_output_format); 00431 phPRINT_RC(rc,NULL,"one->convert(%s)", 00432 phImageFormatToString(this->m_output_format)); 00433 00434 two->resize(70,50); 00435 rc = two->convert(this->m_output_format); 00436 phPRINT_RC(rc,NULL,"two->convert(%s)", 00437 phImageFormatToString(this->m_output_format)); 00438 00439 /* 00440 rc = two->resize(one->getWidth(),one->getHeight()); 00441 phPRINT_RC(rc,NULL,"two->resize"); 00442 */ 00443 /* Make sure our buffer is large enough */ 00444 phDALLOC_RESIZE(this->m_buf, 00445 this->m_buf_size, 00446 one->getSize(), 00447 uint8_t ); 00448 00449 depth = phImageFormatToDepth(this->m_output_format); 00450 00451 outptr = this->m_buf; 00452 /* Get the pointers to the image only after the conversions */ 00453 ptr[0] = (uint8_t*)one->getImage(); 00454 ptr[1] = (uint8_t*)two->getImage(); 00455 00456 height[0] = one->getHeight(); 00457 height[1] = two->getHeight(); 00458 00459 width[0] = one->getWidth(); 00460 width[1] = two->getWidth(); 00461 00462 output_width = one->getWidth(); 00463 output_height = one->getHeight(); 00464 00465 /* half width diff == the offset of the X coord of the upper left 00466 * corner of the smaller image within the larger image */ 00467 offset_x = width[0] - width[1]; 00468 if (offset_x > 0) offset_x = offset_x / 2; 00469 00470 /* half height diff == the offset of the Y coord of the upper 00471 * left corner of the smaller image within the larger image */ 00472 offset_y = height[0] - height[1]; 00473 if (offset_y > 0) offset_y = offset_y / 2; 00474 00475 /* The offset pixel is the pixel within the larger image and the 00476 * output image where the overlayed smaller image will start */ 00477 offset_pixel_x[0] = offset_x + move_x; 00478 offset_pixel_y[0] = offset_y + move_y; 00479 offset_remainder_x[0] = offset_x - move_x; 00480 offset_remainder_y[0] = offset_y - move_y; 00481 offset_pixel_y[1] = 0; 00482 offset_pixel_x[1] = 0; 00483 00484 /* if the offset pixel in the larger image is less than 0, we'll 00485 * index into the smaller image instead of the larger image */ 00486 width_limit = width[1]; 00487 if (offset_pixel_x[0] < 0) 00488 { 00489 offset_pixel_x[1] = -1 * offset_pixel_x[0]; 00490 offset_pixel_x[0] = 0; 00491 width_limit -= offset_pixel_x[1]; 00492 offset_remainder_x[1] = width_limit; 00493 } 00494 00495 height_limit = height[1]; 00496 if (offset_pixel_y[0] < 0) 00497 { 00498 offset_pixel_y[1] = -1 * offset_pixel_y[0]; 00499 offset_pixel_y[0] = 0; 00500 height_limit -= offset_pixel_y[1]; 00501 } 00502 00503 /* Copy all the rows of the image that won't have overlayed data into the 00504 * output image buffer */ 00505 phMemcpy(outptr,ptr[0],offset_pixel_y[0] * width[0] * depth); 00506 00507 /* Index into the buffers. 00508 * Index into the larger buffer and output buffer to the row where 00509 * the overlay will begin */ 00510 ptr[0] += offset_pixel_y[0] * width[0] * depth; 00511 ptr[1] += offset_pixel_y[1] * width[1] * depth; 00512 outptr += offset_pixel_y[0] * output_width * depth; 00513 00514 /* This loops over the two input images and overlays them into 00515 * the output image */ 00516 /* we only need to loop through the entirety of the smaller image */ 00517 for (j = 0; j < height_limit; j++) 00518 { 00519 phMemcpy(outptr,ptr[0],offset_pixel_x[0] * 2 * depth); 00520 ptr[0] += (offset_pixel_x[0] * depth); 00521 ptr[1] += (offset_pixel_x[1] * depth); 00522 outptr += (offset_pixel_x[0] * depth); 00523 00524 for (i = 0; i < width_limit; i++ ) 00525 { 00526 alpha = ((float)ptr[1][ai]) / 255.0; 00527 alphainv = 1.0 - alpha; 00528 00529 for (d = 0; d < 3; d++ ) 00530 { 00531 tmp = ((*ptr[0]) * alphainv) + ((*ptr[1]) * alpha); 00532 if (tmp < 0) tmp = 0; 00533 *outptr = (uint8_t)(tmp > 255 ? 255 : tmp); 00534 ptr[0]++; ptr[1]++; outptr++; 00535 } 00536 00537 outptr++; 00538 ptr[0]++; 00539 ptr[1]++; 00540 } 00541 00542 phMemcpy(outptr,ptr[0],offset_remainder_x[0] * 2 * depth); 00543 ptr[0] += (offset_remainder_x[0] * depth); 00544 outptr += (offset_remainder_x[0] * depth); 00545 } 00546 00547 phMemcpy(outptr,ptr[0],offset_remainder_y[0] * width[0] * depth); 00548 00549 rc = out->setImage(output_width, 00550 output_height, 00551 this->m_output_format, 00552 this->m_buf_size, 00553 this->m_buf); 00554 phCHECK_RC(rc,NULL,"out->setImage"); 00555 00556 phTHIS_UNLOCK(locked); 00557 00558 return phSUCCESS; 00559 error: 00560 00561 phTHIS_ERROR_UNLOCK(locked); 00562 00563 return phFAIL; 00564 } 00565 00566 /* ------------------------------------------------------------------------ */ 00567 int phEffectsThread::run() 00568 { 00569 phFUNCTION("phEffectsThread::run") 00570 phImage local_copy[2]; 00571 int32_t offset_x = 5; 00572 int32_t offset_y = -45; 00573 uint32_t i = 0; 00574 uint32_t counter = 0; 00575 int32_t direction = 1; 00576 00577 for (i = 0; i < 2; i++ ) 00578 { 00579 rc = local_copy[i].connect(this->m_input[i]); 00580 phCHECK_RC(rc,NULL,"this->local_copy[%d].connect(%p)",i,this->m_input[i]); 00581 } 00582 00583 rc = this->signal_running(); 00584 phCHECK_RC(rc,NULL,"this->signal_running"); 00585 00586 while (this->isRunning()) 00587 { 00588 for (i = 0; i < 2; i++ ) 00589 { 00590 rc = local_copy[i].update(); 00591 phPRINT_RC(rc,NULL,"this->local_copy[%d].update()",i); 00592 } 00593 #if 0 00594 rc = this->mosaic_images(&(local_copy[0]),&(local_copy[1]),this->m_output); 00595 phPRINT_RC(rc,NULL,"this->mosaic_images"); 00596 #else 00597 rc = this->overlay_images(&(local_copy[0]), 00598 &(local_copy[1]), 00599 this->m_output, 00600 offset_x, 00601 offset_y ); 00602 phPRINT_RC(rc,NULL,"this->mosaic_images"); 00603 #endif 00604 00605 if (counter == 0) 00606 { 00607 if (this->m_alpha >= 1.00) 00608 direction = -1; 00609 if (this->m_alpha <= 0.00) 00610 direction = 1; 00611 00612 this->m_alpha += 0.1 * direction; 00613 counter = 0; 00614 } 00615 else 00616 { 00617 counter++; 00618 } 00619 } 00620 00621 for (i = 0; i < 2; i++ ) 00622 { 00623 rc = local_copy[i].disconnect(); 00624 phPRINT_RC(rc,NULL,"this->local_copy[%d].disconnect()",i); 00625 } 00626 00627 return phSUCCESS; 00628 error: 00629 rc = this->signal_error(); 00630 phPRINT_RC(rc,NULL,"this->signal_error"); 00631 00632 return phFAIL; 00633 } 00634 00635 /* ------------------------------------------------------------------------ */ 00636 int phEffectsThread::wakeup() 00637 { 00638 phFUNCTION("phEffectsThread::wakeup") 00639 uint32_t i = 0; 00640 00641 for (i = 0; i < 2; i++ ) 00642 { 00643 rc = this->m_input[i]->wakeup_clients(); 00644 phCHECK_RC(rc,NULL,"this->m_input[%d]->wakeup_clients();",i); 00645 } 00646 00647 return phSUCCESS; 00648 error: 00649 return phFAIL; 00650 } 00651 00652 /* ------------------------------------------------------------------------ */ 00653 int main(int argc, char *argv[] ) 00654 { 00655 phFUNCTION("main") 00656 00657 int displaysOpen= 1; 00658 00659 unsigned int i = 0; 00660 unsigned int image_count = 50; 00661 char *filename = NULL; 00662 char savefilename[255]; 00663 00664 phDisplayInterface *display = NULL; 00665 00666 int count = 0; 00667 phImage image; 00668 float fps = 0.0; 00669 float last_fps = 0.0; 00670 00671 /* Utility class to ease the starting and stopping of displays, captures and 00672 * pipelines */ 00673 phSystem system; 00674 phPipeline *pipeline = new phPipeline(); 00675 phPipeline *pipeline2 = new phPipeline(); 00676 invert_Filter *invert = new invert_Filter(); 00677 key_matte_threshold_Filter *key_matte = new key_matte_threshold_Filter(120); 00678 //phAvcodecSource *capture = new phAvcodecSource(); 00679 V4LCapture *capture = new V4LCapture(); 00680 V4LCapture *capture2 = new V4LCapture(); 00681 00682 phEffectsThread effects_thread(pipeline->getLiveSourceOutput(), 00683 pipeline2->getLiveSourceOutput(), 00684 phImageRGBA32); 00685 00686 /* Remove the code below when using this code as an example. 00687 * 00688 * This just checks whether "--test" has been specified with 00689 * a time value argument. It's for testing all the examples 00690 * without the need for human intervention. */ 00691 int test = 0; 00692 00693 phArgTable arg_parser; 00694 00695 /* Setup and parse all the arguments */ 00696 rc = arg_parser.add("--test", &test, phARG_INT); 00697 phCHECK_RC(rc,NULL,"arg_parser.add"); 00698 rc = arg_parser.add("--nodisplay", (void *)&glbl_disable_displays, phARG_BOOL); 00699 phCHECK_RC(rc,NULL,"arg_parser.add"); 00700 rc = arg_parser.add("--saveimages", (void *)&glbl_save_images, phARG_BOOL); 00701 phCHECK_RC(rc,NULL,"arg_parser.add"); 00702 rc = arg_parser.add("--help",(void *)&usage, phARG_FUNC); 00703 phCHECK_RC(rc,NULL,"arg_parser.add"); 00704 00705 rc = arg_parser.parse(argc,argv); 00706 phCHECK_RC(rc,NULL,"arg_parser.parse"); 00707 00708 /* Pipeline 1 */ 00709 rc = pipeline->setLiveSourceInput(capture->getOutput()); 00710 phCHECK_RC(rc,NULL,"pipeline->setLiveSourceInput"); 00711 00712 rc = pipeline->add(invert); 00713 phCHECK_RC(rc,NULL,"pipeline->add"); 00714 00715 rc = system.add(pipeline); 00716 phCHECK_RC(rc,NULL,"system.add"); 00717 00718 /* Pipeline 2 */ 00719 rc = pipeline2->setLiveSourceInput(capture2->getOutput()); 00720 phCHECK_RC(rc,NULL,"pipeline2->setLiveSourceInput"); 00721 00722 rc = pipeline2->add(key_matte); 00723 phCHECK_RC(rc,NULL,"pipeline2->add"); 00724 00725 rc = system.add(pipeline2); 00726 phCHECK_RC(rc,NULL,"system.add"); 00727 00728 00729 /* Set up the capture parameters */ 00730 capture->set ( 320, 240, "/dev/video0" ); 00731 capture->setChannel ( 0 ); 00732 capture->setFormat ( phImageRGBA32 ); 00733 00734 rc = system.add(capture); 00735 phCHECK_RC(rc,NULL,"system.add(capture:%p)",capture); 00736 00737 capture2->set ( 320, 240, "/dev/video2" ); 00738 capture2->setChannel ( 0 ); 00739 capture2->setFormat ( phImageGREY8 ); 00740 00741 rc = system.add(capture2); 00742 phCHECK_RC(rc,NULL,"system.add(capture2:%p)",capture2); 00743 00744 /* TODO: init capture */ 00745 if (glbl_disable_displays == 0) 00746 { 00747 #if 0 00748 display = new X11Display(capture->getWidth(), 00749 capture->getHeight(), 00750 "phAvcodecSourceTest"); 00751 phCHECK_PTR(display,"new","new X11Display failed."); 00752 00753 display->setLiveSourceInput(capture->getLiveSourceOutput()); 00754 #else 00755 display = new X11Display(320,240, 00756 "FLIROverlayExample"); 00757 phCHECK_PTR(display,"new","new X11Display failed."); 00758 00759 display->setLiveSourceInput(effects_thread.getLiveSourceOutput()); 00760 #endif 00761 rc = system.addDisplay(display); 00762 } 00763 00764 rc = system.add(&effects_thread); 00765 phCHECK_RC(rc,NULL,"system.add(&effects_thread)"); 00766 00767 if (glbl_save_images) 00768 { 00769 rc = image.connect(effects_thread.getLiveSourceOutput()); 00770 phCHECK_RC(rc,NULL,"image.connect"); 00771 } 00772 00773 /* startup */ 00774 rc = system.startup(); 00775 phPRINT_RC(rc,NULL,"system.startup()"); 00776 00777 // now loop continuously for as long as we have a display open and a frame available from the avi file 00778 while ((displaysOpen) && (system.capturesActive())) 00779 { 00780 if (glbl_disable_displays == 0) 00781 { 00782 displaysOpen = 0; 00783 if (system.displaysOpen()) 00784 { 00785 displaysOpen = 1; 00786 } 00787 } 00788 00789 /* Remove this if block when using this code as an example */ 00790 /* Set the loop control value to end the loop when testing */ 00791 if (test > 0) 00792 { 00793 /* loop once through for this test */ 00794 if (i == (image_count - 1)) 00795 { 00796 displaysOpen = 0; 00797 } 00798 } 00799 00800 if (glbl_save_images) 00801 { 00802 sprintf(savefilename,"jpegs/flir%09d.jpg",count); 00803 count++; 00804 00805 rc = image.update(); 00806 phPRINT_RC(rc,NULL,"image.update"); 00807 00808 if (rc == phLiveObjectUPDATED) 00809 { 00810 rc = image.save(savefilename); 00811 phPRINT_RC(rc,NULL,"image.save"); 00812 } 00813 } 00814 else 00815 { 00816 phMSleep(100); 00817 } 00818 00819 fps = display->getImageWindow()->getFps(); 00820 if (fps != last_fps) 00821 { 00822 last_fps = fps; 00823 phPRINT("%f\n", fps); 00824 } 00825 } 00826 00827 error: 00828 rc = system.shutdown(); 00829 phPRINT_RC(rc,NULL,"system.shutdown()"); 00830 00831 phDelete(display); 00832 phDelete(capture); 00833 phDelete(capture2); 00834 00835 // free up the filename string allocation 00836 phFree(filename); 00837 00838 return phSUCCESS; 00839 }
| Copyright (C) 2002 - 2007 |
Philip D.S. Thoren ( pthoren@users.sourceforge.net ) University Of Massachusetts at Lowell Robotics Lab |
|
1.4.4