Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

SegmentedColorGenerator.cc

Go to the documentation of this file.
00001 #include "SegmentedColorGenerator.h"
00002 #include "Events/EventRouter.h"
00003 #include "Events/SegmentedColorFilterBankEvent.h"
00004 #include "Wireless/Wireless.h"
00005 #include "Shared/Profiler.h"
00006 #include "Shared/Config.h"
00007 
00008 #include "Shared/debuget.h"
00009 
00010 SegmentedColorGenerator::SegmentedColorGenerator(unsigned int mysid, FilterBankGenerator* fbg, EventBase::EventTypeID_t tid)
00011   : FilterBankGenerator("SegmentedColorGenerator",EventBase::visSegmentEGID,mysid,fbg,tid), srcYChan(0), srcUChan(1), srcVChan(2), tmaps(), tmapNames(), numColors(0), colorNames()
00012 {
00013   //this part is only necessary if you override setNumImages yourself
00014   if(fbg!=NULL) {
00015     numLayers=numChannels=0; //this is to force setNumImages to override settings provided by FilterBankGenerator
00016     setNumImages(fbg->getNumLayers(),fbg->getNumChannels());
00017   }
00018 }
00019 
00020 SegmentedColorGenerator::SegmentedColorGenerator(unsigned int mysid, FilterBankGenerator* fbg, EventBase::EventTypeID_t tid, unsigned int syc, unsigned int suc, unsigned int svc)
00021   : FilterBankGenerator("SegmentedColorGenerator",EventBase::visSegmentEGID,mysid,fbg,tid), srcYChan(syc), srcUChan(suc), srcVChan(svc), tmaps(), tmapNames(), numColors(0), colorNames()
00022 {
00023   if(fbg!=NULL) {
00024     numLayers=numChannels=0; //this is to force setNumImages to override settings provided by FilterBankGenerator
00025     setNumImages(fbg->getNumLayers(),fbg->getNumChannels());
00026   }
00027 }
00028 
00029 SegmentedColorGenerator::~SegmentedColorGenerator() {
00030   freeCaches();
00031   destruct();
00032   for(unsigned int i=0; i<tmaps.size(); i++)
00033     delete [] tmaps[i];
00034 
00035   //hashmap::iterator it=colorNames.begin(); //not the way i'd like to iterate, but there seems to be a bug in the current hashmap implementation we're using...
00036   //for(unsigned int i=0; i<colorNames.size(); it++,i++)
00037   //free(const_cast<char*>(it->first));
00038   //colorNames.clear();
00039 
00040   colorNames.clear(); //we're leaking the memory of the names themselves...
00041 }
00042 
00043 void
00044 SegmentedColorGenerator::doEvent() {
00045   if(event->getGeneratorID()==getListenGeneratorID() && event->getSourceID()==getListenSourceID()) {
00046     SegmentedColorFilterBankEvent segev(this,getGeneratorID(),getSourceID(),EventBase::activateETID,this,getNumColors(),getColors(),&colorNames);
00047     erouter->postEvent(segev);
00048     segev.setTypeID(EventBase::statusETID);
00049     erouter->postEvent(segev);
00050     segev.setTypeID(EventBase::deactivateETID);
00051     erouter->postEvent(segev);
00052   }
00053 }
00054 
00055 unsigned int
00056 SegmentedColorGenerator::loadThresholdMap(const std::string& tm_file) {
00057   const unsigned int size = 1 << (BITS_Y + BITS_U + BITS_V);
00058   cmap_t * tmap = new cmap_t[size];
00059   if(!CMVision::LoadThresholdFile(tmap,NUM_Y,NUM_U,NUM_V,config->portPath(tm_file).c_str())) {
00060     serr->printf("  ERROR: Could not load threshold file '%s'.\n",tm_file.c_str());
00061     delete [] tmap;
00062     return -1U;
00063   }
00064   if(numColors!=0) {
00065     //we've already loaded color info, check against that for invalid indexes
00066     int remapped=CMVision::CheckTMapColors(tmap,NUM_Y,NUM_U,NUM_V,numColors,0);
00067     if(remapped>0)
00068       serr->printf("remapped %d colors in threshold file '%s'\n",remapped, tm_file.c_str());
00069   }
00070 
00071   tmapNames.push_back(tm_file);
00072   tmaps.push_back(tmap);
00073   setNumImages(numLayers,tmaps.size());
00074   return tmaps.size()-1;
00075 }
00076 
00077 bool
00078 SegmentedColorGenerator::loadColorInfo(const std::string& col_file) {
00079   //hashmap::iterator it=colorNames.begin(); //not the way i'd like to iterate, but there seems to be a bug in the current hashmap implementation we're using...
00080   //for(unsigned int i=0; i<colorNames.size(); it++,i++)
00081   //free(const_cast<char*>(it->first));
00082   //colorNames.clear();
00083 
00084   colorNames.clear(); //we're leaking the memory of the names themselves...
00085 
00086   numColors=CMVision::LoadColorInformation(colors,MAX_COLORS,config->portPath(col_file).c_str(),colorNames);
00087   if(numColors <= 0){
00088     serr->printf("  ERROR: Could not load colors file:%s\n", col_file.c_str());
00089     return false;
00090   }
00091 
00092   //we'd better check the already loaded thresholds (if any) for out of bound indexes
00093   for(unsigned int i=0; i<tmaps.size(); i++) {
00094     int remapped=CMVision::CheckTMapColors(tmaps[i],NUM_Y,NUM_U,NUM_V,numColors,0);
00095     if(remapped>0)
00096       serr->printf("remapped %d colors in threshold file '%s'\n",remapped, tmapNames[i].c_str());
00097   }
00098   return true;
00099 }
00100 
00101 
00102 unsigned int
00103 SegmentedColorGenerator::getBinSize() const {
00104   unsigned int used=FilterBankGenerator::getBinSize();
00105   used+=creatorSize("SegColorImage");
00106   used+=widths[selectedSaveLayer]*heights[selectedSaveLayer];
00107   return used;
00108 }
00109 
00110 unsigned int
00111 SegmentedColorGenerator::loadBuffer(const char buf[], unsigned int len, const char* filename) {
00112   unsigned int origlen=len;
00113   if(!checkInc(FilterBankGenerator::loadBuffer(buf,len,filename),buf,len)) return 0;
00114   if(!checkCreatorInc("SegColorImage",buf,len)) {
00115     serr->printf("Unhandled image type for SegmentedColorGenerator: %s",buf+getSerializedSize<unsigned int>());
00116     return 0;
00117   } else {
00118     // actual image
00119     unsigned int used=widths[selectedSaveLayer]*heights[selectedSaveLayer];
00120     if(used>len)
00121       return 0;
00122     if(images[selectedSaveLayer][selectedSaveChannel]==NULL)
00123       images[selectedSaveLayer][selectedSaveChannel]=createImageCache(selectedSaveLayer,selectedSaveChannel);
00124     unsigned char* img=images[selectedSaveLayer][selectedSaveChannel];
00125     if(img==NULL)
00126       return 0;
00127     memcpy(img,buf,used);
00128     len-=used; buf+=used;
00129 
00130     // color table
00131     if(!decodeColorsInc(buf,len)) return 0;
00132     
00133     imageValids[selectedSaveLayer][selectedSaveChannel]=true;
00134     return origlen-len; 
00135   }
00136 }
00137 
00138 unsigned int
00139 SegmentedColorGenerator::saveBuffer(char buf[], unsigned int len) const {
00140   unsigned int origlen=len;
00141   if(!checkInc(FilterBankGenerator::saveBuffer(buf,len),buf,len)) return 0;
00142   if(!saveCreatorInc("SegColorImage",buf,len)) return 0;
00143   
00144   // actual image
00145   unsigned int used=widths[selectedSaveLayer]*heights[selectedSaveLayer];
00146   if(used>len)
00147     return 0;
00148   if(images[selectedSaveLayer][selectedSaveChannel]==NULL) {
00149     serr->printf("SegmentedColorGenerator::saveBuffer() failed because selected image is NULL -- call selectSaveImage first to make sure it's up to date\n");
00150     return 0;
00151   }
00152   if(!imageValids[selectedSaveLayer][selectedSaveChannel]) {
00153     serr->printf("SegmentedColorGenerator::saveBuffer() failed because selected image is invalid -- call selectSaveImage first to make sure it's up to date\n");
00154     return 0;
00155   }
00156   unsigned char* img=images[selectedSaveLayer][selectedSaveChannel];
00157   if(img==NULL)
00158     return 0;
00159   memcpy(buf,img,used);
00160   len-=used; buf+=used;
00161 
00162   // color table
00163   if(!encodeColorsInc(buf,len)) return 0;
00164   
00165   return origlen-len;
00166 }
00167 
00168 bool
00169 SegmentedColorGenerator::encodeColorsInc(char*& buf, unsigned int& len) const {
00170   if(!encodeInc(numColors,buf,len)) return false;
00171   for(unsigned int i=0; i<numColors; i++) {
00172     if(!encodeInc(colors[i].color.red,buf,len)) return false;
00173     if(!encodeInc(colors[i].color.green,buf,len)) return false;
00174     if(!encodeInc(colors[i].color.blue,buf,len)) return false;
00175   }
00176   return true;
00177 }
00178 
00179 bool
00180 SegmentedColorGenerator::decodeColorsInc(const char*& buf, unsigned int& len) {
00181   if(!decodeInc(numColors,buf,len)) return false;
00182   for(unsigned int i=0; i<numColors; i++) {
00183     if(!decodeInc(colors[i].color.red,buf,len)) return false;
00184     if(!decodeInc(colors[i].color.green,buf,len)) return false;
00185     if(!decodeInc(colors[i].color.blue,buf,len)) return false;
00186   }
00187   return true;
00188 }
00189 
00190 void
00191 SegmentedColorGenerator::setDimensions() {
00192   FilterBankGenerator::setDimensions();
00193   for(unsigned int i=0; i<numLayers; i++)
00194     strides[i]=widths[i];
00195 }
00196 
00197 void
00198 SegmentedColorGenerator::setNumImages(unsigned int nLayers, unsigned int /*nChannels*/) {
00199   FilterBankGenerator::setNumImages(nLayers,tmaps.size());
00200 }
00201 
00202 unsigned char *
00203 SegmentedColorGenerator::createImageCache(unsigned int layer, unsigned int /*chan*/) const {
00204   // notice the +1 !!!
00205   // this is because CMVision is a little naughty and writes an unused, terminator flag at the one-past-end of each row
00206   // if we didn't add one, this last byte would be beyond the end of the array
00207   return new unsigned char[widths[layer]*heights[layer]+1];
00208 }
00209 
00210 void
00211 SegmentedColorGenerator::calcImage(unsigned int layer, unsigned int chan) {
00212   if(tmaps.size()==0)
00213     throw NoThresholdException();
00214   PROFSECTION("SegmentedColorGenerator::calcImage(...)",*mainProfiler);
00215   CMVision::image_yuv<const cmap_t> img;
00216   img.buf_y=src->getImage(layer,srcYChan);
00217   img.buf_u=src->getImage(layer,srcUChan);
00218   img.buf_v=src->getImage(layer,srcVChan);
00219   img.width=getWidth(layer);
00220   img.height=getHeight(layer);
00221   img.row_stride=src->getStride(layer);
00222   img.col_stride=src->getIncrement(layer);
00223 
00224   CMVision::ThresholdImageYUVPlanar<cmap_t,CMVision::image_yuv<const cmap_t>,const cmap_t,BITS_Y,BITS_U,BITS_V>(images[layer][chan],img,tmaps[chan]);
00225   imageValids[layer][chan]=true;
00226 }
00227 
00228 /*! @file
00229  * @brief Implements SegmentedColorGenerator, which generates FilterBankEvents indexed color images based on a color threshold file
00230  * @author alokl (Creator)
00231  * @author ejt (reorganized)
00232  */
00233 

Tekkotsu v5.1CVS
Generated Mon May 9 04:58:50 2016 by Doxygen 1.6.3