Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

RLEGenerator.h

Go 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