Homepage | Demos | Overview | Downloads | Tutorials | Reference | Credits |
00001 //-*-c++-*- 00002 #ifndef INCLUDED_RLEGenerator_h_ 00003 #define INCLUDED_RLEGenerator_h_ 00004 00005 #include "Vision/FilterBankGenerator.h" 00006 #include "Vision/cmvision.h" 00007 #include <ext/hash_map> 00008 #include <vector> 00009 00010 //! Generates RLE compressed FilterBankEvents (generally from indexed color images from, say, SegmentedColorGenerator) 00011 /*! Uses the CMVision library for main processing. 00012 * 00013 * The RLE produced isn't quite optimal in terms of size. To make it 00014 * easier to directly process the RLE for recognition tasks, each run 00015 * will be broken at the end of the row. So a solid image will still 00016 * contain <var>height</var> runs instead of just one. 00017 * 00018 * Also, the run structures contain extra fields to be used for 00019 * region connecting. These fields aren't sent over wireless, and 00020 * are filled in by the RegionGenerator. I don't necessarily like 00021 * the tight coupling between the RLE and Region Generators that this 00022 * requires, but it saves a copy of the data and allows us to use 00023 * CMVision instead of rewriting. 00024 * 00025 * Note that since the amount of data for each row is variable 00026 * (depends on the complexity of that row) the row stride and skip 00027 * are useless. You'll have to process the RLE yourself to find a 00028 * given index. 00029 * 00030 * If the incoming events is a SegmentedColorFilterBankEvents, then 00031 * it will post a SegmentedColorFilterBank to retain additional color 00032 * information. If the event is of a different format, it will post 00033 * a regular FilterBankEvent. 00034 * 00035 * Note that although you could hook this class up to a raw intensity 00036 * image, it is primarily of use with segmented color images because 00037 * it doesn't handle gradients or noise well at all - this type of 00038 * encoding/compression assumes cartoonish images of large blocks of 00039 * flat color. However, if you have some kind of other preprocessing 00040 * that also provides suitable data, this can encode it for you. 00041 * 00042 */ 00043 class RLEGenerator : public FilterBankGenerator { 00044 public: 00045 typedef uchar cmap_t; //!< the type to use for a color index 00046 typedef CMVision::run<cmap_t> run; //!< use the CMVision library's run structure 00047 00048 //! constructor 00049 RLEGenerator(EventBase::EventGeneratorID_t gid, unsigned int sid, unsigned int mysid); 00050 //! destructor 00051 virtual ~RLEGenerator(); 00052 00053 static std::string getClassDescription() { return "Compresses a FilterBankGenerator's channels using run length encoding"; } 00054 00055 //! should receive FilterBankEvents from any standard format FilterBankGenerator (like RawCameraGenerator) 00056 virtual void processEvent(const EventBase& event); 00057 00058 virtual unsigned int getBinSize() const; 00059 virtual unsigned int LoadBuffer(const char buf[], unsigned int len); 00060 virtual unsigned int SaveBuffer(char buf[], unsigned int len) const; 00061 00062 //! returns the number of runs for the image 00063 virtual unsigned int getNumRuns(unsigned int layer, unsigned int chan) const { if(!imageValids[layer][chan]) getImage(layer,chan); return numRuns[layer][chan]; } 00064 //! returns the actual runs of the specified image 00065 virtual const run * getRuns(unsigned int layer, unsigned int chan) const { return reinterpret_cast<const run*>(getImage(layer,chan)); } 00066 //! returns a specific run of the specified image 00067 virtual const run& getRun(unsigned int layer, unsigned int chan, unsigned int i) const { return reinterpret_cast<const run*>(getImage(layer,chan))[i]; } 00068 00069 //! returns the generator this is receiving its events from (or the last one anyway) 00070 virtual FilterBankGenerator * getSourceGenerator() const { return src; } 00071 00072 protected: 00073 static const unsigned int MIN_EXP_RUN_LENGTH=8; //!< The expected minimum average length of each run 00074 static const unsigned int XMIT_BYTES_PER_RUN=sizeof(cmap_t)+sizeof(short)+sizeof(short); //!< number of bytes needed to send each run 00075 00076 virtual void setDimensions(); //!< sets the width, height, skip and stride, as well as #maxRuns 00077 virtual void setNumImages(unsigned int nLayers, unsigned int nChannels); 00078 virtual unsigned char * createImageCache(unsigned int layer, unsigned int chan) const; 00079 virtual void calcImage(unsigned int layer, unsigned int chan) const; 00080 virtual void destruct(); 00081 //! uses a heuristic to predict the maximum number of runs expected per layer 00082 unsigned int calcExpMaxRuns(unsigned int layer) const { return getWidth(layer)*getHeight(layer)/MIN_EXP_RUN_LENGTH; } 00083 00084 FilterBankGenerator * src; //!< the generator of the last FilterBankEvent received 00085 00086 unsigned int ** numRuns; //!< a matrix of ints, holds the number of used runs for each image 00087 unsigned int * maxRuns; //!< the maximum number of runs possible for each layer 00088 00089 private: 00090 RLEGenerator(const RLEGenerator& fbk); //!< don't call 00091 const RLEGenerator& operator=(const RLEGenerator& fbk); //!< don't call 00092 }; 00093 00094 /*! @file 00095 * @brief Describes RLEGenerator, which generates RLE compressed FilterBankEvents (generally from indexed color images from, say, SegmentedColorGenerator) 00096 * @author alokl (Creator) 00097 * @author ejt (reorganized) 00098 * 00099 * $Author: ejt $ 00100 * $Name: tekkotsu-2_0 $ 00101 * $Revision: 1.4 $ 00102 * $State: Exp $ 00103 * $Date: 2004/01/18 10:16:59 $ 00104 */ 00105 00106 #endif
Tekkotsu v2.0 |
Generated Wed Jan 21 03:20:29 2004 by Doxygen 1.3.4 |