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

Tekkotsu v2.2.1
Generated Tue Nov 23 16:36:39 2004 by Doxygen 1.3.9.1