Homepage Demos Overview Downloads Tutorials 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 <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