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  *  The RLE produced isn't quite optimal in terms of size.  To make it
00014  *  easier to directly process the RLE for recognition tasks, each run
00015  *  will be broken at the end of the row.  So a solid image will still
00016  *  contain <var>height</var> runs instead of just one.
00017  *
00018  *  Also, the run structures contain extra fields to be used for
00019  *  region connecting.  These fields aren't sent over wireless, and
00020  *  are filled in by the RegionGenerator.  I don't necessarily like
00021  *  the tight coupling between the RLE and Region Generators that this
00022  *  requires, but it saves a copy of the data and allows us to use
00023  *  CMVision instead of rewriting.
00024  *
00025  *  Note that since the amount of data for each row is variable
00026  *  (depends on the complexity of that row) the row stride and skip
00027  *  are useless.  You'll have to process the RLE yourself to find a
00028  *  given index.
00029  *
00030  *  If the incoming events is a SegmentedColorFilterBankEvents, then
00031  *  it will post a SegmentedColorFilterBank to retain additional color
00032  *  information.  If the event is of a different format, it will post
00033  *  a regular FilterBankEvent.
00034  *  
00035  *  Note that although you could hook this class up to a raw intensity
00036  *  image, it is primarily of use with segmented color images because
00037  *  it doesn't handle gradients or noise well at all - this type of
00038  *  encoding/compression assumes cartoonish images of large blocks of
00039  *  flat color.  However, if you have some kind of other preprocessing
00040  *  that also provides suitable data, this can encode it for you.
00041  *  
00042  */
00043 class RLEGenerator : public FilterBankGenerator {
00044 public:
00045   typedef uchar cmap_t; //!< the type to use for a color index
00046   typedef CMVision::run<cmap_t> run; //!< use the CMVision library's run structure
00047   
00048   //! constructor
00049   RLEGenerator(EventBase::EventGeneratorID_t gid, unsigned int sid, unsigned int mysid);
00050   //! destructor
00051   virtual ~RLEGenerator();
00052 
00053   static std::string getClassDescription() { return "Compresses a FilterBankGenerator's channels using run length encoding"; }
00054 
00055   //! should receive FilterBankEvents from any standard format FilterBankGenerator (like RawCameraGenerator)
00056   virtual void processEvent(const EventBase& event);
00057 
00058   virtual unsigned int getBinSize() const;
00059   virtual unsigned int LoadBuffer(const char buf[], unsigned int len);
00060   virtual unsigned int SaveBuffer(char buf[], unsigned int len) const;
00061 
00062   //! returns the number of runs for the image
00063   virtual unsigned int getNumRuns(unsigned int layer, unsigned int chan) const { if(!imageValids[layer][chan]) getImage(layer,chan); return numRuns[layer][chan]; }
00064   //! returns the actual runs of the specified image
00065   virtual const run * getRuns(unsigned int layer, unsigned int chan) const { return reinterpret_cast<const run*>(getImage(layer,chan)); }
00066   //! returns a specific run of the specified image
00067   virtual const run& getRun(unsigned int layer, unsigned int chan, unsigned int i) const { return reinterpret_cast<const run*>(getImage(layer,chan))[i]; }
00068   
00069   //! returns the generator this is receiving its events from (or the last one anyway)
00070   virtual FilterBankGenerator * getSourceGenerator() const { return src; }
00071 
00072 protected:
00073   static const unsigned int MIN_EXP_RUN_LENGTH=8; //!< The expected minimum average length of each run
00074   static const unsigned int XMIT_BYTES_PER_RUN=sizeof(cmap_t)+sizeof(short)+sizeof(short); //!< number of bytes needed to send each run
00075 
00076   virtual void setDimensions(); //!< sets the width, height, skip and stride, as well as #maxRuns
00077   virtual void setNumImages(unsigned int nLayers, unsigned int nChannels);
00078   virtual unsigned char * createImageCache(unsigned int layer, unsigned int chan) const;
00079   virtual void calcImage(unsigned int layer, unsigned int chan) const;
00080   virtual void destruct();
00081   //! uses a heuristic to predict the maximum number of runs expected per layer
00082   unsigned int calcExpMaxRuns(unsigned int layer) const { return getWidth(layer)*getHeight(layer)/MIN_EXP_RUN_LENGTH; }
00083 
00084   FilterBankGenerator * src; //!< the generator of the last FilterBankEvent received
00085 
00086   unsigned int ** numRuns; //!< a matrix of ints, holds the number of used runs for each image
00087   unsigned int * maxRuns; //!< the maximum number of runs possible for each layer
00088 
00089 private:
00090   RLEGenerator(const RLEGenerator& fbk); //!< don't call
00091   const RLEGenerator& operator=(const RLEGenerator& fbk); //!< don't call
00092 };
00093 
00094 /*! @file 
00095  * @brief Describes RLEGenerator, which generates RLE compressed FilterBankEvents (generally from indexed color images from, say, SegmentedColorGenerator)
00096  * @author alokl (Creator)
00097  * @author ejt (reorganized)
00098  *
00099  * $Author: ejt $
00100  * $Name: tekkotsu-2_0 $
00101  * $Revision: 1.4 $
00102  * $State: Exp $
00103  * $Date: 2004/01/18 10:16:59 $
00104  */
00105 
00106 #endif

Tekkotsu v2.0
Generated Wed Jan 21 03:20:29 2004 by Doxygen 1.3.4