Homepage | Demos | Overview | Downloads | Dev. Resources | 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(unsigned int mysid, FilterBankGenerator * fbg, EventBase::EventTypeID_t tid); 00071 00072 //! destructor 00073 virtual ~RLEGenerator() { 00074 freeCaches(); 00075 destruct(); 00076 } 00077 00078 static std::string getClassDescription() { return "Compresses a FilterBankGenerator's channels using run length encoding"; } 00079 00080 //! should receive FilterBankEvents from any standard format FilterBankGenerator (like RawCameraGenerator) 00081 virtual void processEvent(const EventBase& event); 00082 00083 virtual unsigned int getBinSize() const; 00084 virtual unsigned int LoadBuffer(const char buf[], unsigned int len); 00085 virtual unsigned int SaveBuffer(char buf[], unsigned int len) const; 00086 00087 //! returns the number of runs for the image 00088 virtual unsigned int getNumRuns(unsigned int layer, unsigned int chan) { if(!imageValids[layer][chan]) getImage(layer,chan); return numRuns[layer][chan]; } 00089 //! returns the actual runs of the specified image -- returned pointer is to internal storage; do not free 00090 virtual run * getRuns(unsigned int layer, unsigned int chan) { return reinterpret_cast<run*>(getImage(layer,chan)); } 00091 //! returns a specific run of the specified image 00092 virtual const run& getRun(unsigned int layer, unsigned int chan, unsigned int i) { return reinterpret_cast<const run*>(getImage(layer,chan))[i]; } 00093 00094 //! in case you have inserted or removed runs during postprocessing, call this to update the count 00095 virtual void setNumRuns(unsigned int layer, unsigned int chan, unsigned int num) { numRuns[layer][chan]=num; } 00096 00097 protected: 00098 static const unsigned int MIN_EXP_RUN_LENGTH=8; //!< The expected minimum average length of each run 00099 static const unsigned int XMIT_BYTES_PER_RUN=sizeof(cmap_t)+sizeof(short)+sizeof(short); //!< number of bytes needed to send each run 00100 00101 virtual void setDimensions(); //!< sets the width, height, skip and stride, as well as #maxRuns 00102 virtual void setNumImages(unsigned int nLayers, unsigned int nChannels); 00103 virtual unsigned char * createImageCache(unsigned int layer, unsigned int chan) const; 00104 virtual void calcImage(unsigned int layer, unsigned int chan); 00105 virtual void destruct(); 00106 //! uses a heuristic to predict the maximum number of runs expected per layer 00107 unsigned int calcExpMaxRuns(unsigned int layer) const { return getWidth(layer)*getHeight(layer)/MIN_EXP_RUN_LENGTH; } 00108 00109 unsigned int ** numRuns; //!< a matrix of ints, holds the number of used runs for each image 00110 unsigned int * maxRuns; //!< the maximum number of runs possible for each layer 00111 00112 private: 00113 RLEGenerator(const RLEGenerator& fbk); //!< don't call 00114 const RLEGenerator& operator=(const RLEGenerator& fbk); //!< don't call 00115 }; 00116 00117 /*! @file 00118 * @brief Describes RLEGenerator, which generates RLE compressed FilterBankEvents (generally from indexed color images from, say, SegmentedColorGenerator) 00119 * @author alokl (Creator) 00120 * @author ejt (reorganized) 00121 * 00122 * $Author: ejt $ 00123 * $Name: tekkotsu-2_4_1 $ 00124 * $Revision: 1.8 $ 00125 * $State: Exp $ 00126 * $Date: 2005/06/01 05:47:58 $ 00127 */ 00128 00129 #endif |
Tekkotsu v2.4.1 |
Generated Tue Aug 16 16:32:48 2005 by Doxygen 1.4.4 |