00001
00002
00003
00004
00005
00006
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