Tekkotsu Homepage | Demos | Overview | Downloads | Dev. Resources | Reference | Credits |
SegmentedColorGenerator.hGo 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 |