Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

SegmentedColorGenerator.h

Go to the documentation of this file.
00001 //-*-c++-*-
00002 #ifndef INCLUDED_SegmentedColorGenerator_h_
00003 #define INCLUDED_SegmentedColorGenerator_h_
00004 
00005 #include "Vision/FilterBankGenerator.h"
00006 #include "Vision/cmvision.h"
00007 #include "Vision/colors.h"
00008 #include <ext/hash_map>
00009 #include <vector>
00010 
00011 //! Generates FilterBankEvents indexed color images based on a color threshold file
00012 /*! Pretty simple idea - use a big mapping of YUV values to lookup
00013  *  index values.
00014  *
00015  *  Threshold files are 16x64x64 = 64KB.  So each Y component is
00016  *  discretized into 16 levels, U and V into 64 each.  Then the
00017  *  appropriate element of the 3D matrix is looked up, which holds the
00018  *  desired index for that color.  The threshold files are generated
00019  *  offline. See http://www.tekkotsu.org/CameraSetup.html
00020  *
00021  *  The color information is shared for all threshold files in this
00022  *  object.
00023  *
00024  *  The row skip is always 0, and the row stride is always width.
00025  *  But it would be better to use the proper accessor functions to be
00026  *  more general.
00027  *
00028  *  Should receive FilterBankEvents from any standard format
00029  *  FilterBankGenerator (like RawCameraGenerator) <em>However</em>,
00030  *  images that use an increment!=1 will break.
00031  *
00032  *  The events which are produced are SegmentedColorFilterBankEvents,
00033  *  which will allow you to reference the color information later on.
00034  *  Keep in mind that the region and area statistic fields are not
00035  *  filled out at this stage... the RegionGenerator will complete the
00036  *  processing if you want that info as well.
00037  *
00038  *  Uses the CMVision library for main processing
00039  *
00040  *  The format used for serialization is: (code is in saveBuffer())
00041  *  - <@c FilterBankGenerator: superclass header> <i>(First saves the superclass's info)</i>
00042  *  - <@c string: "SegColorImage"> <i>(remember a 'string' is len+str+0; so this is the literal "\015\0\0\0SegColorImage\0"; also remember "\015" is octal for 13)</i>
00043  *  - <<tt>char[</tt>width<tt>*</tt>height<tt>]</tt>: image data> <i>(one byte per sample)</i>
00044  *  - <@c unsigned @c int: num_cols> <i>(number of different colors available)</i>
00045  *  - for each of num_col:
00046  *    - <@c char: red> <i>red color to use for display of this index</i>
00047  *    - <@c char: green> <i>green color to use for display of this index</i>
00048  *    - <@c char: blue> <i>blue color to use for display of this index</i>
00049  *
00050  *  For more information on serialization, see FilterBankGenerator
00051  *
00052  */
00053 class SegmentedColorGenerator : public FilterBankGenerator {
00054 public:
00055   typedef CMVision::uchar cmap_t; //!< type to use for color indexes
00056   typedef CMVision::color_class_state color_class_state; //!< use CMVision's color structure
00057   typedef __gnu_cxx::hash_map<const char*, unsigned int, __gnu_cxx::hash<const char*>, hashcmp_eqstr> hashmap; //!< a shorthand for the hash structure that CMVision expects for the color lookups
00058 
00059   //! constructor
00060   SegmentedColorGenerator(unsigned int mysid, FilterBankGenerator* fbg, EventBase::EventTypeID_t tid);
00061   //! constructor, you can pass which channels to use as Y, U, & V channels
00062   SegmentedColorGenerator(unsigned int mysid, FilterBankGenerator* fbg, EventBase::EventTypeID_t tid, unsigned int syc, unsigned int suc, unsigned int svc);
00063   //! destructor
00064   virtual ~SegmentedColorGenerator();
00065 
00066   static std::string getClassDescription() { return "Converts a FilterBankGenerator's data into indexed color"; }
00067 
00068   //! should receive FilterBankEvents from any standard format FilterBankGenerator (like RawCameraGenerator)
00069   virtual void processEvent(const EventBase& event);
00070 
00071   //! loads a threshold map into memory from a file, returns -1U if failed, otherwise returns corresponding channel
00072   virtual unsigned int loadThresholdMap(const std::string& tm_file);
00073 
00074   //! loads color information from a file, returns false if failed, true otherwise
00075   virtual bool loadColorInfo(const std::string& col_file);
00076 
00077   //! returns the number of different colors available
00078   virtual unsigned int getNumColors() const { return numColors; }
00079 
00080   //! gives direct access to the color information
00081   virtual const color_class_state * getColors() const { return colors; }
00082 
00083   //! gives direct access to the color information
00084   virtual color_class_state * getColors() { return colors; }
00085 
00086   //! returns index of color corresponding to a string (uses a fast hash lookup), or -1U if not found
00087   unsigned int getColorIndex(const char * name) const {
00088     hashmap::const_iterator i;
00089     i=colorNames.find(name);
00090     return (i==colorNames.end())?-1U:i->second;
00091   }
00092 
00093   //! returns index of color corresponding to a string (uses a fast hash lookup), or -1U if not found
00094   unsigned int getColorIndex(const std::string& name) const { return getColorIndex(name.c_str()); }
00095 
00096   //! returns index of color corresponding to a specific rgb color, or -1U if not found
00097   unsigned int getColorIndex(const rgb color) const {
00098     for(unsigned int index = 0; index < getNumColors(); index++)
00099       if(getColorRGB((int)index) == color)
00100         return index;
00101     return -1U;
00102   }
00103 
00104 
00105   //! returns rgb struct (from colors.h) corresponding to an int index.  Returns black if index is invalid.
00106   rgb getColorRGB(const unsigned int index) const {
00107     return (index>=numColors ? rgb() : getColors()[index].color);
00108   }
00109 
00110   //! returns rgb struct (from colors.h) corresponding to a string.  Returns black if index is invalid.
00111   rgb getColorRGB(const char * name) const {
00112     return getColorRGB(getColorIndex(name));
00113   }
00114 
00115   //! returns rgb struct (from colors.h) corresponding to a string.  Returns black if index is invalid.
00116   rgb getColorRGB(const std::string& name) const {
00117     return getColorRGB(name.c_str());
00118   }
00119 
00120         //! returns the name of a color given its index
00121        const char* getColorName(const unsigned int index) const {
00122                return (index>=numColors ? NULL : getColors()[index].name);
00123   }
00124 
00125   virtual unsigned int getBinSize() const;
00126   virtual unsigned int loadBuffer(const char buf[], unsigned int len);
00127   virtual unsigned int saveBuffer(char buf[], unsigned int len) const;
00128   virtual bool encodeColorsInc(char*& buf, unsigned int& len) const; //!< in case you want to only save the color info but not the image (this is binary - *not* the same format as what's read in loadColorInfo)
00129   virtual bool decodeColorsInc(const char*& buf, unsigned int& len); //!< in case you want to only load the color info but not the image (this is binary - *not* the same format as what's read in loadColorInfo)
00130 
00131 
00132 protected:
00133   //! thrown if no threshold maps are available
00134   class NoThresholdException : public std::exception {
00135   public:
00136     //! returns descriptive error string
00137     virtual const char * what() const throw() { return "SegmentedColorGenerator::calcImage(): can't segment image without any loaded threshold maps"; }
00138   };
00139 
00140   static const unsigned int BITS_Y = 4; //!< bits of discretization for Y channel in the threshold map
00141   static const unsigned int BITS_U = 6; //!< bits of discretization for U channel in the threshold map
00142   static const unsigned int BITS_V = 6; //!< bits of discretization for V channel in the threshold map
00143   static const unsigned int NUM_Y = 1 << BITS_Y; //!< levels of discretization for Y channel in the threshold map
00144   static const unsigned int NUM_U = 1 << BITS_U; //!< levels of discretization for U channel in the threshold map
00145   static const unsigned int NUM_V = 1 << BITS_V; //!< levels of discretization for V channel in the threshold map
00146   static const unsigned int MAX_COLORS = 20; //!< maximum number of different colors that can be segmented
00147 
00148   //! ignores @a nChannels - the number of channels is always the number of loaded threshold maps
00149   virtual void setNumImages(unsigned int nLayers, unsigned int nChannels);
00150   virtual void setDimensions(); //!< sets stride parameter to width (as set by FilterBankGenerator::setDimensions())
00151   //! creates the image cache width[layer]*height[layer] + 1 -- why plus one?  Because CMVision temporarily scribbles one-past end of each row
00152   virtual unsigned char * createImageCache(unsigned int layer, unsigned int chan) const;
00153   virtual void calcImage(unsigned int layer, unsigned int chan);
00154 
00155   unsigned int srcYChan; //!< the channel of the source's Y channel
00156   unsigned int srcUChan; //!< the channel of the source's U channel
00157   unsigned int srcVChan; //!< the channel of the source's V channel
00158 
00159   std::vector<cmap_t*> tmaps; //!< list of threshold maps so you can segment the same source different ways
00160   std::vector<std::string> tmapNames; //!< filename of each tmap;
00161 
00162   unsigned int numColors; //!< number of available colors
00163   color_class_state colors[MAX_COLORS]; //!< array of available colors
00164   hashmap colorNames; //!< look up color indexes corresponding to names
00165 
00166 private:
00167   SegmentedColorGenerator(const SegmentedColorGenerator& fbk); //!< don't call
00168   const SegmentedColorGenerator& operator=(const SegmentedColorGenerator& fbk); //!< don't call
00169 };
00170 
00171 /*! @file
00172  * @brief Describes SegmentedColorGenerator, which generates FilterBankEvents indexed color images based on a color threshold file
00173  * @author alokl (Creator)
00174  * @author ejt (reorganized)
00175  *
00176  * $Author: dst $
00177  * $Name: tekkotsu-4_0 $
00178  * $Revision: 1.17 $
00179  * $State: Exp $
00180  * $Date: 2006/11/12 09:08:05 $
00181  */
00182 
00183 #endif

Tekkotsu v4.0
Generated Thu Nov 22 00:54:55 2007 by Doxygen 1.5.4