00001 #include "RegionGenerator.h"
00002 #include "Events/EventRouter.h"
00003 #include "Wireless/Wireless.h"
00004 #include "Shared/Profiler.h"
00005 #include "SegmentedColorGenerator.h"
00006
00007 #include "Vision/RLEGenerator.h"
00008
00009 #include "Shared/debuget.h"
00010
00011 RegionGenerator::RegionGenerator(unsigned int mysid, RLEGenerator* rleg, EventBase::EventTypeID_t tid)
00012 : FilterBankGenerator("RegionGenerator","RegionGenerator",EventBase::visRegionEGID,mysid,rleg,tid), srcNumColors(0), srcColors(NULL), regions(NULL)
00013 {
00014 if(rleg!=NULL) {
00015 numLayers=numChannels=0;
00016 setNumImages(rleg->getNumLayers(),rleg->getNumChannels());
00017 if(const SegmentedColorGenerator* seg=dynamic_cast<const SegmentedColorGenerator*>(rleg->getSourceGenerator())) {
00018 srcNumColors=seg->getNumColors();
00019 srcColors=seg->getColors();
00020 } else {
00021 serr->printf("WARNING: Region generator expects it's source's source to be a SegmentedColorGenerator so that it can access color table information.\n");
00022 }
00023 }
00024 }
00025
00026 void
00027 RegionGenerator::freeCaches() {
00028 FilterBankGenerator::freeCaches();
00029 for(unsigned int l=0; l<numLayers; l++)
00030 for(unsigned int c=0; c<numChannels; c++) {
00031 delete [] regions[l][c];
00032 regions[l][c]=NULL;
00033 }
00034 }
00035
00036 void
00037 RegionGenerator::processEvent(const EventBase& event) {
00038 FilterBankGenerator::processEvent(event);
00039 if(event.getGeneratorID()==getListenGeneratorID() && event.getSourceID()==getListenSourceID()) {
00040 const RLEGenerator * rle=dynamic_cast<const RLEGenerator*>(src);
00041 if(NULL==rle) {
00042 serr->printf("RegionGenerator's event %s is not from RLEGenerator\n",event.getName().c_str());
00043 return;
00044 }
00045 const SegmentedColorFilterBankEvent * segev=dynamic_cast<const SegmentedColorFilterBankEvent*>(&event);
00046 if(NULL==segev) {
00047 serr->printf("RegionGenerator's event %s is not SegmentedColorFilterBankEvent\n",event.getName().c_str());
00048 return;
00049 }
00050 if(srcNumColors!=segev->getNumColors())
00051 freeCaches();
00052 srcNumColors=segev->getNumColors();
00053 srcColors=segev->getColors();
00054 SegmentedColorFilterBankEvent fbkev(this,getGeneratorID(),getSourceID(),EventBase::activateETID,*segev);
00055 erouter->postEvent(fbkev);
00056 fbkev.setTypeID(EventBase::statusETID);
00057 erouter->postEvent(fbkev);
00058 fbkev.setTypeID(EventBase::deactivateETID);
00059 erouter->postEvent(fbkev);
00060 }
00061 }
00062
00063 unsigned int
00064 RegionGenerator::getBinSize() const {
00065 unsigned int used=FilterBankGenerator::getBinSize();
00066 used+=strlen("RegionImage")+LoadSave::stringpad;
00067 used+=sizeof(unsigned int);
00068 used+=sizeof(unsigned int)*srcNumColors;
00069 unsigned int xmit_bytes_per_run=5*sizeof(int)+2*sizeof(float)+2*sizeof(int);
00070 if(imageValids[selectedSaveLayer][selectedSaveChannel]) {
00071 unsigned char* img=images[selectedSaveLayer][selectedSaveChannel];
00072 region_stats * stats=reinterpret_cast<region_stats*>(img);
00073 if(stats==NULL)
00074 return 0;
00075 for(unsigned int i=0; i<srcNumColors; i++)
00076 used+=xmit_bytes_per_run*stats[i].num;
00077 } else {
00078 used+=xmit_bytes_per_run*MAX_REGIONS;
00079 }
00080 used+=sizeof(unsigned int)*srcNumColors;
00081 used+=sizeof(unsigned int)*srcNumColors;
00082 used+=sizeof(float)*srcNumColors;
00083 return used;
00084 }
00085
00086 unsigned int
00087 RegionGenerator::loadBuffer(const char buf[], unsigned int len) {
00088 unsigned int origlen=len;
00089 if(!checkInc(FilterBankGenerator::loadBuffer(buf,len),buf,len)) return 0;
00090 std::string tmp;
00091 if(!decodeInc(tmp,buf,len)) return 0;
00092 if(tmp!="RegionImage") {
00093 serr->printf("Unhandled image type for RegionGenerator: %s",tmp.c_str());
00094 return 0;
00095 } else {
00096 unsigned int tmpNumClr=0;
00097 if(!decodeInc(tmpNumClr,buf,len)) return 0;
00098 if(tmpNumClr!=srcNumColors)
00099 freeCaches();
00100 srcNumColors=tmpNumClr;
00101 if(images[selectedSaveLayer][selectedSaveChannel]==NULL)
00102 images[selectedSaveLayer][selectedSaveChannel]=createImageCache(selectedSaveLayer,selectedSaveChannel);
00103 region_stats * stats=reinterpret_cast<region_stats*>(images[selectedSaveLayer][selectedSaveChannel]);
00104 if(stats==NULL)
00105 return 0;
00106 for(unsigned int i=0; i<srcNumColors; i++) {
00107 unsigned int tmpNumReg=0;
00108 if(!decodeInc(tmpNumReg,buf,len)) return 0;
00109 if(MAX_REGIONS<=tmpNumReg)
00110 return 0;
00111 for(unsigned int j=0; j<tmpNumReg; j++) {
00112 region * curreg=®ions[selectedSaveLayer][selectedSaveChannel][j];
00113 if(!decodeInc(curreg->color,buf,len)) return 0;
00114 if(!decodeInc(curreg->x1,buf,len)) return 0;
00115 if(!decodeInc(curreg->y1,buf,len)) return 0;
00116 if(!decodeInc(curreg->x2,buf,len)) return 0;
00117 if(!decodeInc(curreg->y2,buf,len)) return 0;
00118 if(!decodeInc(curreg->cen_x,buf,len)) return 0;
00119 if(!decodeInc(curreg->cen_y,buf,len)) return 0;
00120 if(!decodeInc(curreg->area,buf,len)) return 0;
00121 if(!decodeInc(curreg->run_start,buf,len)) return 0;
00122 if(j==tmpNumReg-1)
00123 curreg->next=NULL;
00124 else
00125 curreg->next=®ions[selectedSaveLayer][selectedSaveChannel][j+1];
00126 }
00127
00128 if(!decodeInc(stats[i].min_area,buf,len)) return 0;
00129 if(!decodeInc(stats[i].total_area,buf,len)) return 0;
00130 if(!decodeInc(stats[i].merge_threshold,buf,len)) return 0;
00131 stats[i].list=regions[selectedSaveLayer][selectedSaveChannel];
00132 stats[i].num=tmpNumReg;
00133 }
00134 imageValids[selectedSaveLayer][selectedSaveChannel]=true;
00135 return origlen-len;
00136 }
00137 }
00138
00139 unsigned int
00140 RegionGenerator::saveBuffer(char buf[], unsigned int len) const {
00141 unsigned int origlen=len;
00142 if(!checkInc(FilterBankGenerator::saveBuffer(buf,len),buf,len)) return 0;
00143 if(!encodeInc("RegionImage",buf,len)) return 0;
00144
00145 if(images[selectedSaveLayer][selectedSaveChannel]==NULL) {
00146 serr->printf("RegionGenerator::saveBuffer() failed because selected image is NULL -- call selectSaveImage first to make sure it's up to date\n");
00147 return 0;
00148 }
00149 if(!imageValids[selectedSaveLayer][selectedSaveChannel]) {
00150 serr->printf("RegionGenerator::saveBuffer() failed because selected image is invalid -- call selectSaveImage first to make sure it's up to date\n");
00151 return 0;
00152 }
00153 unsigned char* img=images[selectedSaveLayer][selectedSaveChannel];
00154 region_stats * stats=reinterpret_cast<region_stats*>(img);
00155 if(stats==NULL)
00156 return 0;
00157 if(!encodeInc(srcNumColors,buf,len)) return 0;
00158 for(unsigned int i=0; i<srcNumColors; i++) {
00159 if(!encodeInc(stats[i].num,buf,len)) return 0;
00160 region * curreg=stats[i].list;
00161 for(int j=0; j<stats[i].num; j++) {
00162 if(!encodeInc(curreg->color,buf,len)) return 0;
00163 if(!encodeInc(curreg->x1,buf,len)) return 0;
00164 if(!encodeInc(curreg->y1,buf,len)) return 0;
00165 if(!encodeInc(curreg->x2,buf,len)) return 0;
00166 if(!encodeInc(curreg->y2,buf,len)) return 0;
00167 if(!encodeInc(curreg->cen_x,buf,len)) return 0;
00168 if(!encodeInc(curreg->cen_y,buf,len)) return 0;
00169 if(!encodeInc(curreg->area,buf,len)) return 0;
00170 if(!encodeInc(curreg->run_start,buf,len)) return 0;
00171 curreg=curreg->next;
00172 }
00173
00174 if(!encodeInc(stats[i].min_area,buf,len)) return 0;
00175 if(!encodeInc(stats[i].total_area,buf,len)) return 0;
00176 if(!encodeInc(stats[i].merge_threshold,buf,len)) return 0;
00177 }
00178 return origlen-len;
00179 }
00180
00181 void
00182 RegionGenerator::setNumImages(unsigned int nLayers, unsigned int nChannels) {
00183 if(nLayers==numLayers && nChannels==numChannels)
00184 return;
00185 FilterBankGenerator::setNumImages(nLayers,nChannels);
00186 regions = new region**[numLayers];
00187 for(unsigned int i=0; i<numLayers; i++) {
00188 regions[i] = new region*[numChannels];
00189 for(unsigned int j=0; j<numChannels; j++)
00190 regions[i][j]=NULL;
00191 }
00192 }
00193
00194 unsigned char *
00195 RegionGenerator::createImageCache(unsigned int layer, unsigned int chan) const {
00196
00197 regions[layer][chan]=new region[MAX_REGIONS];
00198
00199
00200
00201 region_stats * stats=new region_stats[srcNumColors];
00202
00203
00204 memcpy(stats,srcColors,srcNumColors*sizeof(region_stats));
00205
00206 return reinterpret_cast<unsigned char*>(stats);
00207 }
00208
00209 void
00210 RegionGenerator::calcImage(unsigned int layer, unsigned int chan) {
00211 PROFSECTION("RegionGenerator::calcImage(...)",*mainProfiler);
00212
00213
00214 RLEGenerator& srcRLE=dynamic_cast<RLEGenerator&>(*src);
00215 RLEGenerator::run * rmap=reinterpret_cast<RLEGenerator::run*>(srcRLE.getImage(layer,chan));
00216 region_stats * stats=reinterpret_cast<region_stats*>(images[layer][chan]);
00217
00218
00219 CMVision::ConnectComponents(rmap,srcRLE.getNumRuns(layer,chan));
00220 unsigned int numReg = CMVision::ExtractRegions(regions[layer][chan],MAX_REGIONS,rmap,srcRLE.getNumRuns(layer,chan));
00221 unsigned int maxArea = CMVision::SeparateRegions(stats,srcNumColors,regions[layer][chan],numReg);
00222 CMVision::SortRegions(stats,srcNumColors,maxArea);
00223 CMVision::MergeRegions(stats,(int)srcNumColors,rmap);
00224 CMVision::CalcTotalArea(stats,srcNumColors);
00225
00226
00227 imageValids[layer][chan]=true;
00228 }
00229
00230 void
00231 RegionGenerator::destruct() {
00232 FilterBankGenerator::destruct();
00233 for(unsigned int i=0; i<numLayers; i++)
00234 delete [] regions[i];
00235 delete [] regions;
00236 regions=NULL;
00237 }
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250