Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

RegionGenerator.cc

Go to the documentation of this file.
00001 #include "RegionGenerator.h"
00002 #include "Events/EventRouter.h"
00003 #include "Wireless/Wireless.h"
00004 #include "Shared/WorldState.h"
00005 
00006 #include "Vision/RLEGenerator.h"
00007 
00008 #include "Shared/debuget.h"
00009 
00010 RegionGenerator::RegionGenerator(unsigned int mysid, RLEGenerator* rleg, EventBase::EventTypeID_t tid)
00011   : FilterBankGenerator("RegionGenerator","RegionGenerator",EventBase::visRegionEGID,mysid,rleg,tid), srcNumColors(0), srcColors(0), regions(NULL)
00012 {
00013   //this part is only necessary if you override setNumImages yourself
00014   if(rleg!=NULL) {
00015     numLayers=numChannels=0; //this is to force setNumImages to override settings provided by FilterBankGenerator
00016     setNumImages(rleg->getNumLayers(),rleg->getNumChannels());
00017   }
00018 }
00019 
00020 void
00021 RegionGenerator::freeCaches() {
00022   FilterBankGenerator::freeCaches();
00023   for(unsigned int l=0; l<numLayers; l++)
00024     for(unsigned int c=0; c<numChannels; c++) {
00025       delete [] regions[l][c];
00026       regions[l][c]=NULL;
00027     }
00028 }
00029 
00030 void
00031 RegionGenerator::processEvent(const EventBase& event) {
00032   FilterBankGenerator::processEvent(event);
00033   if(event.getGeneratorID()==getListenGeneratorID() && event.getSourceID()==getListenSourceID()) {
00034     const RLEGenerator * rle=dynamic_cast<const RLEGenerator*>(src);
00035     if(NULL==rle) {
00036       serr->printf("RegionGenerator's event %s is not from RLEGenerator\n",event.getName().c_str());
00037       return;
00038     }
00039     const SegmentedColorFilterBankEvent * segev=dynamic_cast<const SegmentedColorFilterBankEvent*>(&event);
00040     if(NULL==segev) {
00041       serr->printf("RegionGenerator's event %s is not SegmentedColorFilterBankEvent\n",event.getName().c_str());
00042       return;
00043     }
00044     if(srcNumColors!=segev->getNumColors())
00045       freeCaches();
00046     srcNumColors=segev->getNumColors();
00047     srcColors=segev->getColors();
00048     erouter->postEvent(new SegmentedColorFilterBankEvent(this,getGeneratorID(),getSourceID(),EventBase::activateETID,*segev));
00049     erouter->postEvent(new SegmentedColorFilterBankEvent(this,getGeneratorID(),getSourceID(),EventBase::statusETID,*segev));
00050     erouter->postEvent(new SegmentedColorFilterBankEvent(this,getGeneratorID(),getSourceID(),EventBase::deactivateETID,*segev));
00051   }
00052 }
00053 
00054 unsigned int
00055 RegionGenerator::getBinSize() const {
00056   unsigned int used=FilterBankGenerator::getBinSize();
00057   used+=strlen("RegionImage")+LoadSave::stringpad;
00058   used+=sizeof(unsigned int); //srcNumColors
00059   used+=sizeof(unsigned int)*srcNumColors; //stats[i].num (for each color i)
00060   unsigned int xmit_bytes_per_run=5*sizeof(int)+2*sizeof(float)+2*sizeof(int);
00061   if(imageValids[selectedSaveLayer][selectedSaveChannel]) {
00062     unsigned char* img=images[selectedSaveLayer][selectedSaveChannel];
00063     region_stats * stats=reinterpret_cast<region_stats*>(img);
00064     if(stats==NULL)
00065       return 0;
00066     for(unsigned int i=0; i<srcNumColors; i++)
00067       used+=xmit_bytes_per_run*stats[i].num;
00068   } else {
00069     used+=xmit_bytes_per_run*MAX_REGIONS;
00070   }
00071   used+=sizeof(unsigned int)*srcNumColors; //stats[i].min_area (for each color i)
00072   used+=sizeof(unsigned int)*srcNumColors; //stats[i].total_area (for each color i)
00073   used+=sizeof(float)*srcNumColors; //stats[i].merge_threshold (for each color i)
00074   return used;
00075 }
00076 
00077 unsigned int
00078 RegionGenerator::LoadBuffer(const char buf[], unsigned int len) {
00079   unsigned int origlen=len;
00080   unsigned int used;
00081   std::string tmp;
00082   if(0==(used=FilterBankGenerator::LoadBuffer(buf,len))) return 0;
00083   len-=used; buf+=used;
00084   if(0==(used=decode(tmp,buf,len))) return 0;
00085   len-=used; buf+=used;
00086   if(tmp!="RegionImage") {
00087     serr->printf("Unhandled image type for RegionGenerator: %s",tmp.c_str());
00088     return 0;
00089   } else {
00090     unsigned int tmpNumClr=0;
00091     if(0==(used=decode(tmpNumClr,buf,len))) return 0;
00092     len-=used; buf+=used;
00093     if(tmpNumClr!=srcNumColors)
00094       freeCaches();
00095     srcNumColors=tmpNumClr;
00096     if(images[selectedSaveLayer][selectedSaveChannel]==NULL)
00097       images[selectedSaveLayer][selectedSaveChannel]=createImageCache(selectedSaveLayer,selectedSaveChannel);
00098     region_stats * stats=reinterpret_cast<region_stats*>(images[selectedSaveLayer][selectedSaveChannel]);
00099     if(stats==NULL)
00100       return 0;
00101     for(unsigned int i=0; i<srcNumColors; i++) {
00102       unsigned int tmpNumReg=0;
00103       if(0==(used=decode(tmpNumReg,buf,len))) return 0;
00104       len-=used; buf+=used;
00105       if(MAX_REGIONS<=tmpNumReg)
00106         return 0;
00107       for(unsigned int j=0; j<tmpNumReg; j++) {
00108         region * curreg=&regions[selectedSaveLayer][selectedSaveChannel][j];
00109         if(0==(used=decode(curreg->color,buf,len))) return 0;
00110         len-=used; buf+=used;
00111         if(0==(used=decode(curreg->x1,buf,len))) return 0;
00112         len-=used; buf+=used;
00113         if(0==(used=decode(curreg->y1,buf,len))) return 0;
00114         len-=used; buf+=used;
00115         if(0==(used=decode(curreg->x2,buf,len))) return 0;
00116         len-=used; buf+=used;
00117         if(0==(used=decode(curreg->y2,buf,len))) return 0;
00118         len-=used; buf+=used;
00119         if(0==(used=decode(curreg->cen_x,buf,len))) return 0;
00120         len-=used; buf+=used;
00121         if(0==(used=decode(curreg->cen_y,buf,len))) return 0;
00122         len-=used; buf+=used;
00123         if(0==(used=decode(curreg->area,buf,len))) return 0;
00124         len-=used; buf+=used;
00125         if(0==(used=decode(curreg->run_start,buf,len))) return 0;
00126         len-=used; buf+=used;
00127         if(j==tmpNumReg-1)
00128           curreg->next=NULL;
00129         else
00130           curreg->next=&regions[selectedSaveLayer][selectedSaveChannel][j+1];
00131       }
00132       //we're only going to save the region part (not the color info)
00133       if(0==(used=decode(stats[i].min_area,buf,len))) return 0;
00134       len-=used; buf+=used;
00135       if(0==(used=decode(stats[i].total_area,buf,len))) return 0;
00136       len-=used; buf+=used;
00137       if(0==(used=decode(stats[i].merge_threshold,buf,len))) return 0;
00138       len-=used; buf+=used;
00139       stats[i].list=regions[selectedSaveLayer][selectedSaveChannel];
00140       stats[i].num=tmpNumReg;
00141     }
00142     imageValids[selectedSaveLayer][selectedSaveChannel]=true;
00143     return origlen-len; 
00144   }
00145 }
00146 
00147 unsigned int
00148 RegionGenerator::SaveBuffer(char buf[], unsigned int len) const {
00149   unsigned int origlen=len;
00150   unsigned int used;
00151   if(0==(used=FilterBankGenerator::SaveBuffer(buf,len))) return 0;
00152   len-=used; buf+=used;
00153   if(0==(used=encode("RegionImage",buf,len))) return 0;
00154   len-=used; buf+=used;
00155   
00156   if(images[selectedSaveLayer][selectedSaveChannel]==NULL) {
00157     serr->printf("RegionGenerator::SaveBuffer() failed because selected image is NULL -- call selectSaveImage first to make sure it's up to date\n");
00158     return 0;
00159   }
00160   if(!imageValids[selectedSaveLayer][selectedSaveChannel]) {
00161     serr->printf("RegionGenerator::SaveBuffer() failed because selected image is invalid -- call selectSaveImage first to make sure it's up to date\n");
00162     return 0;
00163   }
00164   unsigned char* img=images[selectedSaveLayer][selectedSaveChannel];
00165   region_stats * stats=reinterpret_cast<region_stats*>(img);
00166   if(stats==NULL)
00167     return 0;
00168   if(0==(used=encode(srcNumColors,buf,len))) return 0;
00169   len-=used; buf+=used;
00170   for(unsigned int i=0; i<srcNumColors; i++) {
00171     if(0==(used=encode(stats[i].num,buf,len))) return 0;
00172     len-=used; buf+=used;
00173     region * curreg=stats[i].list;
00174     for(int j=0; j<stats[i].num; j++) {
00175       if(0==(used=encode(curreg->color,buf,len))) return 0;
00176       len-=used; buf+=used;
00177       if(0==(used=encode(curreg->x1,buf,len))) return 0;
00178       len-=used; buf+=used;
00179       if(0==(used=encode(curreg->y1,buf,len))) return 0;
00180       len-=used; buf+=used;
00181       if(0==(used=encode(curreg->x2,buf,len))) return 0;
00182       len-=used; buf+=used;
00183       if(0==(used=encode(curreg->y2,buf,len))) return 0;
00184       len-=used; buf+=used;
00185       if(0==(used=encode(curreg->cen_x,buf,len))) return 0;
00186       len-=used; buf+=used;
00187       if(0==(used=encode(curreg->cen_y,buf,len))) return 0;
00188       len-=used; buf+=used;
00189       if(0==(used=encode(curreg->area,buf,len))) return 0;
00190       len-=used; buf+=used;
00191       if(0==(used=encode(curreg->run_start,buf,len))) return 0;
00192       len-=used; buf+=used;
00193       curreg=curreg->next;
00194     }
00195     //we're only going to save the region part (not the color info)
00196     if(0==(used=encode(stats[i].min_area,buf,len))) return 0;
00197     len-=used; buf+=used;
00198     if(0==(used=encode(stats[i].total_area,buf,len))) return 0;
00199     len-=used; buf+=used;
00200     if(0==(used=encode(stats[i].merge_threshold,buf,len))) return 0;
00201     len-=used; buf+=used;
00202   }
00203   return origlen-len;
00204 }
00205 
00206 void
00207 RegionGenerator::setNumImages(unsigned int nLayers, unsigned int nChannels) {
00208   if(nLayers==numLayers && nChannels==numChannels)
00209     return;
00210   FilterBankGenerator::setNumImages(nLayers,nChannels);
00211   regions = new region**[numLayers];
00212   for(unsigned int i=0; i<numLayers; i++) {
00213     regions[i] = new region*[numChannels];
00214     for(unsigned int j=0; j<numChannels; j++)
00215       regions[i][j]=NULL;
00216   }
00217 }
00218 
00219 unsigned char *
00220 RegionGenerator::createImageCache(unsigned int layer, unsigned int chan) const {
00221   //this is where we'll store the linked list of regions for this image
00222   regions[layer][chan]=new region[MAX_REGIONS];
00223 
00224   //this is where we store the head of each list as well as some general stats of each image
00225   //this is what will be returned as getImage()
00226   region_stats * stats=new region_stats[srcNumColors];
00227   
00228   //initialize the region parameters (held in color definition...)
00229   memcpy(stats,srcColors,srcNumColors*sizeof(region_stats));
00230   
00231   return reinterpret_cast<unsigned char*>(stats);
00232 }
00233 
00234 void
00235 RegionGenerator::calcImage(unsigned int layer, unsigned int chan) {
00236   PROFSECTION("RegionGenerator::calcImage(...)",state->mainProfile);
00237   
00238   //some shorthand to make the rest of the code more readable
00239   RLEGenerator& srcRLE=dynamic_cast<RLEGenerator&>(*src); //source generator
00240   RLEGenerator::run * rmap=reinterpret_cast<RLEGenerator::run*>(srcRLE.getImage(layer,chan)); //the RLE encoded image from source
00241   region_stats * stats=reinterpret_cast<region_stats*>(images[layer][chan]); //our top level region stats array (which is what users get from getImage())
00242 
00243   //do the actual calculations
00244   CMVision::ConnectComponents(rmap,srcRLE.getNumRuns(layer,chan));
00245   unsigned int numReg = CMVision::ExtractRegions(regions[layer][chan],MAX_REGIONS,rmap,srcRLE.getNumRuns(layer,chan));
00246   unsigned int maxArea = CMVision::SeparateRegions(stats,srcNumColors,regions[layer][chan],numReg);
00247   CMVision::SortRegions(stats,srcNumColors,maxArea);
00248   CMVision::MergeRegions(stats,(int)srcNumColors,rmap); //yes that (int) is necessary or compiler complains of ambiguous function call
00249 
00250   //and set the flag so we don't recompute if getImage() is called again before the next frame
00251   imageValids[layer][chan]=true;
00252 }
00253 
00254 void
00255 RegionGenerator::destruct() {
00256   FilterBankGenerator::destruct();
00257   for(unsigned int i=0; i<numLayers; i++)
00258     delete [] regions[i];
00259   delete [] regions;
00260   regions=NULL;
00261 }
00262 
00263 /*! @file
00264  * @brief Implements RegionGenerator, which connects regions of CMVision format runs in RLEGenerator
00265  * @author alokl (Creator)
00266  * @author ejt (reorganized)
00267  *
00268  * $Author: ejt $
00269  * $Name: tekkotsu-2_4_1 $
00270  * $Revision: 1.11 $
00271  * $State: Exp $
00272  * $Date: 2005/06/06 20:23:15 $
00273  */
00274 

Tekkotsu v2.4.1
Generated Tue Aug 16 16:32:48 2005 by Doxygen 1.4.4