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",0,0,gid,sid,EventBase::visRegionEGID,mysid), src(NULL), srcNumColors(0), srcColors(0), regions(NULL)
00012 {
00013 setNumImages(numLayers,numChannels);
00014 }
00015
00016 RegionGenerator::~RegionGenerator() {
00017 freeCaches();
00018 destruct();
00019 }
00020
00021 void
00022 RegionGenerator::freeCaches() {
00023 FilterBankGenerator::freeCaches();
00024 for(unsigned int l=0; l<numLayers; l++)
00025 for(unsigned int c=0; c<numChannels; c++) {
00026 delete [] regions[l][c];
00027 regions[l][c]=NULL;
00028 }
00029 }
00030
00031 void
00032 RegionGenerator::processEvent(const EventBase& event) {
00033 const FilterBankEvent& fbkevent=dynamic_cast<const FilterBankEvent& >(event);
00034 src=fbkevent.getSource();
00035 frameNumber=src->getFrameNumber();
00036 const RLEGenerator * rle=dynamic_cast<const RLEGenerator*>(src);
00037 if(NULL==rle) {
00038 serr->printf("RegionGenerator's event %s is not from RLEGenerator\n",event.getName().c_str());
00039 return;
00040 }
00041 const SegmentedColorFilterBankEvent * segev=dynamic_cast<const SegmentedColorFilterBankEvent*>(&event);
00042 if(NULL==segev) {
00043 serr->printf("RegionGenerator's event %s is not SegmentedColorFilterBankEvent\n",event.getName().c_str());
00044 return;
00045 }
00046 if(srcNumColors!=segev->getNumColors())
00047 freeCaches();
00048 srcNumColors=segev->getNumColors();
00049 srcColors=segev->getColors();
00050 if(src->getNumLayers()!=numLayers || src->getNumChannels()!=numChannels)
00051 setNumImages(src->getNumLayers(),src->getNumChannels());
00052 if(src->getWidth(numLayers-1)!=getWidth(numLayers-1))
00053 setDimensions();
00054
00055 invalidateCaches();
00056 framesProcessed++;
00057 erouter->postEvent(new SegmentedColorFilterBankEvent(this,getGeneratorID(),getSourceID(),*segev));
00058 }
00059
00060 unsigned int
00061 RegionGenerator::getBinSize() const {
00062 unsigned int used=FilterBankGenerator::getBinSize();
00063 used+=strlen("RegionImage")+LoadSave::stringpad;
00064 used+=sizeof(unsigned int);
00065 unsigned int xmit_bytes_per_run=5*sizeof(int)+2*sizeof(float)+2*sizeof(int);
00066 if(imageValids[selectedSaveLayer][selectedSaveChannel])
00067 used+=xmit_bytes_per_run;
00068 else
00069 used+=xmit_bytes_per_run*MAX_REGIONS;
00070 return used;
00071 }
00072
00073 unsigned int
00074 RegionGenerator::LoadBuffer(const char buf[], unsigned int len) {
00075 unsigned int origlen=len;
00076 unsigned int used;
00077 std::string tmp;
00078 if(0==(used=FilterBankGenerator::LoadBuffer(buf,len))) return 0;
00079 len-=used; buf+=used;
00080 if(0==(used=decode(tmp,buf,len))) return 0;
00081 len-=used; buf+=used;
00082 if(tmp!="RegionImage") {
00083 serr->printf("Unhandled image type for RegionGenerator: %s",tmp.c_str());
00084 return 0;
00085 } else {
00086 unsigned int tmpNumClr=0;
00087 if(0==(used=decode(tmpNumClr,buf,len))) return 0;
00088 len-=used; buf+=used;
00089 if(tmpNumClr!=srcNumColors)
00090 freeCaches();
00091 srcNumColors=tmpNumClr;
00092 if(images[selectedSaveLayer][selectedSaveChannel]==NULL)
00093 images[selectedSaveLayer][selectedSaveChannel]=createImageCache(selectedSaveLayer,selectedSaveChannel);
00094 region_stats * stats=reinterpret_cast<region_stats*>(images[selectedSaveLayer][selectedSaveChannel]);
00095 if(stats==NULL)
00096 return 0;
00097 for(unsigned int i=0; i<srcNumColors; i++) {
00098 unsigned int tmpNumReg=0;
00099 if(0==(used=decode(tmpNumReg,buf,len))) return 0;
00100 len-=used; buf+=used;
00101 if(MAX_REGIONS<=tmpNumReg)
00102 return 0;
00103 for(unsigned int j=0; j<tmpNumReg; j++) {
00104 region * curreg=®ions[selectedSaveLayer][selectedSaveChannel][j];
00105 if(0==(used=decode(curreg->color,buf,len))) return 0;
00106 len-=used; buf+=used;
00107 if(0==(used=decode(curreg->x1,buf,len))) return 0;
00108 len-=used; buf+=used;
00109 if(0==(used=decode(curreg->y1,buf,len))) return 0;
00110 len-=used; buf+=used;
00111 if(0==(used=decode(curreg->x2,buf,len))) return 0;
00112 len-=used; buf+=used;
00113 if(0==(used=decode(curreg->y2,buf,len))) return 0;
00114 len-=used; buf+=used;
00115 if(0==(used=decode(curreg->cen_x,buf,len))) return 0;
00116 len-=used; buf+=used;
00117 if(0==(used=decode(curreg->cen_y,buf,len))) return 0;
00118 len-=used; buf+=used;
00119 if(0==(used=decode(curreg->area,buf,len))) return 0;
00120 len-=used; buf+=used;
00121 if(0==(used=decode(curreg->run_start,buf,len))) return 0;
00122 len-=used; buf+=used;
00123 if(j==tmpNumReg-1)
00124 curreg->next=NULL;
00125 else
00126 curreg->next=®ions[selectedSaveLayer][selectedSaveChannel][j+1];
00127 }
00128
00129 if(0==(used=decode(stats[i].min_area,buf,len))) return 0;
00130 len-=used; buf+=used;
00131 if(0==(used=decode(stats[i].total_area,buf,len))) return 0;
00132 len-=used; buf+=used;
00133 if(0==(used=decode(stats[i].merge_threshold,buf,len))) return 0;
00134 len-=used; buf+=used;
00135 stats[i].list=regions[selectedSaveLayer][selectedSaveChannel];
00136 stats[i].num=tmpNumReg;
00137 }
00138 imageValids[selectedSaveLayer][selectedSaveChannel]=true;
00139 return origlen-len;
00140 }
00141 }
00142
00143 unsigned int
00144 RegionGenerator::SaveBuffer(char buf[], unsigned int len) const {
00145 unsigned int origlen=len;
00146 unsigned int used;
00147 if(0==(used=FilterBankGenerator::SaveBuffer(buf,len))) return 0;
00148 len-=used; buf+=used;
00149 if(0==(used=encode("RegionImage",buf,len))) return 0;
00150 len-=used; buf+=used;
00151
00152 region_stats * stats=reinterpret_cast<region_stats*>(getImage(selectedSaveLayer,selectedSaveChannel));
00153 if(stats==NULL)
00154 return 0;
00155 if(0==(used=encode(srcNumColors,buf,len))) return 0;
00156 len-=used; buf+=used;
00157 for(unsigned int i=0; i<srcNumColors; i++) {
00158 if(0==(used=encode(stats[i].num,buf,len))) return 0;
00159 len-=used; buf+=used;
00160 region * curreg=stats[i].list;
00161 for(int j=0; j<stats[i].num; j++) {
00162 if(0==(used=encode(curreg->color,buf,len))) return 0;
00163 len-=used; buf+=used;
00164 if(0==(used=encode(curreg->x1,buf,len))) return 0;
00165 len-=used; buf+=used;
00166 if(0==(used=encode(curreg->y1,buf,len))) return 0;
00167 len-=used; buf+=used;
00168 if(0==(used=encode(curreg->x2,buf,len))) return 0;
00169 len-=used; buf+=used;
00170 if(0==(used=encode(curreg->y2,buf,len))) return 0;
00171 len-=used; buf+=used;
00172 if(0==(used=encode(curreg->cen_x,buf,len))) return 0;
00173 len-=used; buf+=used;
00174 if(0==(used=encode(curreg->cen_y,buf,len))) return 0;
00175 len-=used; buf+=used;
00176 if(0==(used=encode(curreg->area,buf,len))) return 0;
00177 len-=used; buf+=used;
00178 if(0==(used=encode(curreg->run_start,buf,len))) return 0;
00179 len-=used; buf+=used;
00180 curreg=curreg->next;
00181 }
00182
00183 if(0==(used=encode(stats[i].min_area,buf,len))) return 0;
00184 len-=used; buf+=used;
00185 if(0==(used=encode(stats[i].total_area,buf,len))) return 0;
00186 len-=used; buf+=used;
00187 if(0==(used=encode(stats[i].merge_threshold,buf,len))) return 0;
00188 len-=used; buf+=used;
00189 }
00190 return origlen-len;
00191 }
00192
00193 void
00194 RegionGenerator::setNumImages(unsigned int nLayers, unsigned int nChannels) {
00195 FilterBankGenerator::setNumImages(nLayers,nChannels);
00196 regions = new region**[numLayers];
00197 for(unsigned int i=0; i<numLayers; i++) {
00198 regions[i] = new region*[numChannels];
00199 for(unsigned int j=0; j<numChannels; j++)
00200 regions[i][j]=NULL;
00201 }
00202 }
00203
00204
00205 void
00206 RegionGenerator::setDimensions() {
00207 for(unsigned int i=0; i<numLayers; i++) {
00208 widths[i]=src->getWidth(i);
00209 heights[i]=src->getHeight(i);
00210 }
00211 }
00212
00213 unsigned char *
00214 RegionGenerator::createImageCache(unsigned int layer, unsigned int chan) const {
00215 regions[layer][chan]=new region[MAX_REGIONS];
00216 region_stats * stats=new region_stats[srcNumColors];
00217
00218 memcpy(stats,srcColors,srcNumColors*sizeof(region_stats));
00219 return reinterpret_cast<unsigned char*>(stats);
00220 }
00221
00222 void
00223 RegionGenerator::calcImage(unsigned int layer, unsigned int chan) const {
00224 PROFSECTION("RegionGenerator::calcImage(...)",state->mainProfile);
00225 const RLEGenerator& srcRLE=dynamic_cast<const RLEGenerator&>(*src);
00226 RLEGenerator::run * rmap=reinterpret_cast<RLEGenerator::run*>(srcRLE.getImage(layer,chan));
00227 region_stats * stats=reinterpret_cast<region_stats*>(images[layer][chan]);
00228
00229 CMVision::ConnectComponents(rmap,srcRLE.getNumRuns(layer,chan));
00230 unsigned int numReg = CMVision::ExtractRegions(regions[layer][chan],MAX_REGIONS,rmap,srcRLE.getNumRuns(layer,chan));
00231 unsigned int maxArea = CMVision::SeparateRegions(stats,srcNumColors,regions[layer][chan],numReg);
00232 CMVision::SortRegions(stats,srcNumColors,maxArea);
00233 CMVision::MergeRegions(stats,(int)srcNumColors,rmap);
00234
00235 imageValids[layer][chan]=true;
00236 }
00237
00238 void
00239 RegionGenerator::destruct() {
00240 FilterBankGenerator::destruct();
00241 for(unsigned int i=0; i<numLayers; i++)
00242 delete [] regions[i];
00243 delete [] regions;
00244 regions=NULL;
00245 }
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258