Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

RealVoxel.H

Go to the documentation of this file.
00001 /*!@file PointCloud/RealVoxel.H Open Scene Graph Utils */
00002 
00003 // //////////////////////////////////////////////////////////////////// //
00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2003   //
00005 // by the University of Southern California (USC) and the iLab at USC.  //
00006 // See http://iLab.usc.edu for information about this project.          //
00007 // //////////////////////////////////////////////////////////////////// //
00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00010 // in Visual Environments, and Applications'' by Christof Koch and      //
00011 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00012 // pending; application number 09/912,225 filed July 23, 2001; see      //
00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00014 // //////////////////////////////////////////////////////////////////// //
00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00016 //                                                                      //
00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00018 // redistribute it and/or modify it under the terms of the GNU General  //
00019 // Public License as published by the Free Software Foundation; either  //
00020 // version 2 of the License, or (at your option) any later version.     //
00021 //                                                                      //
00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00025 // PURPOSE.  See the GNU General Public License for more details.       //
00026 //                                                                      //
00027 // You should have received a copy of the GNU General Public License    //
00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00030 // Boston, MA 02111-1307 USA.                                           //
00031 // //////////////////////////////////////////////////////////////////// //
00032 //
00033 // Primary maintainer for this file: T. Nathan Mundhenk <mundhenk@usc.edu>
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/PointCloud/RealVoxel.H $
00035 // $Id: RealVoxel.H 10794 2009-02-08 06:21:09Z itti $
00036 //
00037 
00038 #ifndef REALVOXEL_H_DEFINED
00039 #define REALVOXEL_H_DEFINED
00040 
00041 #include "Image/ArrayData.H"
00042 #include "Image/Pixels.H"
00043 #include "PointCloud/Point.H"
00044 #include "PointCloud/VoxelImage.H"
00045 
00046 #include <cstdlib>
00047 #include <iostream>
00048 #include <string>
00049 
00050 // ######################################################################
00051 // ######################################################################
00052 // ######################################################################
00053 //! Create, store and get real voxels (non-sparse voxel images), Base Class
00054 template <class T>
00055 class RealVoxel : public
00056 VoxelImage<T,RealVoxel<T>,ArrayHandle<T> >
00057 {
00058 public:
00059   //typedef T VOX;
00060   typedef ArrayHandle<T> BASE_IMAGE;
00061 
00062   //! Create a new real voxel image which is blank
00063   RealVoxel();
00064 
00065   //! Copy a new real voxel image of size x,y,z
00066   RealVoxel(const T* inarray,
00067             const unsigned int size_x,
00068             const unsigned int size_y,
00069             const unsigned int size_z);
00070 
00071   //! Create a new real voxel image of size x,y,z
00072   RealVoxel(const unsigned int size_x,
00073             const unsigned int size_y,
00074             const unsigned int size_z,
00075             const InitPolicy init = NO_INIT);
00076 
00077   //! Create a new real voxel image of coord size
00078   RealVoxel(const Point<int,3>& coord_size,
00079             const InitPolicy init = NO_INIT);
00080 
00081   //! Create a new real voxel image from another
00082   RealVoxel(const RealVoxel<T>& A);
00083 
00084   virtual ~RealVoxel();
00085 
00086   //! Free memory and switch to uninitialized state.
00087   /*! Note that it is \b NOT necessary to call this function to ensure
00088       proper cleanup, that will be done in the destructor by
00089       default. Rather, freeMem() is offered just as a performance
00090       optimization, to allow you to release a potentially large chunk
00091       of memory when you are finished using it. */
00092   void freeMem();
00093 
00094   //! Swap the contents of two images
00095   void swap(RealVoxel<T>& other);
00096 
00097   //! Use existing memory.
00098   /*! This is potentially dangerous and should really be avoided. The
00099       only case where this really is useful is to attach an image to
00100       an existing memory segment that is shared or into which data is
00101       streaming via DMA. */
00102   void attach(T* array,
00103                      const unsigned int width,
00104                      const unsigned int height,
00105                      const unsigned int depth);
00106 
00107   //! Detach previously attach()'ed image.
00108   /*! The main purpose of detach() is to make sure that this Image
00109       object does not continue to point at attach()'ed memory after
00110       that memory has been freed. Nevertheless, this function is not
00111       strictly necessary to ensure correct memory handling, since the
00112       Image destructor will only try to free memory if that memory is
00113       owned (i.e., not attach()'ed). All that it does is release any
00114       association with a previously attach()'ed memory block, by
00115       setting the current image to a new empty (zero-by-zero)
00116       ArrayData object. We assume that attached memory will be
00117       destroyed later. */
00118   void detach();
00119 
00120   //! Return a new image object with a deep copy of the underlying data
00121   RealVoxel<T> deepcopy() const;
00122 
00123   //! Free mem and realloc new array (array contents are lost).
00124   void resize(const unsigned int size_x,
00125               const unsigned int size_y,
00126               const unsigned int size_z,
00127               const bool do_clear = false);
00128 
00129   //! Free mem and realloc new array (array contents are lost).
00130   void resize(const Point<int,3>& coord_size,
00131                      const bool do_clear = false);
00132 
00133   //! clear contents (or set to given value)
00134   void clear(const T& val = T());
00135 
00136   //! inefficent access to get x,y,z if possible use iterator
00137   /*! if the virtual voxel does not exist (nothing is there) then it will
00138       return false and vox will be null.
00139   */
00140   virtual bool getVal(const unsigned int x,
00141                       const unsigned int y,
00142                       const unsigned int z,
00143                       T& vox);
00144 
00145   //! inefficent access to get x,y,z if possible use iterator
00146   bool getVal(const Point<int,3>& coord,T& vox);
00147 
00148   //! Return the virtual voxels. Bool will be false if vox is empty.
00149   virtual bool get(BASE_IMAGE& ivox) const;
00150 
00151   //! store a voxel at x,y,z
00152   virtual void setVal(const unsigned int x,
00153                       const unsigned int y,
00154                       const unsigned int z,
00155                       const T& vox);
00156 
00157   //! store a voxel at x,y,z using a point
00158   void setVal(const Point<int,3>& coord,const T& vox);
00159 
00160   //! Sets the virtual voxel
00161   virtual void set(const BASE_IMAGE& ivox);
00162 
00163   //! Returns read-only (const) pointer to internal image array
00164   const T* getArrayPtr() const;
00165 
00166   //! Returns read/write (non-const) pointer to internal image array
00167   T* getArrayPtr();
00168 
00169   //! Test whether point falls inside array boundaries
00170   bool coordsOk(const unsigned int i,
00171                 const unsigned int j,
00172                 const unsigned int k) const;
00173 
00174   //! Test whether point falls inside array boundaries
00175   bool coordsOk(const Point<int,3>& coord) const;
00176 
00177   //! Check whether image is non-empty (i.e., non-zero height and width).
00178   virtual bool initialized() const;
00179 
00180 #ifndef INVT_MEM_DEBUG
00181   // standard iterators are just pointers to the data:
00182   //! Read/write iterator.
00183   typedef T* iterator;
00184   //! Read-only iterator.
00185   typedef const T* const_iterator;
00186 #else
00187   // range-checked iterators can detect attempts to access past image bounds:
00188   //! Read/write iterator.
00189   typedef CheckedIterator<T> iterator;
00190   //! Read-only iterator.
00191   typedef CheckedIterator<const T> const_iterator;
00192 #endif
00193 
00194   //! Returns the constant head iterator
00195   const_iterator begin() const;
00196 
00197   //! Returns the constant end iterator
00198   const_iterator end() const;
00199 
00200   //! Returns the head iterator
00201   iterator beginw();
00202 
00203   //! Returns the end iterator
00204   iterator endw();
00205 
00206   //! get the range of the voxels in real space
00207   //virtual void range(VoxRange& range) const;
00208 
00209   //! number of points we now have (same as getSize)
00210   virtual int size() const;
00211 
00212   //! Return an Image Slice, set the normal axis' to -1
00213   /*! This will return a single INVT image slice of the full voxel
00214       image. To use this, set the values in the Point object to -1
00215       for the axis that lay on the image plane.
00216 
00217       Example: I want to return an image at a depth of 12. That is, z=12
00218 
00219       In this case, the returned image will be of size X (width) by Y (height)
00220       make a Point like Point<int,3>(-1,-1,12) and pass it with the
00221       method call.
00222 
00223       The bool is for compatability with sparse voxel images
00224   */
00225   virtual bool getSlice(const Point<int,3>& coord, Image<T>& img) const;
00226 
00227   //! Return a vector column, set the normal axis to -1
00228   /*! This will return a column in a std::vector from the voxel. To use
00229       it, set the ortho axis to -1. So if you want to get a column at
00230       X = 12 and Y = 18 then set Z to -1 since its the orthogonal plane.
00231 
00232       Example: I want to get a column of voxels from offset X = 12 and Y = 18
00233 
00234       The returned vector will be the of size Z (depth). Creat a point like
00235       Point<int,3>(12,18,-1). Since the Z is -1, the method will know
00236       we want the column othogonal to the z plane.
00237   */
00238   virtual bool getColumn(const Point<int,3>& coord, std::vector<T>& vec) const;
00239 
00240   //! Return a single value (voxel)
00241   //virtual bool getVal(const Point<int,3>& coord, T& val);
00242 
00243   //! Set an Image Slice, set the normal axis' to -1
00244   /*! This will set a single voxel slice to the value of an INVT image
00245       To use this, set the values in the Point object to -1
00246       for the axis that lay on the image plane. The image must be the same
00247       size dimensions parallel to the image slice. So if setting a
00248       slice at Z=12, then the X (width) and Y (height) must be the same size
00249       as the voxel image.
00250 
00251       Example: I want to set a slice at a row of 22. That is, y=22
00252 
00253       In this case, the image must be of size X (width) by Z (depth)
00254       make a Point like Point<int,3>(-1,22,-1) and pass it with the
00255       method call.
00256   */
00257   virtual void setSlice(const Point<int,3>& coord, const Image<T>& img);
00258 
00259   //! Set a vector column, set the normal axis to -1
00260   /*! This will set a column with a std::vector of voxels. To use
00261       it, set the ortho axis to -1. So if you want to set a column at
00262       X = 12 and Y = 18 then set Z to -1 since its the orthogonal plane. The
00263       vector must be the same size as the axis requested. So if the image
00264       size Z (depth) is 256, then the vector needs to be that size in order
00265       to set along the z axis.
00266 
00267       Example: I want to set a column of voxels from offset X = 12 and Y = 18
00268 
00269       The the vector must be the of size Z (depth). Creat a point like
00270       Point<int,3>(12,18,-1). Since the Z is -1, the method will know
00271       we want the column othogonal to the z plane.
00272   */
00273   virtual void setColumn(const Point<int,3>& coord, const std::vector<T>& vec);
00274 
00275   //! Set a single value
00276   //virtual void setVal(const Point<int,3>& coord, const T& val);
00277 
00278   //! get our height - Y (itsSizeY)
00279   virtual unsigned int getHeight() const;
00280 
00281   //! get our width - X (itsSizeX)
00282   virtual unsigned int getWidth() const;
00283 
00284   //! get out depth - Z (itsSizeZ)
00285   virtual unsigned int getDepth() const;
00286 
00287   //! get total size (number of voxels)
00288   unsigned int getSize() const;
00289 
00290   //! Check if *this is the same size as the other thing
00291   template <class C>
00292   bool isSameSize(const C& other) const;
00293 
00294   //! Check if the image is 1D, i.e., width == 1 or height == 1
00295   bool is1D() const;
00296 
00297   //! Check if the image is square, i.e., width == height == depth
00298   /*! Ok, it's really a cube, but we keep the name from the Image class */
00299   bool isSquare() const;
00300 
00301   //! Access voxel image elements through C array index interface
00302   /*! To get an element at x,y,z use the following computation:
00303 
00304     x + y * width + z * width * height
00305 
00306     Example: get a voxel at position (x,y,z) = (13,23,56) in RealVoxel
00307     image ivox...
00308 
00309     T voxel = ivox[13 + 23 * ivox.getWidth() +
00310     56 * ivox.getWidth() * ivox.getHeight()];
00311   */
00312   T& operator[](const unsigned int index);
00313 
00314   //! Access voxel image elements through C array index interface
00315   /*! To get an element at x,y,z use the following computation:
00316 
00317     x + y * width + z * width * height
00318 
00319     Example: get a voxel at position (x,y,z) = (13,23,56) in RealVoxel
00320     image ivox...
00321 
00322     T voxel = ivox[13 + 23 * ivox.getWidth() +
00323     56 * ivox.getWidth() * ivox.getHeight()];
00324   */
00325   const T& operator[](const unsigned int index) const;
00326 
00327   //! Access voxel image elements through C array index interface
00328   T& operator[](const Point<int,3>& p);
00329 
00330   //! Access voxel image elements through C array index interface
00331   const T& operator[](const Point<int,3>& p) const;
00332 
00333   //! Equality Operator
00334   bool operator==(const RealVoxel<T>& ivox) const;
00335 
00336   //! copy operator
00337   virtual RealVoxel<T> & operator=(const RealVoxel<T>& ivox);
00338 
00339   //! RealVoxel + RealVoxel operator
00340   template <class T2>
00341   RealVoxel<typename promote_trait<T,T2>::TP>
00342   operator+(const RealVoxel<T2>& ivox) const;
00343 
00344   //! RealVoxel - RealVoxel operator
00345   template <class T2>
00346   RealVoxel<typename promote_trait<T,T2>::TP>
00347   operator-(const RealVoxel<T2>& ivox) const;
00348 
00349   //! RealVoxel * RealVoxel operator
00350   template <class T2>
00351   RealVoxel<typename promote_trait<T,T2>::TP>
00352   operator*(const RealVoxel<T2>& ivox) const;
00353 
00354   //! RealVoxel / RealVoxel operator
00355   template <class T2>
00356   RealVoxel<typename promote_trait<T,T2>::TP>
00357   operator/(const RealVoxel<T2>& ivox) const;
00358 
00359   //! RealVoxel operator which does the work
00360   template <class T2, class MATH_OP>
00361   RealVoxel<typename promote_trait<T,T2>::TP>
00362   basicOp(const RealVoxel<T2>& ivox) const;
00363 
00364   //! RealVoxel += RealVoxel operator
00365   template <class T2>
00366   RealVoxel<T> & operator+=(const RealVoxel<T2>& ivox);
00367 
00368   //! RealVoxel -= RealVoxel operator
00369   template <class T2>
00370   RealVoxel<T> & operator-=(const RealVoxel<T2>& ivox);
00371 
00372   //! RealVoxel *= RealVoxel operator
00373   template <class T2>
00374   RealVoxel<T> & operator*=(const RealVoxel<T2>& ivox);
00375 
00376   //! RealVoxel /= RealVoxel operator
00377   template <class T2>
00378   RealVoxel<T> & operator/=(const RealVoxel<T2>& ivox);
00379 
00380   //! copy operator
00381   virtual RealVoxel<T> & operator=(const T& val);
00382 
00383   //! RealVoxel + value operator
00384   template <class T2>
00385   RealVoxel<typename promote_trait<T,T2>::TP>
00386   operator+(const T2& val) const;
00387 
00388   //! RealVoxel - value operator
00389   template <class T2>
00390   RealVoxel<typename promote_trait<T,T2>::TP>
00391   operator-(const T2& val) const;
00392 
00393   //! RealVoxel * value operator
00394   template <class T2>
00395   RealVoxel<typename promote_trait<T,T2>::TP>
00396   operator*(const T2& val) const;
00397 
00398   //! RealVoxel / value operator
00399   template <class T2>
00400   RealVoxel<typename promote_trait<T,T2>::TP>
00401   operator/(const T2& val) const;
00402 
00403   //! RealVoxel value operator which does the work
00404   template <class T2, class MATH_OP>
00405   RealVoxel<typename promote_trait<T,T2>::TP>
00406   valueOp(const T2& val) const;
00407 
00408   //! RealVoxel += value operator
00409   template <class T2>
00410   RealVoxel<T> & operator+=(const T2& val);
00411 
00412   //! RealVoxel -= value operator
00413   template <class T2>
00414   RealVoxel<T> & operator-=(const T2& val);
00415 
00416   //! RealVoxel *= value operator
00417   template <class T2>
00418   RealVoxel<T> & operator*=(const T2& val);
00419 
00420   //! RealVoxel /= value operator
00421   template <class T2>
00422   RealVoxel<T> & operator/=(const T2& val);
00423 
00424   // ############################################################
00425 
00426   //! Add an image to this voxel image at each slice along an axis
00427   template <class T2>
00428   void addImage(const imgvox::axis axis, const Image<T2>& img);
00429 
00430   //! Subract an image from this voxel image at each slice along an axis
00431   /*! Here we have 2DImage - VoxelImage */
00432   template <class T2>
00433   void subtractImage(const imgvox::axis axis, const Image<T2>& img);
00434 
00435   //! Subract an image from this voxel image at each slice along an axis
00436   /*! Here we have VoxelImage - 2DImage */
00437   template <class T2>
00438   void subtractImageFrom(const imgvox::axis axis, const Image<T2>& img);
00439 
00440   //! Multiply an image by this voxel image at each slice along an axis
00441   template <class T2>
00442   void multiplyImage(const imgvox::axis axis, const Image<T2>& img);
00443 
00444   //! Divide an image by this voxel image at each slice along an axis
00445   /*! Here we have 2DImage / VoxelImage */
00446   template <class T2>
00447   void divideImage(const imgvox::axis axis, const Image<T2>& img);
00448 
00449   //! Divide an image by this voxel image at each slice along an axis
00450   /*! Here we have VoxelImage / 2DImage */
00451   template <class T2>
00452   void divideImageFrom(const imgvox::axis axis, const Image<T2>& img);
00453 
00454   // This method does the work for all the methods listed above
00455   template <class T2, class MATH_OP>
00456   void sliceOp(const imgvox::axis axis, const Image<T2>& img);
00457 
00458   // ############################################################
00459   /*! @name Functions for testing/debugging only */
00460   //@{
00461 
00462   //! For testing/debugging only.
00463   /*! See if we are pointing to the same ArrayData<T> as is the other
00464       Image<T>. */
00465   bool hasSameData(const RealVoxel<T>& b) const;
00466 
00467   //! For testing/debugging only.
00468   /*! Returns the current reference count. */
00469   long refCount() const throw();
00470 
00471   //! For testing/debugging only.
00472   /*! Check if the ArrayHandle is shared. */
00473   bool isShared() const throw();
00474 
00475   //@}
00476 protected:
00477 
00478   //! Returns a newish semi-copy (shallow copy) object for = overload
00479   virtual RealVoxel<T> getNew(const RealVoxel<T>& vvox);
00480 
00481   unsigned int itsSizeX;
00482   unsigned int itsSizeY;
00483   unsigned int itsSizeZ;
00484   unsigned int itsSize;
00485 
00486   //! Handel to the actual storage container for all the voxels
00487   BASE_IMAGE itsVox;
00488 
00489   const ArrayData<T>& impl() const;
00490   ArrayData<T>& uniq();
00491 
00492 
00493 };
00494 // ######################################################################
00495 // ######################################################################
00496 // ##### Special Helper Classes
00497 // ######################################################################
00498 // ######################################################################
00499 
00500 template <class T> class RealVoxelAdd
00501 {
00502 public:
00503   RealVoxelAdd();
00504   ~RealVoxelAdd();
00505   template <class T2>
00506   typename promote_trait<T,T2>::TP op(const T& a, const T2& b) const;
00507 };
00508 
00509 // ######################################################################
00510 template <class T> class RealVoxelSub
00511 {
00512 public:
00513   RealVoxelSub();
00514   ~RealVoxelSub();
00515   template <class T2>
00516   typename promote_trait<T,T2>::TP op(const T& a, const T2& b) const;
00517 };
00518 
00519 // ######################################################################
00520 template <class T> class RealVoxelSubInv
00521 {
00522 public:
00523   RealVoxelSubInv();
00524   ~RealVoxelSubInv();
00525   template <class T2>
00526   typename promote_trait<T,T2>::TP op(const T& a, const T2& b) const;
00527 };
00528 
00529 // ######################################################################
00530 template <class T> class RealVoxelMult
00531 {
00532 public:
00533   RealVoxelMult();
00534   ~RealVoxelMult();
00535   template <class T2>
00536   typename promote_trait<T,T2>::TP op(const T& a, const T2& b) const;
00537 };
00538 
00539 // ######################################################################
00540 template <class T> class RealVoxelDiv
00541 {
00542 public:
00543   RealVoxelDiv();
00544   ~RealVoxelDiv();
00545   template <class T2>
00546   typename promote_trait<T,T2>::TP op(const T& a, const T2& b) const;
00547 };
00548 
00549 // ######################################################################
00550 template <class T> class RealVoxelDivInv
00551 {
00552 public:
00553   RealVoxelDivInv();
00554   ~RealVoxelDivInv();
00555   template <class T2>
00556   typename promote_trait<T,T2>::TP op(const T& a, const T2& b) const;
00557 };
00558 
00559 // ######################################################################
00560 // ######################################################################
00561 // INLINE Methods
00562 // ######################################################################
00563 // ######################################################################
00564 template <class T> inline void
00565 RealVoxel<T>::freeMem()
00566 {
00567   RealVoxel<T> empty;
00568   this->swap(empty);
00569   itsSizeX = 0; itsSizeY = 0; itsSizeZ = 0; itsSize = 0;
00570 }
00571 
00572 // ######################################################################
00573 template <class T> inline void
00574 RealVoxel<T>::swap(RealVoxel<T>& other)
00575 {
00576   itsVox.swap(other.itsVox);
00577 
00578   // We swap the array memory , but we need to copy the
00579   // size values since we maintain them locally
00580 
00581   const unsigned int x = other.itsSizeX;
00582   other.itsSizeX = itsSizeX; itsSizeX = x;
00583 
00584   const unsigned int y = other.itsSizeY;
00585   other.itsSizeY = itsSizeY; itsSizeY = y;
00586 
00587   const unsigned int z = other.itsSizeZ;
00588   other.itsSizeZ = itsSizeZ; itsSizeZ = z;
00589 
00590   const unsigned int s = other.itsSize;
00591   other.itsSize  = itsSize; itsSize  = s;
00592 }
00593 
00594 // ######################################################################
00595 template <class T> inline void
00596 RealVoxel<T>::attach(T* array,
00597                      const unsigned int width,
00598                      const unsigned int height,
00599                      const unsigned int depth)
00600 {
00601   itsSizeX = width; itsSizeY = height; itsSizeZ = depth;
00602   itsSize = width * height * depth;
00603   ArrayHandle<T> attached(new ArrayData<T>(Dims(1, itsSize),
00604                                            array, WRITE_THRU));
00605   itsVox.swap(attached);
00606 }
00607 
00608 // ######################################################################
00609 template <class T> inline void
00610 RealVoxel<T>::detach()
00611 {
00612   ArrayHandle<T> emptyHdl;
00613   itsVox.swap(emptyHdl);
00614   itsSizeX = 0; itsSizeY = 0; itsSizeZ = 0; itsSize = 0;
00615 }
00616 
00617 // ######################################################################
00618 template <class T> inline RealVoxel<T>
00619 RealVoxel<T>::deepcopy() const
00620 {
00621   return RealVoxel<T>(this->getArrayPtr(), itsSizeX, itsSizeY, itsSizeZ);
00622 }
00623 
00624 // ######################################################################
00625 template <class T> inline void
00626 RealVoxel<T>::resize(const unsigned int size_x,
00627                      const unsigned int size_y,
00628                      const unsigned int size_z,
00629                      const bool do_clear)
00630 {
00631 
00632   if((size_x != itsSizeX) && (size_y != itsSizeY) && (size_z != itsSizeZ))
00633   {
00634     itsSize = size_x * size_y * size_z;
00635     ArrayHandle<T> resized(new ArrayData<T>(Dims(1,itsSize),
00636                                             do_clear ? ZEROS:NO_INIT));
00637     itsVox.swap(resized);
00638     itsSizeX = size_x;
00639     itsSizeY = size_y;
00640     itsSizeZ = size_z;
00641   }
00642   else // we're keeping the same size, so just clear() if necessary
00643   {
00644     if (do_clear) clear( T() );
00645   }
00646 }
00647 
00648 //######################################################################
00649 template <class T> inline void
00650 RealVoxel<T>::resize(const Point<int,3>& coord_size,
00651                      const bool do_clear)
00652 {
00653   resize(coord_size.P[0],coord_size.P[1],coord_size.P[2],do_clear);
00654 }
00655 
00656 // ######################################################################
00657 template <class T> inline
00658 void RealVoxel<T>::clear(const T& val)
00659 {
00660   // Check if we have a shared implementation... if yes, then for
00661   // efficiency we should release our copy before doing the iterative
00662   // loop, which would otherwise unnecessarily make a unique copy of
00663   // the shared data for us, which we would then ceremoniously ignore
00664   // as we clear it to a new value.
00665   if (itsVox.isShared())
00666     *this = RealVoxel<T>(itsSizeX, itsSizeY, itsSizeZ, NO_INIT);
00667 
00668   for (iterator itr = beginw(), stop = endw(); itr != stop; ++itr)
00669     *itr = val;
00670 }
00671 
00672 // ######################################################################
00673 template <class T> inline bool
00674 RealVoxel<T>::getVal(const Point<int,3>& coord,T& vox)
00675 {
00676   return getVal(coord.P[0],coord.P[1],coord.P[2],vox);
00677 }
00678 
00679 // ######################################################################
00680 template <class T> inline void
00681 RealVoxel<T>::setVal(const Point<int,3>& coord,const T& vox)
00682 {
00683   setVal(coord.P[0],coord.P[1],coord.P[2],vox);
00684 }
00685 
00686 // ######################################################################
00687 template <class T> inline
00688 const T* RealVoxel<T>::getArrayPtr() const
00689 {
00690   return impl().data();
00691 }
00692 
00693 // ######################################################################
00694 template <class T> inline
00695 T* RealVoxel<T>::getArrayPtr()
00696 {
00697   return uniq().dataw();
00698 }
00699 
00700 // ######################################################################
00701 template <class T> inline bool
00702 RealVoxel<T>::coordsOk(const unsigned int i,
00703                        const unsigned int j,
00704                        const unsigned int k) const
00705 {
00706   // Since this is an unsigned int, we do  not need to check for
00707   // coords less than zero
00708   return (i < getWidth() && j < getHeight() && k < getDepth());
00709 }
00710 
00711 // ######################################################################
00712 template <class T> inline bool
00713 RealVoxel<T>::coordsOk(const Point<int,3>& coord) const
00714 {
00715   // Since this is an unsigned int, we do  not need to check for
00716   // coords less than zero
00717   return (coord.P[0] < (int)itsSizeX &&
00718           coord.P[1] < (int)itsSizeY &&
00719           coord.P[2] < (int)itsSizeZ);
00720 }
00721 
00722 // ######################################################################
00723 // ##### Iterators:
00724 // ######################################################################
00725 
00726 #ifndef INVT_MEM_DEBUG
00727 
00728 template<class T> inline
00729 typename RealVoxel<T>::const_iterator RealVoxel<T>::begin() const
00730 { return impl().data(); }
00731 
00732 template<class T> inline
00733 typename RealVoxel<T>::const_iterator RealVoxel<T>::end() const
00734 { return impl().end(); }
00735 
00736 template<class T> inline
00737 typename RealVoxel<T>::iterator RealVoxel<T>::beginw()
00738 { return uniq().dataw(); }
00739 
00740 template<class T> inline
00741 typename RealVoxel<T>::iterator RealVoxel<T>::endw()
00742 { return uniq().endw(); }
00743 
00744 #else
00745 
00746 template <class T> inline
00747 typename RealVoxel<T>::const_iterator RealVoxel<T>::begin() const
00748 { return const_iterator(impl().data(), impl().data(), impl().end()); }
00749 
00750 template <class T> inline
00751 typename RealVoxel<T>::const_iterator RealVoxel<T>::end() const
00752 { return const_iterator(impl().end(), impl().data(), impl().end()); }
00753 
00754 template <class T> inline
00755 typename RealVoxel<T>::iterator RealVoxel<T>::beginw()
00756 { return iterator(uniq().dataw(), uniq().dataw(), uniq().endw()); }
00757 
00758 template <class T> inline
00759 typename RealVoxel<T>::iterator RealVoxel<T>::endw()
00760 { return iterator(uniq().endw(), uniq().dataw(), uniq().endw()); }
00761 
00762 #endif
00763 
00764 // ######################################################################
00765 template <class T> inline unsigned int
00766 RealVoxel<T>::getSize() const
00767 { return itsSize; }
00768 
00769 // ######################################################################
00770 template <class T> template <class C> inline
00771 bool RealVoxel<T>::isSameSize(const C& other) const
00772 {
00773   return itsSizeX == other.itsSizeX &&
00774          itsSizeY == other.itsSizeY &&
00775          itsSizeZ == other.itsSizeZ;
00776 }
00777 
00778 // ######################################################################
00779 template <class T> inline
00780 bool RealVoxel<T>::is1D() const
00781 { return (itsSizeX == 1) || (itsSizeY == 1) || (itsSizeZ == 1); }
00782 
00783 // ######################################################################
00784 template <class T> inline
00785 bool RealVoxel<T>::isSquare() const
00786 { return ((itsSizeX == itsSizeY) && (itsSizeX == itsSizeZ)); }
00787 
00788 // ######################################################################
00789 // ##### General Overloaded RealVoxel Operators
00790 // ######################################################################
00791 
00792 template <class T> inline
00793 T& RealVoxel<T>::operator[](unsigned int index)
00794 {
00795   ASSERT(index >= 0 && index < this->getSize());
00796   return beginw()[index];
00797 }
00798 
00799 // ######################################################################
00800 template <class T> inline
00801 const T& RealVoxel<T>::operator[](unsigned int index) const
00802 {
00803   ASSERT(index >= 0 && index < this->getSize());
00804   return begin()[index];
00805 }
00806 
00807 // ######################################################################
00808 template <class T> inline
00809 T& RealVoxel<T>::operator[](const Point<int,3>& p)
00810 {
00811   ASSERT(this->coordsOk(p));
00812   return this->beginw()[p.P[0] +
00813                         p.P[1] * this->getWidth() +
00814                         p.P[2] * this->getWidth() * this->getHeight()];
00815 }
00816 
00817 // ######################################################################
00818 template <class T> inline
00819 const T& RealVoxel<T>::operator[](const Point<int,3>& p) const
00820 {
00821   ASSERT(this->coordsOk(p));
00822   return this->begin()[p.P[0] +
00823                        p.P[1] * this->getWidth() +
00824                        p.P[2] * this->getWidth() * this->getHeight()];
00825 }
00826 
00827 // ######################################################################
00828 template <class T> inline bool
00829 RealVoxel<T>::operator==(const RealVoxel<T>& ivox) const
00830 {
00831   if (!this->isSameSize(ivox)) return false;
00832 
00833   return std::equal(this->begin(), this->end(), ivox.begin());
00834 }
00835 
00836 // ######################################################################
00837 template <class T> RealVoxel<T> &
00838 RealVoxel<T>::operator=(const RealVoxel<T>& ivox)
00839 {
00840   RealVoxel<T> v_copy( ivox );
00841   this->swap(v_copy);
00842   return *this;
00843 }
00844 
00845 // ######################################################################
00846 template <class T> template <class T2>
00847 inline RealVoxel<typename promote_trait<T,T2>::TP>
00848 RealVoxel<T>::operator+(const RealVoxel<T2>& ivox) const
00849 { return basicOp<RealVoxelAdd>(ivox); }
00850 
00851 // ######################################################################
00852 template <class T> template <class T2>
00853 inline RealVoxel<typename promote_trait<T,T2>::TP>
00854 RealVoxel<T>::operator-(const RealVoxel<T2>& ivox) const
00855 { return basicOp<RealVoxelSub>(ivox); }
00856 
00857 // ######################################################################
00858 template <class T> template <class T2>
00859 inline RealVoxel<typename promote_trait<T,T2>::TP>
00860 RealVoxel<T>::operator*(const RealVoxel<T2>& ivox) const
00861 { return basicOp<RealVoxelMult>(ivox); }
00862 
00863 // ######################################################################
00864 template <class T> template <class T2>
00865 inline RealVoxel<typename promote_trait<T,T2>::TP>
00866 RealVoxel<T>::operator/(const RealVoxel<T2>& ivox) const
00867 { return basicOp<RealVoxelDiv>(ivox); }
00868 
00869 // ######################################################################
00870 // Operate on the VoxelImage using an Image Slice
00871 template <class T> template <class T2, class MATH_OP>
00872 inline RealVoxel<typename promote_trait<T,T2>::TP>
00873 RealVoxel<T>::basicOp(const RealVoxel<T2>& ivox) const
00874 {
00875   MATH_OP math_op;
00876   ASSERT(isSameSize(ivox));
00877   typedef typename promote_trait<T,T2>::TP TPRO;
00878   RealVoxel<TPRO> result(itsSizeX,itsSizeY,itsSizeZ,NO_INIT);
00879   typename RealVoxel<TPRO>::iterator ritr     = result.beginw();
00880   typename RealVoxel<T2>::const_iterator vitr = ivox.begin();
00881   for(typename RealVoxel<T>::const_iterator itr = begin(), stop = end();
00882       itr != stop; ++itr, ++vitr, ++ritr)
00883     *ritr = math_op.op((*itr),(*vitr));
00884   return result;
00885 }
00886 
00887 // ######################################################################
00888 template <class T> template <class T2>
00889 inline RealVoxel<T> &
00890 RealVoxel<T>::operator+=(const RealVoxel<T2>& ivox)
00891 {
00892   ASSERT(isSameSize(ivox));
00893   typename RealVoxel<T2>::const_iterator vitr = ivox.begin();
00894   for (typename RealVoxel<T>::iterator itr = beginw(), stop = endw();
00895        itr != stop; ++itr, ++vitr)
00896     *itr = clamped_convert<T>((*itr) + (*vitr));
00897   return *this;
00898 }
00899 
00900 // ######################################################################
00901 template <class T> template <class T2>
00902 inline RealVoxel<T> &
00903 RealVoxel<T>::operator-=(const RealVoxel<T2>& ivox)
00904 {
00905   ASSERT(isSameSize(ivox));
00906   typename RealVoxel<T2>::const_iterator vitr = ivox.begin();
00907   for (typename RealVoxel<T>::iterator itr = beginw(), stop = endw();
00908        itr != stop; ++itr, ++vitr)
00909     *itr = clamped_convert<T>((*itr) + (*vitr));
00910   return *this;
00911 }
00912 
00913 // ######################################################################
00914 template <class T> template <class T2>
00915 inline RealVoxel<T> &
00916 RealVoxel<T>::operator*=(const RealVoxel<T2>& ivox)
00917 {
00918   ASSERT(isSameSize(ivox));
00919   typename RealVoxel<T2>::const_iterator vitr = ivox.begin();
00920   for (typename RealVoxel<T>::iterator itr = beginw(), stop = endw();
00921        itr != stop; ++itr, ++vitr)
00922     *itr = clamped_convert<T>((*itr) + (*vitr));
00923   return *this;
00924 }
00925 
00926 // ######################################################################
00927 template <class T> template <class T2>
00928 inline RealVoxel<T> &
00929 RealVoxel<T>::operator/=(const RealVoxel<T2>& ivox)
00930 {
00931   ASSERT(isSameSize(ivox));
00932   typename RealVoxel<T2>::const_iterator vitr = ivox.begin();
00933   for (typename RealVoxel<T>::iterator itr = beginw(), stop = endw();
00934        itr != stop; ++itr, ++vitr)
00935     *itr = clamped_convert<T>((*itr) + (*vitr));
00936   return *this;
00937 }
00938 
00939 // ######################################################################
00940 template <class T> inline RealVoxel<T> &
00941 RealVoxel<T>::operator=(const T& val)
00942 {
00943   for (typename RealVoxel<T>::iterator itr = beginw(), stop = endw();
00944        itr != stop; ++itr)
00945     *itr = val;
00946   return *this;
00947 }
00948 
00949 // ######################################################################
00950 template <class T> template <class T2>
00951 inline RealVoxel<typename promote_trait<T,T2>::TP>
00952 RealVoxel<T>::operator+(const T2& val) const
00953 { return valueOp<RealVoxelAdd>(val); }
00954 
00955 // ######################################################################
00956 template <class T> template <class T2>
00957 inline RealVoxel<typename promote_trait<T,T2>::TP>
00958 RealVoxel<T>::operator-(const T2& val) const
00959 { return valueOp<RealVoxelSub>(val); }
00960 
00961 // ######################################################################
00962 template <class T> template <class T2>
00963 inline RealVoxel<typename promote_trait<T,T2>::TP>
00964 RealVoxel<T>::operator*(const T2& val) const
00965 { return valueOp<RealVoxelMult>(val); }
00966 
00967 // ######################################################################
00968 template <class T> template <class T2>
00969 inline RealVoxel<typename promote_trait<T,T2>::TP>
00970 RealVoxel<T>::operator/(const T2& val) const
00971 { return valueOp<RealVoxelDiv>(val); }
00972 
00973 // ######################################################################
00974 template <class T> template <class T2, class MATH_OP>
00975 inline RealVoxel<typename promote_trait<T,T2>::TP>
00976 RealVoxel<T>::valueOp(const T2& val) const
00977 {
00978   MATH_OP math_op;
00979   typedef typename promote_trait<T,T2>::TP TPRO;
00980   RealVoxel<TPRO> result(itsSizeX,itsSizeY,itsSizeZ,NO_INIT);
00981   typename RealVoxel<TPRO>::iterator ritr = result.beginw();
00982   for(typename RealVoxel<T>::const_iterator itr = begin(), stop = end();
00983       itr != stop; ++itr, ++ritr)
00984     *ritr = math_op.op((*itr),val);
00985   return result;
00986 }
00987 
00988 // ######################################################################
00989 template <class T> template <class T2>
00990 inline RealVoxel<T> &
00991 RealVoxel<T>::operator+=(const T2& val)
00992 {
00993   for (typename RealVoxel<T>::iterator itr = beginw(), stop = endw();
00994        itr != stop; ++itr)
00995     *itr = clamped_convert<T>((*itr) + val);
00996   return *this;
00997 }
00998 
00999 // ######################################################################
01000 template <class T> template <class T2>
01001 inline RealVoxel<T> &
01002 RealVoxel<T>::operator-=(const T2& val)
01003 {
01004   for (typename RealVoxel<T>::iterator itr = beginw(), stop = endw();
01005        itr != stop; ++itr)
01006     *itr = clamped_convert<T>((*itr) - val);
01007   return *this;
01008 }
01009 
01010 // ######################################################################
01011 template <class T> template <class T2>
01012 inline RealVoxel<T> &
01013 RealVoxel<T>::operator*=(const T2& val)
01014 {
01015   for (typename RealVoxel<T>::iterator itr = beginw(), stop = endw();
01016        itr != stop; ++itr)
01017     *itr = clamped_convert<T>((*itr) * val);
01018   return *this;
01019 }
01020 
01021 // ######################################################################
01022 template <class T> template <class T2>
01023 inline RealVoxel<T> &
01024 RealVoxel<T>::operator/=(const T2& val)
01025 {
01026   for (typename RealVoxel<T>::iterator itr = beginw(), stop = endw();
01027        itr != stop; ++itr)
01028     *itr = clamped_convert<T>((*itr) / val);
01029   return *this;
01030 }
01031 
01032 // ######################################################################
01033 // ##### Image Slice Overloaded RealVoxel Operators
01034 // ######################################################################
01035 
01036 template <class T> template <class T2>
01037 inline void
01038 RealVoxel<T>::addImage(const imgvox::axis axis, const Image<T2>& img)
01039 { sliceOp<RealVoxelAdd>(axis,img); }
01040 
01041 // ######################################################################
01042 template <class T> template <class T2>
01043 inline void
01044 RealVoxel<T>::subtractImage(const imgvox::axis axis, const Image<T2>& img)
01045 { sliceOp<RealVoxelSub>(axis,img); }
01046 
01047 // ######################################################################
01048 template <class T> template <class T2>
01049 inline void
01050 RealVoxel<T>::subtractImageFrom(const imgvox::axis axis, const Image<T2>& img)
01051 { sliceOp<RealVoxelSubInv>(axis,img); }
01052 
01053 // ######################################################################
01054 template <class T> template <class T2>
01055 inline void
01056 RealVoxel<T>::multiplyImage(const imgvox::axis axis, const Image<T2>& img)
01057 { sliceOp<RealVoxelMult>(axis,img); }
01058 
01059 // ######################################################################
01060 template <class T> template <class T2>
01061 inline void
01062 RealVoxel<T>::divideImage(const imgvox::axis axis, const Image<T2>& img)
01063 { sliceOp<RealVoxelDiv>(axis,img); }
01064 
01065 // ######################################################################
01066 template <class T> template <class T2>
01067 inline void
01068 RealVoxel<T>::divideImageFrom(const imgvox::axis axis, const Image<T2>& img)
01069 { sliceOp<RealVoxelDivInv>(axis,img); }
01070 
01071 // ######################################################################
01072 // Operate on the VoxelImage using an Image Slice
01073 template <class T> template <class T2, class MATH_OP>
01074 inline void
01075 RealVoxel<T>::sliceOp(const imgvox::axis axis, const Image<T2>& img)
01076 {
01077   /* This method works very similar to getSlice and setSlice
01078   */
01079 
01080   // pre compute the image X by Y slice size for Z offset computation
01081 
01082   // This is the operator like a + b or a * b
01083   // it is used as a template so that all this stuff only has to be
01084   // put in once and we just define new ops for each math function
01085   MATH_OP math_op;
01086 
01087   const unsigned int XY = itsSizeX * itsSizeY;
01088   if(axis == imgvox::X_AXIS) // op slice by x-axis
01089   {
01090     ASSERT(img.getWidth()  == (int)itsSizeZ);
01091     ASSERT(img.getHeight() == (int)itsSizeY);
01092 
01093     for(unsigned int i = 0; i < itsSizeX; i++)
01094     {
01095       typename Image<T2>::const_iterator itr = img.begin();
01096       // There is no natural alignement. The data offset
01097       // into the array needs to be computed new each time
01098       for(unsigned int k = 0; k < itsSizeZ; k++)
01099       {
01100         const unsigned int xZ = i + k * XY;
01101         for(unsigned int j = 0; j < itsSizeY; j++)
01102         {
01103           const unsigned int pos = j * itsSizeX + xZ;
01104           beginw()[pos] = math_op.op(begin()[pos], *itr++);
01105         }
01106       }
01107     }
01108   }
01109   else if(axis == imgvox::Y_AXIS) // op slice by y-axis
01110   {
01111     ASSERT(img.getWidth()  == (int)itsSizeX);
01112     ASSERT(img.getHeight() == (int)itsSizeZ);
01113 
01114     for(unsigned int j = 0; j < itsSizeY; j++)
01115     {
01116       typename Image<T2>::const_iterator itr = img.begin();
01117 
01118       const unsigned int Y = j * itsSizeX;
01119       // We will need to compute the z coordinate in jumps
01120       for(unsigned int k = 0; k < itsSizeZ; k++)
01121       {
01122         const unsigned int yZ = Y + k * XY;
01123         const T *a            = &begin()[yZ];
01124         T *b                  = &beginw()[yZ];
01125         // The x axis alignment is natural and we can just
01126         // do a standard iterator copy
01127         for(unsigned int i = 0; i < itsSizeX; i++)
01128         {
01129           *b++ = math_op.op(*itr++,*a++);
01130         }
01131       }
01132     }
01133   }
01134   else if(axis == imgvox::Z_AXIS) // op slice by z-axis
01135   {
01136     ASSERT(img.getWidth()  == (int)itsSizeX);
01137     ASSERT(img.getHeight() == (int)itsSizeY);
01138 
01139     for(unsigned int k = 0; k < itsSizeZ; k++)
01140     {
01141       typename Image<T2>::const_iterator itr = img.begin();
01142 
01143       const unsigned int Z = k * XY;
01144       const T *a           = &begin()[Z];
01145       T *b                 = &beginw()[Z];
01146       // Each point is naturally aligned so we can do an easy copy
01147       // once we have computed the z alignment offset
01148       for(unsigned int p = 0; p < XY; p++)
01149       {
01150         *b++ = math_op.op(*itr++,*a++);
01151       }
01152     }
01153   }
01154   else
01155     LFATAL("Cannot get a slice without specifying axis for slice using -1");
01156 }
01157 
01158 // ######################################################################
01159 // ##### Functions for testing/debugging only:
01160 // ######################################################################
01161 
01162 template <class T> inline
01163 bool RealVoxel<T>::hasSameData(const RealVoxel<T>& b) const
01164 { return itsVox.hasSameData(b.itsVox); }
01165 
01166 // ######################################################################
01167 template <class T> inline
01168 long RealVoxel<T>::refCount() const throw() { return itsVox.refCount(); }
01169 
01170 // ######################################################################
01171 template <class T> inline
01172 bool RealVoxel<T>::isShared() const throw() { return itsVox.isShared(); }
01173 
01174 // ######################################################################
01175 // ##### Protected methods:
01176 // ######################################################################
01177 
01178 template <class T> inline
01179 const ArrayData<T>& RealVoxel<T>::impl() const
01180 { return itsVox.get(); }
01181 
01182 // ######################################################################
01183 template <class T> inline
01184 ArrayData<T>& RealVoxel<T>::uniq()
01185 { return itsVox.uniq(); }
01186 
01187 // ######################################################################
01188 // ######################################################################
01189 // ##### Special Helper Classes
01190 // ######################################################################
01191 // ######################################################################
01192 template <class T> inline RealVoxelAdd<T>::RealVoxelAdd() {}
01193 template <class T> inline RealVoxelAdd<T>::~RealVoxelAdd() {}
01194 
01195 template <class T> template <class T2>
01196 inline typename promote_trait<T,T2>::TP
01197 RealVoxelAdd<T>::op(const T& a, const T2& b) const
01198 { return a + b; }
01199 
01200 // ######################################################################
01201 
01202 template <class T> inline RealVoxelSub<T>::RealVoxelSub() {}
01203 template <class T> inline RealVoxelSub<T>::~RealVoxelSub() {}
01204 
01205 template <class T> template <class T2>
01206 inline typename promote_trait<T,T2>::TP
01207 RealVoxelSub<T>::op(const T& a, const T2& b) const
01208 { return a - b; }
01209 
01210 // ######################################################################
01211 
01212 template <class T> inline RealVoxelSubInv<T>::RealVoxelSubInv() {}
01213 template <class T> inline RealVoxelSubInv<T>::~RealVoxelSubInv() {}
01214 
01215 template <class T> template <class T2>
01216 inline typename promote_trait<T,T2>::TP
01217 RealVoxelSubInv<T>::op(const T& a, const T2& b) const
01218 { return b - a; }
01219 
01220 // ######################################################################
01221 
01222 template <class T> inline RealVoxelMult<T>::RealVoxelMult() {}
01223 template <class T> inline RealVoxelMult<T>::~RealVoxelMult() {}
01224 
01225 template <class T> template <class T2>
01226 inline typename promote_trait<T,T2>::TP
01227 RealVoxelMult<T>::op(const T& a, const T2& b) const
01228 { return a * b; }
01229 
01230 // ######################################################################
01231 
01232 template <class T> inline RealVoxelDiv<T>::RealVoxelDiv() {}
01233 template <class T> inline RealVoxelDiv<T>::~RealVoxelDiv() {}
01234 
01235 template <class T> template <class T2>
01236 inline typename promote_trait<T,T2>::TP
01237 RealVoxelDiv<T>::op(const T& a, const T2& b) const
01238 { return a / b; }
01239 
01240 // ######################################################################
01241 
01242 template <class T> inline RealVoxelDivInv<T>::RealVoxelDivInv() {}
01243 template <class T> inline RealVoxelDivInv<T>::~RealVoxelDivInv() {}
01244 
01245 template <class T> template <class T2>
01246 inline typename promote_trait<T,T2>::TP
01247 RealVoxelDivInv<T>::op(const T& a, const T2& b) const
01248 { return b / a; }
01249 
01250 #endif

Generated on Mon Nov 23 15:46:44 2009 for iLab Neuromorphic Vision Toolkit by  doxygen 1.4.4