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