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;
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=®ions[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=®ions[selectedSaveLayer][selectedSaveChannel][j+1];
00113 }
00114
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
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
00195 regions[layer][chan]=new region[MAX_REGIONS];
00196
00197
00198
00199 region_stats * stats=new region_stats[srcNumColors];
00200
00201
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
00212 const RLEGenerator& srcRLE=dynamic_cast<const RLEGenerator&>(*src);
00213 RLEGenerator::run * rmap=reinterpret_cast<RLEGenerator::run*>(srcRLE.getImage(layer,chan));
00214 region_stats * stats=reinterpret_cast<region_stats*>(images[layer][chan]);
00215
00216
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);
00222
00223
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
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247