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

Tekkotsu v2.2
Generated Tue Oct 19 14:19:15 2004 by Doxygen 1.3.9.1