Image.hpp

00001 // This file is part of the imaging2 class library.
00002 //
00003 // University of Innsbruck, Infmath Imaging, 2009.
00004 // http://infmath.uibk.ac.at
00005 //
00006 // All rights reserved.
00007 
00008 
00009 #ifndef IMAGE_IMAGE_H
00010 #define IMAGE_IMAGE_H
00011 
00012 #include <image/ImageInterface.hpp>
00013 #include <boost/multi_array.hpp>
00014 
00015 
00016 namespace imaging
00017 {
00019   template <size_t N, class DATA_t> class Image;
00020   
00021   namespace image_impl
00022   {
00023     template <size_t N>
00024     class image_access
00025     {
00026     public:
00027       template <class DATA_t>
00028       static const DATA_t & access(const Image<N, DATA_t> & image, const ublas::fixed_vector<size_t, N> & index);
00029       
00030       template <class DATA_t>
00031       static DATA_t & access(Image<N, DATA_t> & image, const ublas::fixed_vector<size_t, N> & index);
00032     };
00033     
00034     template <>
00035     class image_access<2>
00036     {
00037     public:
00038       template <class DATA_t>
00039       static const DATA_t & access(const Image<2, DATA_t> & image, const ublas::fixed_vector<size_t, 2> & index);
00040       
00041       template <class DATA_t>
00042       static DATA_t & access(Image<2, DATA_t> & image, const ublas::fixed_vector<size_t, 2> & index);
00043     };
00044   }
00047   template <size_t N>
00048   bool increment_index(const ublas::fixed_vector<size_t, N> & dimensions, size_t fixed_component, ublas::fixed_vector<size_t, N> & index)
00049   {
00050     for(size_t i = 0; i < N; ++i)
00051     {
00052       if(i == fixed_component)
00053         continue;
00054 
00055       if(++index(i) == dimensions(i))
00056         if(i == N)
00057           return false;
00058         else
00059           index(i) = 0;
00060       else
00061         return true;
00062     }
00063 
00064     return false;
00065   }
00066 
00067   template <size_t N>
00068   bool increment_index(const ublas::fixed_vector<size_t, N> & dimensions, ublas::fixed_vector<size_t, N> & index)
00069   {
00070     for(size_t i = 0; i < N; ++i)
00071     {
00072       if(++index(i) == dimensions(i))
00073         if(i == N)
00074           return false;
00075         else
00076           index(i) = 0;
00077       else
00078         return true;
00079     }
00080 
00081     return false;
00082   }
00083 
00089   template <std::size_t N, class DATA_t>
00090   class Image : public ImageInterface<N, DATA_t>, public boost::multi_array<DATA_t, N>
00091   {
00092   public:
00093     static const std::size_t dimension = N;
00094     typedef DATA_t data_t;
00095 
00096   private:
00097     ublas::fixed_vector<size_t, dimension> _size;
00098 
00099   public:
00101     Image() : boost::multi_array<DATA_t, dimension>(), _size(ublas::scalar_vector<size_t>(N, 0)) {  }
00102 
00104     explicit Image(const ublas::fixed_vector<size_t, dimension> & size) : boost::multi_array<DATA_t, dimension>(size), _size(size)
00105     { }
00106     
00108     explicit Image(const std::string & file_name)
00109     { 
00110       read_image(file_name);
00111     }
00112     
00114     explicit Image(const char * file_name)
00115     { 
00116       read_image(file_name);
00117     }
00118     
00120     template <class source_accessor_t>
00121     explicit Image(const source_accessor_t & image_accessor) : boost::multi_array<DATA_t, dimension>(image_accessor.size()), _size(image_accessor.size())
00122     { 
00123       copy_image(image_accessor, *this);
00124     }
00125     
00127     Image<N, DATA_t> & operator=(const Image<N, DATA_t> & source)
00128     { 
00129       resize(source.size());
00130       boost::multi_array<DATA_t, dimension>::operator=((const boost::multi_array<DATA_t, dimension> &)(source));
00131       
00132       return *this;
00133     }
00134     
00136     template <class source_accessor_t>
00137     const Image<N, DATA_t> & operator=(const source_accessor_t & image_accessor)
00138     { 
00139       resize(image_accessor.size());
00140       copy_image(image_accessor, *this);
00141       
00142       return *this;
00143     }
00144 
00145     const DATA_t & operator[](const ublas::fixed_vector<size_t, dimension> & index) const { return image_impl::image_access<N>::access(*this, index); }
00146     
00147     DATA_t & operator[](const ublas::fixed_vector<size_t, dimension> & index) { return image_impl::image_access<N>::access(*this, index); }
00148 
00149     const ublas::fixed_vector<size_t, dimension> & size() const { return _size; }
00150     
00152     void resize(const ublas::fixed_vector<size_t, dimension> & size)
00153     {
00154       boost::multi_array<DATA_t, dimension>::resize(size);
00155       _size = size;
00156     }
00157     
00159     bool empty() const
00160     {
00161       for(size_t i = 0; i < N; ++i)
00162         if (size()(i) == 0)
00163           return true;
00164       
00165       return false;
00166     }
00167     
00169     void read_image(const std::string & file_name) { }
00170 
00172     void write_image(const std::string & file_name) const { }
00173   };
00174 
00175   template <class source_accessor_t, class target_accessor_t>
00176   void copy_image(const source_accessor_t & source, target_accessor_t & target)
00177   {
00178     if(source.size() != target.size())
00179       throw Exception("Exception: Dimensions in copy_image() do not agree.");
00180 
00181     const std::size_t dimension = source_accessor_t::dimension;
00182     std::size_t n_pixels = 1;
00183 
00184     for(std::size_t i = 0; i < dimension; ++i)
00185       n_pixels *= source.size()(i);
00186 
00187     if(n_pixels == 0) return;
00188 
00189     ublas::fixed_vector<size_t, dimension> index;
00190     index.assign(0);
00191 
00192     do
00193     {
00194       target[index] = (typename target_accessor_t::data_t)(source[index]);
00195     }
00196     while(increment_index(source.size(), index));
00197   }
00198   
00199   namespace image_impl
00200   {
00201     template <size_t N>
00202     template <class DATA_t>
00203     const DATA_t & image_access<N>::access(const Image<N, DATA_t> & image, const ublas::fixed_vector<size_t, N> & index)
00204     {
00205       return image(index);
00206     }
00207     
00208     template <size_t N>
00209     template <class DATA_t>
00210     DATA_t & image_access<N>::access(Image<N, DATA_t> & image, const ublas::fixed_vector<size_t, N> & index)
00211     {
00212       return image(index);
00213     }
00214     
00215     template <class DATA_t>
00216     const DATA_t & image_access<2>::access(const Image<2, DATA_t> & image, const ublas::fixed_vector<size_t, 2> & index)
00217     {
00218       return ((const boost::multi_array<DATA_t, 2> &)(image))[index(0)][index(1)];
00219     }
00220     
00221     template <class DATA_t>
00222     DATA_t & image_access<2>::access(Image<2, DATA_t> & image, const ublas::fixed_vector<size_t, 2> & index)
00223     {
00224       return ((boost::multi_array<DATA_t, 2> &)(image))[index(0)][index(1)];
00225     }
00226   }
00227 }
00228 
00229 #endif

Generated on Tue Feb 10 10:01:30 2009 for imaging2 by  doxygen 1.5.5