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

autoblob_Filter.cpp

Go to the documentation of this file.
00001 /* ---------------------------------------------------------------------------
00002     Phission :
00003         Realtime Vision Processing System
00004 
00005     Copyright (C) 2003-2006 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 #ifdef HAVE_CONFIG_H
00013     #include <phissionconfig.h>
00014 #endif
00015 
00016 #ifdef WIN32
00017     #include <windows.h>
00018 #endif
00019 #include <autoblob_Filter.h>
00020 #include <string.h>
00021 #include <phbase.h>
00022 
00023 #define TIMESTUFF() 0
00024 
00025 /* ---------------------------------------------------------------------- */
00026 autoblob_Filter::autoblob_Filter() :
00027     phFilter("autoblob_Filter")
00028 {
00029     phFUNCTION("autoblob_Filter::autoblob_Filter")
00030     int locked = 0;
00031     
00032     phTHIS_LOOSE_LOCK(locked);
00033     
00034     /* Set the list of acceptable input formats */
00035     /* Can only process/histogram packed image formats; i.e. where all the
00036      * channels are grouped together for each pixel */
00037     this->m_format = phImagePackedFormatMask;
00038    
00039     this->m_incolor         = NULL;
00040     this->m_incolor_size    = 0;
00041     this->m_threshold       = NULL;
00042     this->m_threshold_size  = 0;
00043     this->m_outcolor        = NULL;
00044     this->m_outputFormat    = this->m_inputFormat = phImageNOFORMAT;
00045 
00046     this->m_nColors = 0;
00047 
00048     this->m_data = NULL;
00049     rc = phautoblob_data_new(&(this->m_data));
00050     phPRINT_RC(rc,NULL,"phautoblob_data_new");
00051 
00052     /* Initialize the argument structure that gets passed to
00053      * phautoblob_find_line_segments */
00054     /*
00055     this->m_args.imgptr                = NULL;
00056     this->m_args.width                 = 1;
00057     this->m_args.height                = 1;
00058     this->m_args.depth                 = 1;
00059     this->m_args.format                = phImageNOFORMAT;
00060     this->m_args.color_count           = 0;
00061     */
00062     this->m_args.incolor               = &(this->m_incolor);
00063     this->m_args.threshold             = &(this->m_threshold);
00064     this->m_args.nColors               = &(this->m_nColors);
00065 
00066     this->m_lower_threshold = phColorArray32_new(5,5,5,0);
00067     this->m_upper_threshold = phColorArray32_new(5,5,5,0);
00068     this->m_loop_threshold  = phColorArray32_new(1,0,0,0);
00069     autoblob_Filter::phColor_to_int32_array(this->m_lower_threshold,
00070                                             (int32_t*)this->m_lower_thresh);
00071     autoblob_Filter::phColor_to_int32_array(this->m_upper_threshold,
00072                                             (int32_t*)this->m_upper_thresh);
00073     autoblob_Filter::phColor_to_int32_array(this->m_loop_threshold,
00074                                             (int32_t*)this->m_loop_thresh);
00075     phTHIS_LOOSE_UNLOCK(locked);
00076 }
00077 
00078 /* ---------------------------------------------------------------------- */
00079 autoblob_Filter::autoblob_Filter(phColor    lower_threshold,
00080                                  phColor    upper_threshold,
00081                                  phColor    loop_threshold,
00082                                  phColor    outcolor,
00083                                  int        draw_rects,
00084                                  int        color_blobs,
00085                                  uint32_t   color_min_size ) :
00086     phFilter("autoblob_Filter")
00087 {
00088     phFUNCTION("autoblob_Filter::autoblob_Filter")
00089     int locked = 0;
00090     
00091     phTHIS_LOOSE_LOCK(locked);
00092 
00093     ::autoblob_Filter();
00094    
00095     this->set( lower_threshold, upper_threshold, loop_threshold,
00096                outcolor, draw_rects, color_blobs, color_min_size );
00097     
00098     phTHIS_LOOSE_UNLOCK(locked);
00099 }
00100 
00101 /* ---------------------------------------------------------------------- */
00102 autoblob_Filter::autoblob_Filter(phColor   *incolor,
00103                                  phColor   *threshold,
00104                                  uint32_t   nColors,
00105                                  phColor   *outcolor,
00106                                  int        draw_rects,
00107                                  int        color_blobs,
00108                                  uint32_t   color_min_size ) :
00109     phFilter("autoblob_Filter")
00110 {
00111     phFUNCTION("autoblob_Filter::autoblob_Filter")
00112     int locked = 0;
00113     
00114     phTHIS_LOOSE_LOCK(locked);
00115    
00116     ::autoblob_Filter();
00117    
00118     this->set( incolor, threshold, 
00119                nColors, 
00120                outcolor, 
00121                draw_rects, color_blobs, color_min_size );
00122     
00123     phTHIS_LOOSE_UNLOCK(locked);
00124 }
00125 
00126 /* ---------------------------------------------------------------------- */
00127 autoblob_Filter::~autoblob_Filter()
00128 {
00129     phFUNCTION("autoblob_Filter::~autoblob_Filter")
00130     int locked = 0;
00131     
00132     phTHIS_LOOSE_LOCK(locked);
00133     
00134     rc = phautoblob_data_free(&(this->m_data));
00135     phPRINT_RC(rc,NULL,"phautoblob_data_free");
00136 
00137     phFree(this->m_threshold);
00138     phFree(this->m_incolor);
00139     phFree(this->m_outcolor);
00140     
00141     phTHIS_LOOSE_UNLOCK(locked);
00142 }
00143 
00144 /* ------------------------------------------------------------------------ */
00145 phFilter *autoblob_Filter::cloneFilter()
00146 {
00147     phFUNCTION("autoblob_Filter::cloneFilter")
00148     int locked = 0;
00149 
00150     autoblob_Filter *valret = NULL;
00151     
00152     phTHIS_LOOSE_LOCK(locked);
00153     
00154     if (this->m_autoblob == 0)
00155     {
00156         valret =  new autoblob_Filter(this->m_incolor,
00157                                       this->m_threshold,
00158                                       this->m_nColors,
00159                                       this->m_outcolor,
00160                                       this->m_draw_rects,
00161                                       this->m_color_blobs,
00162                                       this->m_color_min_size
00163                                   );
00164     }
00165     else
00166     {
00167         phColor outcolor = phColorArray32_new(255,0,0,0);
00168         if (this->m_outcolor != NULL)
00169             outcolor = *(this->m_outcolor);
00170         valret =  new autoblob_Filter(this->m_lower_threshold,
00171                                       this->m_upper_threshold,
00172                                       this->m_loop_threshold,
00173                                       outcolor,
00174                                       this->m_draw_rects,
00175                                       this->m_color_blobs,
00176                                       this->m_color_min_size
00177                                       );
00178     }
00179     
00180     phTHIS_LOOSE_UNLOCK(locked);
00181 
00182     return (phFilter *)valret;
00183 }
00184 
00185 /* ---------------------------------------------------------------------- */
00186 int autoblob_Filter::reset()
00187 {
00188     phFUNCTION("autoblob_Filter::reset")
00189     int locked = 0;
00190     
00191     phTHIS_LOOSE_LOCK(locked);
00192    
00193     rc = this->m_blobData.reset();
00194     phPRINT_RC(rc,NULL,"this->m_blobData.reset()");
00195     
00196     rc = this->removeColors();
00197     phPRINT_RC(rc,NULL,"this->removeColors()");
00198     
00199     rc = this->setLowerThreshold(phColorArray32_new(5,5,5,0));
00200     phPRINT_RC(rc,NULL,"this->setLowerThreshold()");
00201 
00202     rc = this->setUpperThreshold(phColorArray32_new(5,5,5,0));
00203     phPRINT_RC(rc,NULL,"this->setUpperThreshold()");
00204     
00205     rc = this->setLoopThreshold(phColorArray32_new(1,0,0,0));
00206     phPRINT_RC(rc,NULL,"this->setLoopThreshold()");
00207 
00208     phTHIS_LOOSE_UNLOCK(locked);
00209 
00210     return phSUCCESS;
00211 }
00212 
00213 /* ---------------------------------------------------------------------- */
00214 int autoblob_Filter::set(phColor    lower_threshold,
00215                          phColor    upper_threshold,
00216                          phColor    loop_threshold )
00217 {
00218     phFUNCTION("autoblob_Filter::set")
00219     int         locked  = 0;
00220     
00221     phTHIS_LOOSE_LOCK(locked);
00222    
00223     rc = this->setLowerThreshold(lower_threshold);
00224     phPRINT_RC(rc,NULL,"this->setLowerThreshold()");
00225 
00226     rc = this->setUpperThreshold(upper_threshold);
00227     phPRINT_RC(rc,NULL,"this->setUpperThreshold()");
00228     
00229     rc = this->setLoopThreshold(loop_threshold);
00230     phPRINT_RC(rc,NULL,"this->setLoopThreshold()");
00231        
00232     this->m_autoblob = 1;
00233     
00234     phTHIS_LOOSE_UNLOCK(locked);
00235 
00236     return phSUCCESS;
00237 error:
00238     phTHIS_ERROR_UNLOCK(locked);
00239 
00240     return phFAIL;
00241 }
00242 
00243 /* ---------------------------------------------------------------------- */
00244 int autoblob_Filter::set(phColor    lower_threshold,
00245                          phColor    upper_threshold,
00246                          phColor    loop_threshold,
00247                          phColor    outcolor,
00248                          int        draw_rects,
00249                          int        color_blobs,
00250                          uint32_t   color_min_size )
00251 {
00252     phFUNCTION("autoblob_Filter::set")
00253     int         locked  = 0;
00254     
00255     phTHIS_LOOSE_LOCK(locked);
00256 
00257     rc = this->set(lower_threshold,upper_threshold,loop_threshold);
00258     phPRINT_RC(rc,NULL,"this->set(phColor,phColor,phColor)");
00259    
00260     rc = this->setOutcolor(outcolor);
00261     phPRINT_RC(rc,NULL,"this->setOutcolor");
00262     
00263     this->m_draw_rects      = draw_rects;
00264     this->m_color_blobs     = color_blobs;
00265     this->m_color_min_size  = color_min_size;
00266   
00267     this->m_autoblob = 1;
00268     
00269     phTHIS_LOOSE_UNLOCK(locked);
00270 
00271     return phSUCCESS;
00272 error:
00273     phTHIS_ERROR_UNLOCK(locked);
00274 
00275     return phFAIL;
00276 }
00277 
00278 /* ---------------------------------------------------------------------- */
00279 int autoblob_Filter::set(phColor    *incolor,
00280                          phColor    *threshold,
00281                          uint32_t   nColors,
00282                          phColor    *outcolor,
00283                          int        draw_rects,
00284                          int        color_blobs,
00285                          uint32_t   color_min_size )
00286 {
00287     phFUNCTION("autoblob_Filter::set")
00288     int         locked  = 0;
00289     uint32_t    i       = 0;
00290     uint32_t    type    = 0;
00291     
00292     phTHIS_LOOSE_LOCK(locked);
00293     
00294     if (nColors > 0)
00295     {
00296         /* check to make sure all the input colors are the same */
00297         type  = incolor[0].type;
00298         for (i = 1; i < nColors; i++ )
00299         {
00300             if ((type != incolor[i].type) && 
00301                 (type != phColorTypeArray) &&
00302                 (incolor[i].type != phColorTypeArray))
00303                       
00304             {
00305                 phCHECK_RC(rc,NULL,"All input colors must be of the same type."
00306                          "Input Color [%d]:%lu doesn't match Input Color [0]:%lu",
00307                          i,(long unsigned)incolor[i].type,(long unsigned)type );
00308             }
00309         }
00310         /* always make sure they have the same amount of memory and
00311          * enough memory for indexing in nColors */
00312         phDALLOC_RESIZE(this->m_incolor,
00313                         this->m_incolor_size,
00314                         nColors,
00315                         phColor );
00316         phDALLOC_RESIZE(this->m_threshold,
00317                         this->m_threshold_size,
00318                         nColors,
00319                         phColor );
00320         
00321         if (incolor != NULL)
00322         {
00323             phMemcpy(this->m_incolor, incolor,
00324                     nColors * sizeof(phColor));
00325         }
00326         
00327         if (threshold != NULL)
00328         {
00329             phMemcpy(this->m_threshold, threshold,
00330                    nColors * sizeof(phColor));
00331         }
00332 
00333         /* This assumes that all the rest of the input colors are the same.
00334          * A assumption based on the fact this function will fail 
00335          * if they aren't all the same. */
00336         /* Not supported */
00337         if ((this->m_incolor[0].type == phColorTypeArray) ||
00338             (this->m_incolor[0].type == phColorTypeYUV9))
00339         {
00340             this->m_inputFormat = phImageNOFORMAT;
00341         }
00342         else
00343         {
00344             this->m_inputFormat = phColorToFormat(this->m_incolor[0]);
00345         }
00346     }
00347     
00348     this->m_nColors = nColors;
00349     
00350     if (outcolor != NULL)
00351     {
00352         rc = this->setOutcolor(*outcolor);
00353         phPRINT_RC(rc,NULL,"this->setOutcolor");
00354     }
00355     
00356     this->m_draw_rects      = draw_rects;
00357     this->m_color_blobs     = color_blobs;
00358     this->m_color_min_size  = color_min_size;
00359 
00360     this->m_autoblob = 0;
00361     
00362     phTHIS_LOOSE_UNLOCK(locked);
00363 
00364     return phSUCCESS;
00365 error:
00366     phTHIS_ERROR_UNLOCK(locked);
00367 
00368     return phFAIL;
00369 }
00370 
00371 /* ---------------------------------------------------------------------- */
00372 int autoblob_Filter::setDrawRects( uint32_t draw_rects )
00373 {
00374     phFUNCTION("autoblob_Filter::setDrawRects")
00375     int locked = 0;
00376     
00377     phTHIS_LOOSE_LOCK(locked);
00378     
00379     this->m_draw_rects      = draw_rects;
00380 
00381     phTHIS_LOOSE_UNLOCK(locked);
00382 
00383     return phSUCCESS;
00384 }
00385 
00386 /* ---------------------------------------------------------------------- */
00387 int autoblob_Filter::setColorBlobs( uint32_t color_blobs )
00388 {
00389     phFUNCTION("autoblob_Filter::setColorBlobs")
00390     int locked = 0;
00391     
00392     phTHIS_LOOSE_LOCK(locked);
00393     
00394     this->m_color_blobs     = color_blobs;
00395 
00396     phTHIS_LOOSE_UNLOCK(locked);
00397 
00398     return phSUCCESS;
00399 }
00400 
00401 /* ---------------------------------------------------------------------- */
00402 int autoblob_Filter::setColorMinSize( uint32_t color_min_size )
00403 {
00404     phFUNCTION("autoblob_Filter::setColorMinSize")
00405     int locked = 0;
00406     
00407     phTHIS_LOOSE_LOCK(locked);
00408 
00409     this->m_color_min_size = color_min_size;
00410     
00411     phTHIS_LOOSE_UNLOCK(locked);
00412 
00413     return phSUCCESS;
00414 }
00415 
00416 /* ---------------------------------------------------------------------- */
00417 int autoblob_Filter::setOutcolor( phColor outcolor )
00418 {
00419     phFUNCTION("autoblob_Filter::setOutcolor")
00420     int locked = 0;
00421     
00422     phTHIS_LOOSE_LOCK(locked);
00423  
00424     phDALLOC_RESIZE(this->m_outcolor,
00425                     this->m_outcolor_size,
00426                     1,
00427                     phColor );
00428     this->m_outcolor[0] = outcolor;
00429  
00430     if ((this->m_outcolor[0].type == phColorTypeArray) |
00431         (this->m_outcolor[0].type == phColorTypeYUV9))
00432     {
00433         this->m_outputFormat = phImageNOFORMAT;
00434     }
00435     else
00436     {
00437         this->m_outputFormat = phColorToFormat(this->m_outcolor[0]);
00438     }
00439     
00440     phTHIS_LOOSE_UNLOCK(locked);
00441 
00442     return phSUCCESS;
00443 error:
00444     phTHIS_ERROR_UNLOCK(locked);
00445 
00446     return phFAIL;
00447 }
00448 
00449 
00450 /* ---------------------------------------------------------------------- */
00451 void autoblob_Filter::phColor_to_int32_array(phColor color,int32_t *array)
00452 {
00453     int i = 0;
00454     if (array != NULL)
00455         for (i = 0; i < phCOLOR_MAXELEMS; i++ )
00456             array[i] = (int32_t)color.array.v[i];
00457 }
00458 
00459 /* ---------------------------------------------------------------------- */
00460 int autoblob_Filter::setAutoBlob( int autoblob )
00461 {
00462     phFUNCTION("autoblob_Filter::setAutoBlob")
00463     int locked = 0;
00464 
00465     phTHIS_LOCK(locked);
00466 
00467     this->m_autoblob = autoblob;
00468 
00469     phTHIS_UNLOCK(locked);
00470 
00471     return phSUCCESS;
00472 error:
00473     phTHIS_ERROR_UNLOCK(locked);
00474 
00475     return phFAIL;
00476 }
00477 /* ---------------------------------------------------------------------- */
00478 int autoblob_Filter::setThresholds( phColor lower_threshold,
00479                                     phColor upper_threshold,
00480                                     phColor loop_threshold )
00481 {
00482     phFUNCTION("autoblob_Filter::setThresholds")
00483     int locked = 0;
00484 
00485     phTHIS_LOCK(locked);
00486 
00487     this->m_lower_threshold = lower_threshold;
00488     autoblob_Filter::phColor_to_int32_array(this->m_lower_threshold,
00489                                             (int32_t*)this->m_lower_thresh);
00490 
00491     this->m_upper_threshold = upper_threshold;
00492     autoblob_Filter::phColor_to_int32_array(this->m_upper_threshold,
00493                                             (int32_t*)this->m_upper_thresh);
00494 
00495     this->m_loop_threshold = loop_threshold;
00496     autoblob_Filter::phColor_to_int32_array(this->m_loop_threshold,
00497                                             (int32_t*)this->m_loop_thresh);
00498 
00499     phTHIS_UNLOCK(locked);
00500 
00501     return phSUCCESS;
00502 error:
00503     phTHIS_ERROR_UNLOCK(locked);
00504 
00505     return phFAIL;
00506 }
00507 /* ---------------------------------------------------------------------- */
00508 int autoblob_Filter::setLowerThreshold( phColor lower_threshold )
00509 {
00510     phFUNCTION("autoblob_Filter::setLowerThreshold")
00511     int locked = 0;
00512 
00513     phTHIS_LOCK(locked);
00514 
00515     this->m_lower_threshold = lower_threshold;
00516     autoblob_Filter::phColor_to_int32_array(this->m_lower_threshold,
00517                                             (int32_t*)this->m_lower_thresh);
00518 
00519     phTHIS_UNLOCK(locked);
00520 
00521     return phSUCCESS;
00522 error:
00523     phTHIS_ERROR_UNLOCK(locked);
00524 
00525     return phFAIL;
00526 }
00527 
00528 /* ---------------------------------------------------------------------- */
00529 int autoblob_Filter::setUpperThreshold( phColor upper_threshold )
00530 {
00531     phFUNCTION("autoblob_Filter::setUpperThreshold")
00532     int locked = 0;
00533 
00534     phTHIS_LOCK(locked);
00535 
00536     this->m_upper_threshold = upper_threshold;
00537     autoblob_Filter::phColor_to_int32_array(this->m_upper_threshold,
00538                                             (int32_t*)this->m_upper_thresh);
00539 
00540     phTHIS_UNLOCK(locked);
00541 
00542     return phSUCCESS;
00543 error:
00544     phTHIS_ERROR_UNLOCK(locked);
00545 
00546     return phFAIL;
00547 }
00548 
00549 /* ---------------------------------------------------------------------- */
00550 int autoblob_Filter::setLoopThreshold( phColor loop_threshold )
00551 {
00552     phFUNCTION("autoblob_Filter::setLoopThreshold")
00553     int locked = 0;
00554 
00555     phTHIS_LOCK(locked);
00556 
00557     this->m_loop_threshold = loop_threshold;
00558     autoblob_Filter::phColor_to_int32_array(this->m_loop_threshold,
00559                                             (int32_t*)this->m_loop_thresh);
00560 
00561     phTHIS_UNLOCK(locked);
00562 
00563     return phSUCCESS;
00564 error:
00565     phTHIS_ERROR_UNLOCK(locked);
00566 
00567     return phFAIL;
00568 }
00569 
00570  
00571 /* ---------------------------------------------------------------------- */
00572 int autoblob_Filter::setColor( phColor incolor,
00573                                phColor threshold )
00574 {
00575     phFUNCTION("autoblob_Filter::setColor")
00576     int locked = 0;
00577     
00578     phTHIS_LOOSE_LOCK(locked);
00579     
00580     this->m_nColors = 0;
00581     if (this->m_nColors == 0)
00582     {
00583         /* This assumes that all the rest of the input colors are the same.
00584          * A assumption based on the fact this function will fail 
00585          * if they aren't all the same. */
00586             
00587         /* Not supported */
00588         if ((incolor.type == phColorTypeArray) ||
00589             (incolor.type == phColorTypeYUV9))
00590         {
00591             this->m_inputFormat = phImageNOFORMAT;
00592         }
00593         else
00594         {
00595             this->m_inputFormat = phColorToFormat(incolor);
00596         }
00597     }
00598 
00599     this->m_nColors++;
00600     phDALLOC_RESIZE(this->m_incolor, this->m_incolor_size,
00601                     this->m_nColors, phColor );
00602     phDALLOC_RESIZE(this->m_threshold, this->m_threshold_size,
00603                     this->m_nColors, phColor );
00604     this->m_incolor[this->m_nColors -1] = incolor;
00605     this->m_threshold[this->m_nColors -1] = threshold;
00606     
00607     phTHIS_LOOSE_UNLOCK(locked);
00608 
00609     return phSUCCESS;
00610 error:
00611     phTHIS_ERROR_UNLOCK(locked);
00612 
00613     return phFAIL;
00614 }
00615 
00616 /* ---------------------------------------------------------------------- */
00617 int autoblob_Filter::addColor(phColor incolor,
00618                               phColor threshold )
00619 {
00620     phFUNCTION("autoblob_Filter::addColor")
00621     int         locked  = 0;
00622     uint32_t    i       = 0;
00623     
00624     phTHIS_LOOSE_LOCK(locked);
00625     
00626     if (this->m_nColors == 0)
00627     {
00628         /* This assumes that all the rest of the input colors are the same.
00629          * A assumption based on the fact this function will fail 
00630          * if they aren't all the same. */
00631             
00632         /* Not supported */
00633         if ((incolor.type == phColorTypeArray) ||
00634             (incolor.type == phColorTypeYUV9))
00635         {
00636             this->m_inputFormat = phImageNOFORMAT;
00637         }
00638         else
00639         {
00640             this->m_inputFormat = phColorToFormat(incolor);
00641         }
00642     }
00643 
00644     this->m_nColors++;
00645     phDALLOC_RESIZE(this->m_incolor, this->m_incolor_size,
00646                     this->m_nColors, phColor );
00647     phDALLOC_RESIZE(this->m_threshold, this->m_threshold_size,
00648                     this->m_nColors, phColor );
00649     this->m_incolor[this->m_nColors -1] = incolor;
00650     this->m_threshold[this->m_nColors -1] = threshold;
00651         
00652     phTHIS_LOOSE_UNLOCK(locked);
00653 
00654     return phSUCCESS;
00655 error:
00656     phTHIS_ERROR_UNLOCK(locked);
00657 
00658     return phFAIL;
00659 }
00660 
00661 /* ---------------------------------------------------------------------- */
00662 int autoblob_Filter::replaceColor(phColor old_incolor,
00663                                   phColor old_threshold,
00664                                   phColor new_incolor,
00665                                   phColor new_threshold )
00666 {
00667     phFUNCTION("autoblob_Filter::replaceColor")
00668     int         locked  = 0;
00669     uint32_t    i       = 0;
00670     uint32_t    replaced= 0;
00671     
00672     phTHIS_LOOSE_LOCK(locked);
00673 
00674     if (this->m_nColors > 0)
00675     {
00676         for (i = 0; (i < this->m_nColors) && (replaced == 0); i++ )
00677         {
00678             if (phColorEqual(this->m_incolor[i],    old_incolor  ) && 
00679                 phColorEqual(this->m_threshold[i],  old_threshold))
00680             {
00681                 this->m_incolor[i] = new_incolor;
00682                 this->m_threshold[i] = new_threshold;
00683 
00684                 /* This assumes that all the rest of the input colors are the same.
00685                  * An assumption based on the fact this function will fail 
00686                  * if they aren't all the same. */
00687                 
00688                 /* Not supported */
00689                 if ((new_incolor.type == phColorTypeArray) ||
00690                     (new_incolor.type == phColorTypeYUV9))
00691                 {
00692                     this->m_inputFormat = phImageNOFORMAT;
00693                 }
00694                 else
00695                 {
00696                     this->m_inputFormat = phColorToFormat(new_incolor);
00697                 }
00698             }
00699             
00700             replaced = 1;
00701         }
00702     }
00703     
00704     phTHIS_LOOSE_UNLOCK(locked);
00705 
00706     return (replaced == 1 ? phSUCCESS : phFAIL);
00707 /*
00708 error:
00709     phTHIS_ERROR_UNLOCK(locked);
00710 
00711     return phFAIL;
00712 */
00713 }
00714 
00715 /* ---------------------------------------------------------------------- */
00716 int autoblob_Filter::removeColor(phColor incolor,
00717                                  phColor threshold )
00718 {
00719     phFUNCTION("autoblob_Filter::removeColor")
00720     int         locked  = 0;
00721     uint32_t    i       = 0;
00722     uint32_t    removed = 0;
00723     
00724     phTHIS_LOOSE_LOCK(locked);
00725 
00726     if (this->m_nColors > 0)
00727     {
00728         for (i = 0; (i < this->m_nColors) && (removed == 0); i++ )
00729         {
00730             if (phColorEqual(this->m_incolor[i],    incolor  ) && 
00731                 phColorEqual(this->m_threshold[i],  threshold))
00732             {
00733                 /* Copy the end of the list over the removed color */
00734                 /* Ex:
00735                  *
00736                  *  [0][1][2][3][4]
00737                  *           ^------remove this
00738                  *           i == 3
00739                  *           m_nColors == 5
00740                  *            copyCount == 5 - ( 3 + 1 ) == 5 - 4 == 1 
00741                  */
00742                              
00743                 uint32_t copyCount = (this->m_nColors - (i+1));
00744 
00745                 if (copyCount > 0)
00746                 {
00747                     phMemcpy(&(this->m_incolor[i]),   &(this->m_incolor[i + 1]),  copyCount);
00748                     phMemcpy(&(this->m_threshold[i]), &(this->m_threshold[i + 1]),copyCount);
00749                 }
00750                 
00751                 this->m_nColors--;
00752 
00753                 if (this->m_nColors > 0)
00754                 {                
00755                     /* This will shrink the memory of the list down if it needs to be */
00756                     phDALLOC_RESIZE(this->m_incolor,    this->m_incolor_size,
00757                                     this->m_nColors,    phColor );
00758                     phDALLOC_RESIZE(this->m_threshold,  this->m_threshold_size,
00759                                     this->m_nColors,    phColor );
00760                 }
00761                 else
00762                 {
00763                     this->m_inputFormat = phImageNOFORMAT;
00764                 }
00765                     
00766                 removed = 1;
00767             }
00768         }
00769     }
00770     
00771     phTHIS_LOOSE_UNLOCK(locked);
00772 
00773     return (removed == 1 ? phSUCCESS : phFAIL);
00774 error:
00775     phTHIS_ERROR_UNLOCK(locked);
00776 
00777     return phFAIL;
00778 }
00779 
00780 /* ---------------------------------------------------------------------- */
00781 int autoblob_Filter::removeColors()
00782 {
00783     phFUNCTION("autoblob_Filter::removeColors")
00784     int locked = 0;
00785     
00786     phTHIS_LOOSE_LOCK(locked);
00787     
00788     phFree(this->m_threshold);
00789     phFree(this->m_incolor);
00790     phFree(this->m_outcolor);
00791 
00792     this->m_nColors         = 0;
00793     this->m_incolor_size    = 0;
00794     this->m_threshold_size  = 0;
00795     this->m_outputFormat    = this->m_inputFormat = phImageNOFORMAT;
00796 
00797     phTHIS_LOOSE_UNLOCK(locked);
00798 
00799     return phSUCCESS;
00800 }
00801 
00802 
00803 /* ---------------------------------------------------------------------- */
00804 int autoblob_Filter::getBlobData( phAutoBlobData &blobData )
00805 {
00806     int rc = 0;
00807 
00808     rc = blobData.copy(this->m_blobData);
00809 
00810     return rc;
00811 }
00812     
00813 /* ---------------------------------------------------------------------- */
00814 phLiveObject *autoblob_Filter::getLiveBlobOutput() 
00815 {
00816     return (phLiveObject *)&(this->m_blobData);
00817 }
00818 
00819 /* ---------------------------------------------------------------------- */
00820 /* Definitions:
00821  *      Line Segment: 
00822  *          a series of horizontal neighboring pixels that match a color 
00823  *          value within a given threshold.
00824  *          Line segments are connected to each other only if they overlap.
00825  *          
00826  *      Blob Group:
00827  *          a group of line segments that can be reached through any 
00828  *          other line segment using the line segment pointer connections
00829  *          made during 
00830  *          
00831  * This filter involves the implementation of several steps:
00832  *
00833  *  1.) Line segment discovery 
00834  *  2.) Line segment connecting
00835  *  3.) Blob identification
00836  *  4.) Image Blob Colorizing 
00837  *  5.) Rectangle outlining of the rectangles
00838  */
00839 /* ---------------------------------------------------------------------- */
00840 int autoblob_Filter::filter()
00841 {
00842     phFUNCTION("autoblob_Filter::blob")
00843 
00844     /* Defined by phFilter:
00845      * width
00846      * height
00847      * depth (for RGB variations only)
00848      * format
00849      * Image
00850      *
00851      * Object is locked prior to calling the filter() method
00852      * */
00853     /*phautoblob_args args;*/
00854     
00855 #if TIMESTUFF()
00856     uint32_t       timestamp = 0;
00857     const uint32_t nStamps = 7;
00858     char *tags[nStamps] = {
00859         "phautoblob_find_line_segments",
00860         "phautoblob_link_line_segments",
00861         "phautoblob_create_blobs",
00862         "phautoblob_sort_blobs",
00863         "phAutoBlobData->setData()",
00864         "phautoblob_color_lines",
00865         "phautoblob_draw_blob_rects"
00866     };
00867     ph_time_db      timedb = NULL;
00868     rc = ph_timedb_alloc(&timedb,"autoblob_Filter");
00869     phPRINT_RC(rc,NULL,"ph_timedb_alloc");
00870 #endif /* TIMESTUFF() */
00871     
00872     phImage     tempImage;
00873     uint8_t    *imgptr          = (uint8_t*)Image;
00874     uint32_t    imgformat       = format;
00875     uint8_t     imgdepth        = depth;
00876     uint32_t    input_format    = this->m_inputFormat;
00877     uint32_t    output_format   = this->m_outputFormat;
00878     uint32_t    final_output_format = this->m_outputFormat;
00879    
00880     /* Make sure there is a color to match against */
00881     if ((this->m_nColors <= 0) && (this->m_autoblob == 0))
00882     {
00883 #if TIMESTUFF() /* phTIME_REPORT_ALL & */
00884         if (timedb)
00885         {
00886             rc = ph_timedb_free(&timedb);
00887             phPRINT_RC(rc,NULL,"ph_timedb_free");
00888         }
00889 #endif
00890         return phFAIL;
00891         /* phCHECK_RC(-1,NULL,"No color to match against"); */
00892     }
00893 
00894     /* Make sure the user properly initialized this filter */
00895     if ((!this->m_autoblob) && (input_format == (uint32_t)phImageNOFORMAT))
00896     {
00897         phERR_PRINT("Warning: input format not set properly.\n");
00898         /*
00899         phCHECK_RC(-1,NULL,"input format not set properly. "
00900                  "Must set the color(s) to match.");
00901                  */
00902     }
00903     
00904     /* 0.) Make sure the input format to the phautoblob_find_line_segments
00905      * function is compatible with the incolor format */
00906     /* if there is no set color, just use the incoming format */
00907     if ((input_format != format) &&
00908         (input_format != (uint32_t)phImageNOFORMAT))
00909     {
00910         rc = tempImage.setImage(*this->m_workspaceImage);
00911         phCHECK_RC(rc,NULL,"Error setting temp image.");
00912         
00913         /* rc == 0 means conversion happened */
00914         /* rc == 1 means no conversion */
00915         rc = tempImage.convert(input_format);
00916         phCHECK_RC(rc,NULL,"Error converting image");
00917         
00918         imgptr      = (uint8_t *)tempImage.getData();        
00919         imgformat   = input_format;
00920         imgdepth    = depth;
00921     }
00922     
00923     /* -------------------------------------------------------------------- */
00924     /* 1.) Find all the line segments in the rows of the image */    
00925     /* -------------------------------------------------------------------- */
00926 #if TIMESTUFF()
00927     rc = ph_timedb_start(timedb,tags[0]);
00928     phPRINT_RC(rc,NULL,"ph_timedb_start");
00929 #endif
00930     /* XXX: Why &imgptr ? */
00931     this->m_args.imgptr    = &imgptr;
00932     this->m_args.width     = width;
00933     this->m_args.height    = height;
00934     this->m_args.depth     = imgdepth;
00935     this->m_args.format    = imgformat;
00936 
00937     if (this->m_autoblob == 0)
00938     {
00939         rc = phautoblob_find_line_segments_color(&this->m_args,
00940                                                  this->m_data);
00941         phCHECK_RC(rc,NULL,"phautoblob_find_line_segments failed.");
00942     }
00943     else
00944     {
00945         phMemcpy(this->m_args.lower_threshold,
00946                  this->m_lower_thresh,
00947                  sizeof(int32_t) * phCOLOR_MAXELEMS);
00948         phMemcpy(this->m_args.upper_threshold,
00949                  this->m_upper_thresh,
00950                  sizeof(int32_t) * phCOLOR_MAXELEMS);
00951         phMemcpy(this->m_args.loop_threshold,
00952                  this->m_loop_thresh,
00953                  sizeof(int32_t) * phCOLOR_MAXELEMS);
00954         
00955         rc = phautoblob_find_line_segments_neighbor(&this->m_args,
00956                                                     this->m_data);
00957         phCHECK_RC(rc,NULL,"phautoblob_find_line_segments failed.");
00958     }
00959     
00960 #if TIMESTUFF()
00961     rc = ph_timedb_stop(timedb);
00962     phPRINT_RC(rc,NULL,"ph_timedb_stop");
00963 #endif
00964  
00965     /* -------------------------------------------------------------------- */
00966     /* 2.) Link the overlapping segments to each other */
00967     /* connects ->left, ->right, ->first/last_down and 
00968      * ->first/last_up pointers to segments that overlap */
00969     /* -------------------------------------------------------------------- */
00970 #if TIMESTUFF()
00971     rc = ph_timedb_start(timedb,tags[1]);
00972     phPRINT_RC(rc,NULL,"ph_timedb_start");
00973 #endif
00974     rc = phautoblob_link_line_segments(&this->m_args, this->m_data );
00975     phPRINT_RC(rc,NULL,"phautoblob_link_line_segments");
00976 #if TIMESTUFF()
00977     rc = ph_timedb_stop(timedb);
00978     phPRINT_RC(rc,NULL,"ph_timedb_stop");
00979 #endif
00980     
00981   
00982     /* -------------------------------------------------------------------- */
00983     /* 3a.) Identify the blobs                                              */
00984     /* -------------------------------------------------------------------- */
00985 #if TIMESTUFF()
00986     rc = ph_timedb_start(timedb,tags[2]);
00987     phPRINT_RC(rc,NULL,"ph_timedb_start");
00988 #endif
00989     rc = phautoblob_create_blobs(width, height, this->m_data );
00990     phPRINT_RC(rc,NULL,"phautoblob_create_blobs");
00991 #if TIMESTUFF()
00992     rc = ph_timedb_stop(timedb);
00993     phPRINT_RC(rc,NULL,"ph_timedb_stop");
00994 #endif
00995 
00996     /* -------------------------------------------------------------------- */
00997     /* 3b.) Color in the matching segments before sorting them */
00998     /* -------------------------------------------------------------------- */
00999 #if TIMESTUFF()
01000     rc = ph_timedb_start(timedb,tags[5]);
01001     phPRINT_RC(rc,NULL,"ph_timedb_start");
01002 #endif
01003     if (this->m_color_blobs)
01004     {
01005         rc = 1;
01006         if (output_format != (uint32_t)phImageNOFORMAT)
01007         {
01008             rc = this->m_workspaceImage->convert(output_format);
01009             phPRINT_RC(rc,NULL,"Image->convert(outputFormat) failed.");
01010         }
01011 
01012         /* rc == 0 means conversion happened */
01013         /* rc == 1 means no conversion */
01014         if (rc == phSUCCESS)
01015         {
01016             rc = this->setFilterVars();
01017             phPRINT_RC(rc,NULL,"setFilterVars");
01018         }
01019             
01020         imgptr = (uint8_t *)Image;
01021         
01022         rc = phautoblob_color_lines(imgptr,width,height,format,
01023                                     this->m_outcolor,
01024                                     this->m_data,
01025                                     this->m_color_min_size,
01026                                     0,
01027                                     phBLOB_DRAW_ALL );
01028         phPRINT_RC(rc,NULL,"phautoblob_color_lines failed.");
01029     }
01030 
01031 #if TIMESTUFF()
01032     rc = ph_timedb_stop(timedb);
01033     phPRINT_RC(rc,NULL,"ph_timedb_stop");
01034 #endif
01035    
01036 
01037     /* -------------------------------------------------------------------- */
01038     /* 3c.) Sort the blobs                                                  */
01039     /* -------------------------------------------------------------------- */
01040 #if TIMESTUFF()
01041     rc = ph_timedb_start(timedb,tags[3]);
01042     phPRINT_RC(rc,NULL,"ph_timedb_start");
01043 #endif
01044     rc = phautoblob_sort_blobs( this->m_data );
01045     phPRINT_RC(rc,NULL,"phautoblob_sort_blobs");
01046 #if TIMESTUFF()
01047     rc = ph_timedb_stop(timedb);
01048     phPRINT_RC(rc,NULL,"ph_timedb_stop");
01049 #endif
01050         
01051     /* -------------------------------------------------------------------- */
01052     /* 4.) Copy the data <strike>before performing any image altering</strike>*/
01053     /* -------------------------------------------------------------------- */
01054 #if TIMESTUFF()
01055     rc = ph_timedb_start(timedb,tags[4]);
01056     phPRINT_RC(rc,NULL,"ph_timedb_start");
01057 #endif
01058     rc = this->m_blobData.setData( this->m_data );
01059     phPRINT_RC(rc,NULL,"m_blobData.setData failed.");
01060 #if TIMESTUFF()
01061     rc = ph_timedb_stop(timedb);
01062     phPRINT_RC(rc,NULL,"ph_timedb_stop");
01063 #endif
01064         
01065     /* -------------------------------------------------------------------- */
01066     /* 5.) Put rectangles around all the blobs */
01067     /* -------------------------------------------------------------------- */
01068 #if TIMESTUFF()
01069     rc = ph_timedb_start(timedb,tags[6]);
01070     phPRINT_RC(rc,NULL,"ph_timedb_start");
01071 #endif
01072     if (this->m_draw_rects)
01073     {
01074         rc = 1;
01075         if (final_output_format != (uint32_t)phImageNOFORMAT)
01076         {
01077             rc = this->m_workspaceImage->convert(output_format);
01078             phPRINT_RC(rc,NULL,"Image->convert(outputFormat) failed.");
01079         }
01080         
01081         /* rc == 0 means conversion happened */
01082         /* rc == 1 means no conversion */
01083         if (rc == phSUCCESS)
01084         {
01085             rc = this->setFilterVars();
01086             phPRINT_RC(rc,NULL,"setFilterVars");
01087         }
01088             
01089         imgptr = (uint8_t *)Image;
01090         
01091         /* NULL arg == black */
01092         rc = phautoblob_draw_blob_rects(imgptr,width,height,format,
01093                                         this->m_outcolor,
01094                                         this->m_data,
01095                                         0,
01096                                         this->m_color_min_size,
01097                                         phBLOB_DRAW_ALL );
01098         phPRINT_RC(rc,NULL,"phautoblob_draw_blob_rects failed.");
01099     }
01100 #if TIMESTUFF()
01101     rc = ph_timedb_stop(timedb);
01102     phPRINT_RC(rc,NULL,"ph_timedb_stop");
01103 #endif
01104     
01105 #if TIMESTUFF() /* phTIME_REPORT_ALL & */
01106     rc = ph_timedb_report( timedb, phTIME_REPORT_SUM | phTIME_REPORT_ALL );
01107     phPRINT_RC(rc,NULL,"ph_timedb_report");
01108     
01109     if (timedb)
01110     {
01111         rc = ph_timedb_free(&timedb);
01112         phPRINT_RC(rc,NULL,"ph_timedb_free");
01113     }
01114 #endif
01115     
01116     return phSUCCESS; 
01117 error:
01118 #if TIMESTUFF() /* phTIME_REPORT_ALL & */
01119     if (timedb)
01120     {
01121         rc = ph_timedb_free(&timedb);
01122         phPRINT_RC(rc,NULL,"ph_timedb_free");
01123     }
01124 #endif
01125     return phFAIL;
01126 }  
01127 
01128 




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