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   
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) const { if(!imageValids[layer][chan]) getImage(layer,chan); return numRuns[layer][chan]; }
00089   //! returns the actual runs of the specified image
00090   virtual const run * getRuns(unsigned int layer, unsigned int chan) const { return reinterpret_cast<const 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) const { return reinterpret_cast<const run*>(getImage(layer,chan))[i]; }
00093   
00094 protected:
00095   static const unsigned int MIN_EXP_RUN_LENGTH=8; //!< The expected minimum average length of each run
00096   static const unsigned int XMIT_BYTES_PER_RUN=sizeof(cmap_t)+sizeof(short)+sizeof(short); //!< number of bytes needed to send each run
00097 
00098   virtual void setDimensions(); //!< sets the width, height, skip and stride, as well as #maxRuns
00099   virtual void setNumImages(unsigned int nLayers, unsigned int nChannels);
00100   virtual unsigned char * createImageCache(unsigned int layer, unsigned int chan) const;
00101   virtual void calcImage(unsigned int layer, unsigned int chan) const;
00102   virtual void destruct();
00103   //! uses a heuristic to predict the maximum number of runs expected per layer
00104   unsigned int calcExpMaxRuns(unsigned int layer) const { return getWidth(layer)*getHeight(layer)/MIN_EXP_RUN_LENGTH; }
00105 
00106   unsigned int ** numRuns; //!< a matrix of ints, holds the number of used runs for each image
00107   unsigned int * maxRuns; //!< the maximum number of runs possible for each layer
00108 
00109 private:
00110   RLEGenerator(const RLEGenerator& fbk); //!< don't call
00111   const RLEGenerator& operator=(const RLEGenerator& fbk); //!< don't call
00112 };
00113 
00114 /*! @file 
00115  * @brief Describes RLEGenerator, which generates RLE compressed FilterBankEvents (generally from indexed color images from, say, SegmentedColorGenerator)
00116  * @author alokl (Creator)
00117  * @author ejt (reorganized)
00118  *
00119  * $Author: ejt $
00120  * $Name: tekkotsu-2_2 $
00121  * $Revision: 1.7 $
00122  * $State: Exp $
00123  * $Date: 2004/02/18 21:13:32 $
00124  */
00125 
00126 #endif

Tekkotsu v2.2
Generated Tue Oct 19 14:19:15 2004 by Doxygen 1.3.9.1