Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

SketchData.h

Go to the documentation of this file.
00001 //-*-c++-*-
00002 
00003 #ifndef INCLUDED_SketchData_h
00004 #define INCLUDED_SketchData_h
00005 
00006 #include <valarray>
00007 #include <iostream>
00008 #include <stdexcept>
00009 #include <limits> // needed for findMinPlus
00010 #include <map>
00011 
00012 #include "Shared/LoadSave.h"
00013 #include "Shared/Config.h"
00014 #include "Shared/debuget.h" // needed for ASSERT macros
00015 #include "Vision/SegmentedColorGenerator.h"
00016 #include "Shared/ProjectInterface.h" // needed for defSegmentedColorGenerator
00017 
00018 #include "SketchTypes.h"
00019 #include "SketchDataRoot.h"
00020 #include "ViewerConnection.h"
00021 
00022 namespace DualCoding {
00023 
00024 class SketchSpace;
00025 template<typename T> class SketchPool;
00026 template<typename T> class Sketch;
00027 
00028 //! Holds the pixels for an individual sketch.
00029 
00030 /*! SketchData<T> holds the pixels for an individual sketch of type T, using a valarray<T>.  A collection of
00031     SketchData<T> objects is maintained in a SketchPool<T>.  Basic functions such as indexed access and empty test
00032     that are not implemented as Sketch operators are implemented as SketchData<T> member functions.  Sketch<T>
00033     overrides the -> operator to provide "smart pointer" access to these SketchData<T> functions.   */
00034 
00035 template<class T>
00036 class SketchData : public SketchDataRoot {
00037   //! the valarray which actually stores the image
00038   std::valarray<T> pixels;
00039 
00040   friend class Sketch<T>;
00041   friend class SketchPool<T>;
00042 
00043 public:
00044   //! Constructor.  Don't call this.  SketchData objects should only be created and managed by their SketchSpace
00045   SketchData(SketchSpace *_space);
00046   ~SketchData();
00047 
00048   //! The type of this sketch.
00049   virtual SketchType_t getType() const;  // must go here, not in SketchDataRoot, due to templating
00050 
00051   //! Address of the memory area containing the actual pixel data.
00052   T* getRawPixels() { return &(pixels[0]); }
00053 
00054   //! Address of the memory area containing the actual pixel data.
00055   const T* getRawPixels() const { return &(pixels[0]); }
00056 
00057   //! Serializes a sketch to a buffer, for transmission to the sketch viewer.
00058   unsigned int saveBuffer(char buf[], unsigned int avail) const;
00059 
00060   //@{
00061   //! Indexed access, with bounds checking
00062   T& at(size_t x);
00063 
00064   //! Subscripted (x,y) access, with bounds checking
00065   T& at(size_t x, size_t y);
00066 
00067   //@}
00068 
00069   //! Returns true if all pixels are zero.
00070   bool empty() const;
00071 
00072   //!@name Sum/Max/Min
00073   //@{
00074 
00075   //! Sum of pixels
00076   T sum() const;
00077 
00078   //! Max of pixel values
00079   T max() const;
00080 
00081   //! Index of first maximum-value pixel
00082   int findMax() const;
00083 
00084   //! Min of pixel values
00085   T min() const;
00086 
00087   //! Index of first minimum-value pixel
00088   int findMin() const;
00089 
00090   //! Min of non-zero pixel values
00091   T minPlus() const;
00092 
00093   //! Index of first minimum non-zero pixel, or -1 if none
00094   int findMinPlus() const;
00095 
00096   //! Mode (most common) pixel value
00097   T mode() const;
00098 
00099   //! Mode (most common) non-zero pixel value
00100   T modePlus() const;
00101 
00102   //@}
00103 
00104 protected:
00105   unsigned int savePixels(char buf[], unsigned int avail) const; //!< handle copying pixels to buffer
00106 
00107 private:
00108   SketchData (const SketchData& other); //!< never call this
00109 };
00110 
00111 } // namespace
00112 
00113 #include "SketchSpace.h"
00114 
00115 namespace DualCoding {
00116 
00117 template<class T>
00118 SketchData<T>::SketchData(SketchSpace *_space) :
00119   SketchDataRoot(_space), pixels(_space->getNumPixels()+1) {
00120   if  ( getType() == sketchUint || getType() == sketchFloat )
00121     colormap = jetMapScaled;
00122   else
00123     colormap = segMap;
00124 }
00125 
00126 template<class T> SketchData<T>::~SketchData() {}
00127 
00128 template <class T>
00129 SketchData<T>::SketchData (const SketchData<T> &other)
00130   : SketchDataRoot(other.space), pixels(other.pixels) {}
00131 
00132 template<>
00133 inline SketchType_t SketchData<bool>:: getType() const { return sketchBool; }
00134 template<>
00135 inline SketchType_t SketchData<uchar>::getType() const { return sketchUchar; }
00136 template<>
00137 inline SketchType_t SketchData<uint>::getType() const { return sketchUint; }
00138 template<>
00139 inline SketchType_t SketchData<float>::getType() const { return sketchFloat; }
00140 
00141 template<class T>
00142 T& SketchData<T>::at(size_t x) {
00143   if ( x < (unsigned int)(space->getWidth()*space->getHeight()) )
00144     return pixels[x];
00145   else
00146     throw std::out_of_range("Sketch subscript out of bounds");
00147 }
00148 
00149 template <class T>
00150 T& SketchData<T>::at(size_t x, size_t y) {
00151   if ( x < (unsigned int)(space->getWidth()) && y < (unsigned int)(space->getHeight()) )
00152     return pixels[y*space->getWidth()+x];
00153   else
00154     throw std::out_of_range("Sketch subscript out of bounds");
00155 }
00156 
00157 template <class T>
00158 bool SketchData<T>::empty() const {
00159   for ( size_t i=0; i < pixels.size(); i++ )
00160     if ( pixels[i] != 0 )
00161       return false;
00162   return true;
00163 }
00164 
00165 template <class T>
00166 T SketchData<T>::sum() const {
00167   T result = pixels[0];
00168   for (unsigned int i=1; i<getNumPixels(); i++)
00169     result += pixels[i];
00170   return result;
00171 }
00172 
00173 template <class T>
00174 T SketchData<T>::max() const {
00175   T result = pixels[0];
00176   for (unsigned int i=1; i<getNumPixels(); i++)
00177     result = std::max(result,pixels[i]);
00178   return result;
00179 }
00180 
00181 template <class T>
00182 int SketchData<T>::findMax() const {
00183   T maxval = pixels[0];
00184   int maxidx = -1;
00185   for (unsigned int i = 1; i<getNumPixels(); i++)
00186     if ( pixels[i] > maxval ) {
00187       maxidx = i;
00188       maxval = pixels[i];
00189     }
00190   return maxidx;
00191 }
00192 
00193 template <class T>
00194 T SketchData<T>::min() const {
00195   T result = pixels[0];
00196   for (unsigned int i=1; i<getNumPixels(); i++)
00197     result = std::min(result,pixels[i]);
00198   return result;
00199 }
00200 
00201 template <class T>
00202 int SketchData<T>::findMin() const {
00203   T minval = pixels[0];
00204   int minidx = -1;
00205   for (unsigned int i = 1; i<getNumPixels(); i++)
00206     if ( pixels[i] < minval ) {
00207       minidx = i;
00208       minval = pixels[i];
00209     }
00210   return minidx;
00211 }
00212 
00213 template <class T>
00214 T SketchData<T>::minPlus() const {
00215   T result = 0;
00216   unsigned int i = 0;
00217   for (; i<getNumPixels(); i++)
00218     if ( pixels[i] != 0 ) {
00219       result = pixels[i];
00220       break;
00221     }
00222   for (; i<getNumPixels(); i++)
00223     if ( pixels[i] != 0 )
00224       result = std::min(result,pixels[i]);
00225   return result;
00226 }
00227 
00228 template <class T>
00229 int SketchData<T>::findMinPlus() const {
00230   T minval=std::numeric_limits<T>::max();
00231   int minidx = -1;
00232   for (unsigned int i=getNumPixels()-1; i!=-1U; --i)
00233     if ( pixels[i] != 0 && pixels[i] <= minval ) {
00234       minidx = i;
00235       minval = pixels[i];
00236     }
00237   return minidx;
00238 }
00239 
00240 template <class T>
00241 T SketchData<T>::mode() const {
00242   std::map<T,size_t> hist;
00243   for(unsigned int i=0; i<getNumPixels(); i++)
00244     hist[pixels[i]]++;
00245   T maxval=T();
00246   size_t maxcnt=0;
00247   for(typename std::map<T,size_t>::const_iterator it=hist.begin(); it!=hist.end(); ++it) {
00248     if(maxcnt<=it->second) {
00249       maxval=it->first;
00250       maxcnt=it->second;
00251     }
00252   }
00253   return maxval;
00254 }
00255 
00256 template <class T>
00257 T SketchData<T>::modePlus() const {
00258   std::map<T,size_t> hist;
00259   for(unsigned int i=0; i<getNumPixels(); i++)
00260     if(pixels[i]!=0)
00261       hist[pixels[i]]++;
00262   T maxval=T();
00263   size_t maxcnt=0;
00264   for(typename std::map<T,size_t>::const_iterator it=hist.begin(); it!=hist.end(); ++it) {
00265     if(maxcnt<=it->second) {
00266       maxval=it->first;
00267       maxcnt=it->second;
00268     }
00269   }
00270   return maxval;
00271 }
00272 
00273 
00274 // ================================================================
00275 
00276 #define SKETCHDATA_ENCODE(a) \
00277   if(!LoadSave::encodeInc(a,buf,avail,"SketchData encode ran out of space at %s:%u\n",__FILE__,__LINE__)) return 0;
00278 
00279 template <class T>
00280 unsigned int SketchData<T>::saveBuffer(char buf[], unsigned int avail) const
00281 {
00282   char* packet = buf; // beginning of packet
00283   static int frameNum = 0; // should this become a static member variable?
00284   unsigned int used=0;
00285 
00286   SKETCHDATA_ENCODE("TekkotsuImage");
00287   SKETCHDATA_ENCODE(Config::vision_config::RawCamConfig::ENCODE_SINGLE_CHANNEL);
00288   SKETCHDATA_ENCODE(Config::vision_config::RawCamConfig::COMPRESS_NONE);
00289   SKETCHDATA_ENCODE(getWidth());
00290   SKETCHDATA_ENCODE(getHeight());
00291   SKETCHDATA_ENCODE(get_time()); // is this what should be used for time stamp?
00292   SKETCHDATA_ENCODE(frameNum++);
00293 
00294   // encode filterbank info
00295   SKETCHDATA_ENCODE("FbkImage");
00296   SKETCHDATA_ENCODE(getWidth());
00297   SKETCHDATA_ENCODE(getHeight());
00298   SKETCHDATA_ENCODE(CAM_LAYER);
00299   SKETCHDATA_ENCODE(CAM_CHANNEL);
00300 
00301   // encode actual image data
00302   SKETCHDATA_ENCODE("SketchImage");
00303   SKETCHDATA_ENCODE((unsigned char)getType());
00304   const unsigned int imglength  = savePixels(buf,avail);
00305   if(imglength==0)
00306     return 0; // savePixels should have already reported the error
00307   avail-=imglength;
00308   buf+=imglength;
00309 
00310   // encode color table(same as color table of segmentedcolorgenerator for now
00311   used = (dynamic_cast<SegmentedColorGenerator*>
00312     (ProjectInterface::defSegmentedColorGenerator))->encodeColorsInc(buf,avail);
00313   return buf-packet;
00314 }
00315 
00316 template <class T>
00317 unsigned int SketchData<T>::savePixels(char buf[], unsigned int avail) const
00318 {
00319   const unsigned int imglength  = getWidth() * getHeight() * sizeof(T);
00320   ASSERTRETVAL(imglength<avail,"Insufficient buffer space for image",0);
00321   memcpy(buf,(const unsigned char*)&(pixels[0]),imglength);
00322   return imglength;
00323 }
00324 
00325 #ifdef __POWERPC__
00326 //bool can be 4 bytes on PowerPC systems
00327 template<>
00328 inline unsigned int SketchData<bool>::savePixels(char buf[], unsigned int avail) const
00329 {
00330   const unsigned int imglength  = getWidth() * getHeight() * sizeof(char);
00331   ASSERTRETVAL(imglength<avail,"Insufficient buffer space for image",0);
00332   if(sizeof(bool)==sizeof(char))
00333     memcpy(buf,(const unsigned char*)&(pixels[0]),imglength);
00334   else
00335     for(unsigned int i=0; i<imglength; ++i)
00336       buf[i]=pixels[i]; //do manual copy to ensure one byte per pixel
00337   return imglength;
00338 }
00339 #endif
00340 
00341 } // namespace
00342 
00343 /*! @file
00344  * @brief A resource which holds the image date for a Sketch, managed collectively by a SketchSpace
00345  * @author neilh (Creator)
00346  *
00347  * $Author: dst $
00348  * $Name: tekkotsu-4_0 $
00349  * $Revision: 1.22 $
00350  * $State: Exp $
00351  * $Date: 2007/08/25 01:49:16 $
00352  */
00353 
00354 #endif

DualCoding 4.0
Generated Thu Nov 22 00:52:36 2007 by Doxygen 1.5.4