| Homepage | Demos | Overview | Downloads | Tutorials | Reference | Credits |
RLEGenerator.hGo to the documentation of this file.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 * getImage() will return the first run, from the upper left hand 00014 * corner. The type is RLEGenerator::run. 00015 * 00016 * The RLE produced isn't quite optimal in terms of size. To make it 00017 * easier to directly process the RLE for recognition tasks, each run 00018 * will be broken at the end of the row. So a solid image will still 00019 * contain <var>height</var> runs instead of just one. 00020 * 00021 * Also, the run structures contain extra fields to be used for 00022 * region connecting. These fields aren't sent over wireless, and 00023 * are filled in by the RegionGenerator. I don't necessarily like 00024 * the tight coupling between the RLE and Region Generators that this 00025 * requires, but it saves a copy of the data and allows us to use 00026 * CMVision instead of rewriting. 00027 * 00028 * Note that since the amount of data for each row is variable 00029 * (depends on the complexity of that row) the row stride and skip 00030 * are useless. You'll have to process the RLE yourself to find a 00031 * given index. 00032 * 00033 * If the incoming events is a SegmentedColorFilterBankEvents, then 00034 * it will post a SegmentedColorFilterBank to retain additional color 00035 * information. If the event is of a different format, it will post 00036 * a regular FilterBankEvent. 00037 * 00038 * Note that although you could hook this class up to a raw intensity 00039 * image, it is primarily of use with segmented color images because 00040 * it doesn't handle gradients or noise well at all - this type of 00041 * encoding/compression assumes cartoonish images of large blocks of 00042 * flat color. However, if you have some kind of other preprocessing 00043 * that also provides suitable data, this can encode it for you. 00044 * 00045 * The format used for serialization is: (code is in SaveBuffer()) 00046 * - <@c FilterBankGenerator: superclass header> <i>(First saves the superclass's info)</i> 00047 * - <@c string: "RLEImage"> <i>(remember a 'string' is len+str+0; so this is the literal "\010\0\0\0RLEImage\0"; also remember "\010" is octal for 8)</i> 00048 * - <@c unsigned @c int: num_runs> <i>(how many runs will follow)</i> 00049 * - for each of num_runs: 00050 * - <@c char: color> <i>(index value of color of run)</i> 00051 * - <@c short: x> <i>(x position of start of run ("unknown" runs are skipped - assume index 0 for pixels which are jumped))</i> 00052 * - <@c short: width> <i>(length of run, will not exceed remaining width of image)</i> 00053 * 00054 * Note that the RLEGenerator doesn't save the color infomation 00055 * regarding what each index value "means". This is just a 00056 * compression stage, pure and simple. You'll need to look at the 00057 * RLEGenerator's source (@e probably SegmentedColorGenerator, but 00058 * doesn't @e have to be) to determine how to interpret the indicies. 00059 * 00060 * @see SegCamBehavior for information on transmission over wireless. 00061 * 00062 * @see FilterBankGenerator more information on serialization 00063 */ 00064 class RLEGenerator : public FilterBankGenerator { 00065 public: 00066 typedef uchar cmap_t; //!< the type to use for a color index 00067 typedef CMVision::run<cmap_t> run; //!< use the CMVision library's run structure 00068 00069 //! constructor 00070 RLEGenerator(EventBase::EventGeneratorID_t gid, unsigned int sid, unsigned int mysid); 00071 //! destructor 00072 virtual ~RLEGenerator(); 00073 00074 static std::string getClassDescription() { return "Compresses a FilterBankGenerator's channels using run length encoding"; } 00075 00076 //! should receive FilterBankEvents from any standard format FilterBankGenerator (like RawCameraGenerator) 00077 virtual void processEvent(const EventBase& event); 00078 00079 virtual unsigned int getBinSize() const; 00080 virtual unsigned int LoadBuffer(const char buf[], unsigned int len); 00081 virtual unsigned int SaveBuffer(char buf[], unsigned int len) const; 00082 00083 //! returns the number of runs for the image 00084 virtual unsigned int getNumRuns(unsigned int layer, unsigned int chan) const { if(!imageValids[layer][chan]) getImage(layer,chan); return numRuns[layer][chan]; } 00085 //! returns the actual runs of the specified image 00086 virtual const run * getRuns(unsigned int layer, unsigned int chan) const { return reinterpret_cast<const run*>(getImage(layer,chan)); } 00087 //! returns a specific run of the specified image 00088 virtual const run& getRun(unsigned int layer, unsigned int chan, unsigned int i) const { return reinterpret_cast<const run*>(getImage(layer,chan))[i]; } 00089 00090 //! returns the generator this is receiving its events from (or the last one anyway) 00091 virtual FilterBankGenerator * getSourceGenerator() const { return src; } 00092 00093 protected: 00094 static const unsigned int MIN_EXP_RUN_LENGTH=8; //!< The expected minimum average length of each run 00095 static const unsigned int XMIT_BYTES_PER_RUN=sizeof(cmap_t)+sizeof(short)+sizeof(short); //!< number of bytes needed to send each run 00096 00097 virtual void setDimensions(); //!< sets the width, height, skip and stride, as well as #maxRuns 00098 virtual void setNumImages(unsigned int nLayers, unsigned int nChannels); 00099 virtual unsigned char * createImageCache(unsigned int layer, unsigned int chan) const; 00100 virtual void calcImage(unsigned int layer, unsigned int chan) const; 00101 virtual void destruct(); 00102 //! uses a heuristic to predict the maximum number of runs expected per layer 00103 unsigned int calcExpMaxRuns(unsigned int layer) const { return getWidth(layer)*getHeight(layer)/MIN_EXP_RUN_LENGTH; } 00104 00105 FilterBankGenerator * src; //!< the generator of the last FilterBankEvent received 00106 00107 unsigned int ** numRuns; //!< a matrix of ints, holds the number of used runs for each image 00108 unsigned int * maxRuns; //!< the maximum number of runs possible for each layer 00109 00110 private: 00111 RLEGenerator(const RLEGenerator& fbk); //!< don't call 00112 const RLEGenerator& operator=(const RLEGenerator& fbk); //!< don't call 00113 }; 00114 00115 /*! @file 00116 * @brief Describes RLEGenerator, which generates RLE compressed FilterBankEvents (generally from indexed color images from, say, SegmentedColorGenerator) 00117 * @author alokl (Creator) 00118 * @author ejt (reorganized) 00119 * 00120 * $Author: ejt $ 00121 * $Name: tekkotsu-2_0_1+Doc $ 00122 * $Revision: 1.6 $ 00123 * $State: Exp $ 00124 * $Date: 2004/02/05 23:33:48 $ 00125 */ 00126 00127 #endif |
|
Tekkotsu v2.0.1+Doc |
Generated Mon Feb 9 22:16:50 2004 by Doxygen 1.3.5 |