ivl 679
ivl/details/image/impl/specialization/image_class.hpp
00001 /* This file is part of the ivl C++ library <http://image.ntua.gr/ivl>.
00002    A C++ template library extending syntax towards mathematical notation.
00003 
00004    Copyright (C) 2012 Yannis Avrithis <iavr@image.ntua.gr>
00005    Copyright (C) 2012 Kimon Kontosis <kimonas@image.ntua.gr>
00006 
00007    ivl is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU Lesser General Public License 
00009    version 3 as published by the Free Software Foundation.
00010 
00011    Alternatively, you can redistribute it and/or modify it under the terms 
00012    of the GNU General Public License version 2 as published by the Free 
00013    Software Foundation.
00014 
00015    ivl is distributed in the hope that it will be useful,
00016    but WITHOUT ANY WARRANTY; without even the implied warranty of
00017    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
00018    See the GNU General Public License for more details.
00019 
00020    You should have received a copy of the GNU General Public License 
00021    and a copy of the GNU Lesser General Public License along 
00022    with ivl. If not, see <http://www.gnu.org/licenses/>. */
00023 
00024 
00025 //--------------------------------------------------------------
00026 // CLASS image
00027 
00028 namespace data {
00029 
00030 template <class HAS_RANDOM_ACCESS, class IS_2D>
00031 struct get_pixel { };
00032 
00033 template <>
00034 struct get_pixel<types::t_true, types::t_false>
00035 {
00036         template<class A>
00037         static inline
00038         typename A::pixel from(A& a, size_t row, size_t col)
00039         {
00040                 return typename A::pixel(
00041                         a._iter(2, a.begin() + (col * a.rows() + row)), a.channels());
00042         }
00043         template<class A>
00044         static inline
00045         typename A::const_pixel from(const A& a, size_t row, size_t col)
00046         {
00047                 return typename A::const_pixel(
00048                         a._iter(2, a.begin() + (col * a.rows() + row)), a.channels());
00049         }
00050 };
00051 
00052 template <>
00053 struct get_pixel<types::t_false, types::t_false>
00054 {
00055         template<class A>
00056         static inline
00057         typename A::pixel from(A& a, size_t row, size_t col)
00058         {
00059                 return typename A::pixel(
00060                         a._iter(2,
00061                                 array<size_t, data::fixed<2> >(row, col)), a.channels());
00062         }
00063         template<class A>
00064         static inline
00065         typename A::const_pixel from(const A& a, size_t row, size_t col)
00066         {
00067                 return typename A::const_pixel(
00068                         a._iter(2,
00069                                 array<size_t, data::fixed<2> >(row, col)), a.channels());
00070         }
00071         /*
00072         typename A::pixel from(A& a, size_t row, size_t col)
00073         {
00074                 return typename A::pixel(a._iter(2, a._begin(0) + row, col));
00075         }
00076         template<class A>
00077         static inline
00078         typename A::const_pixel from(const A& a, size_t row, size_t col)
00079         {
00080                 return typename A::const_pixel(a._iter(2, a._begin(0) + row, col));
00081         }
00082         */
00083 };
00084 
00085 template <class ANY>
00086 struct get_pixel<ANY, types::t_true>
00087 {
00088         template<class A>
00089         static inline
00090         typename A::pixel from(A& a, size_t row, size_t col)
00091         {
00092                 return a(row, col);
00093         }
00094         template<class A>
00095         static inline
00096         typename A::const_pixel from(const A& a, size_t row, size_t col)
00097         {
00098                 return a(row, col);
00099         }
00100 };
00101 
00102 
00103 } /* namespace data */
00104 
00110 template <class T,
00111                  class OPTS = data::normal_image<0>
00112              >
00113 class image :
00114         public
00115                 array_common_base<image<T, OPTS> >
00116 {
00117 private:
00118         typedef array_common_base<image<T, OPTS> > common_base_class;
00119 
00120         using common_base_class::Ch;
00121         enum { N = common_base_class::im_channels::value };
00122 
00123         typedef typename image_details::cv<true, T>::iplimage_t iplimage_t;
00124 
00125         void copy_from(const iplimage_t* src)
00126         {
00127                 image_details::cv<true, T>::copy_from(*this, src);
00128         }
00129 
00130         void copy_to(iplimage_t* ipl) const
00131         {
00132                 image_details::cv<true, T>::copy_to(*this, ipl);
00133         }
00134 
00135 public:
00136         typedef image this_type;
00137 
00138         typedef typename this_type::derived_type derived_type;
00139 
00140         typedef typename common_base_class::base_class base_class;
00141 
00142         typedef this_type this_image_type;
00143 
00144         typedef this_type array_type;
00145 
00146         typedef typename this_type::size_type size_type;
00147 
00148         using base_class::derived;
00149 
00150         typedef typename this_type::all_init_arg_base all_init_arg;
00151         typedef typename this_type::data_init_arg_base data_init_arg;
00152 
00153 
00154 // image types
00155         typedef typename types::best_iterator<base_class>::type best_iterator;
00156         typedef typename base_class::const_iterator const_iterator;
00157 
00158         typedef typename types::best_iterator_nd<base_class>::type best_iterator_nd;
00159         typedef typename base_class::const_iterator_nd const_iterator_nd;
00160 
00162         typedef typename types::t_if<types::t_expr<N != 1>,
00163                 array<T,
00164                         data::ref_iterator<const_iterator_nd, types::term, N> >,
00165                 typename const_iterator::reference>::type
00166                         const_pixel;
00167 
00168         typedef typename types::t_if<types::t_expr<N != 1>,
00169                 array<T,
00170                         data::ref_iterator<best_iterator_nd, const_iterator_nd, N> >,
00171                 typename best_iterator::reference>::type pixel;
00172 
00174         typedef ivl::color<T, OPTS::Ch> color_type;
00175 
00178 
00179         image() : common_base_class(size_dims<3>(0, 0, (!N ? 1 : N))) { };
00180 
00182         image(size_t rows, size_t cols, size_t channels = (!N ? 3 : N)) :
00183                 common_base_class(size_dims<3>(rows, cols, channels))
00184                 { CHECK(!N || channels == N, edims); };
00185 
00187         image(size_t rows, size_t cols, size_t channels, const T& value) :
00188                 common_base_class(size_dims<3>(rows, cols, channels), value)
00189                 { CHECK(!N || channels == N, edims); }
00190 
00192         /*image(size_t rows, size_t cols, size_t channels, const T* ptr) :
00193                 common_base_class(size_dims<3>(rows, cols, channels), ptr)
00194                 { CHECK(!N || channels == N, edims); }*/
00195 
00197         template <class J, class D>
00198         image(size_t rows, size_t cols, size_t channels, const array<J, D>& a) :
00199                 common_base_class(size_dims<3>(rows, cols, channels), a)
00200                 { CHECK(!N || channels == N, edims); }
00201 
00203         template <class S>
00204         image(const array<size_t, S>& sz) :
00205                 common_base_class(sz) {} ;
00206 
00208         template <class S>
00209         image(const array<size_t, S>& sz, const T& value) :
00210                 common_base_class(sz, value) {} ;
00211 
00213         template <class S>
00214         image(const array<size_t, S>& sz, const T* ptr) :
00215                 common_base_class(sz, ptr) {} ;
00216 
00218         template <class S>
00219         image(const array<size_t, S>& sz, const data_init_arg& data) :
00220                 common_base_class(sz, data) {} ;
00221 
00222 
00224         template <class S, class J, class D>
00225         image(const array<size_t, S>& sz, const array<J, D>& a) :
00226                 common_base_class(sz, a) {} ;
00227 
00229         image(const std::string& filename, image_channels channels = ic_auto);
00230 
00232         image(const iplimage_t* ipl);
00233 
00235         template <class J, class S>
00236         image(const array_nd<J, S>& a) : common_base_class(a) {}
00237 
00239         template <class J, class S>
00240         image(array_nd<J, S>& a) : common_base_class(a) {}
00241 
00243         image(const this_type& a) : common_base_class(a) {}
00244 
00247         // Destructor
00248         ~image() {}
00249 
00250 
00253         //using common_base_class::operator=;
00254         template<class K>
00255         derived_type& operator=(const K& k)
00256         { common_base_class::operator=(k); return derived(); }
00257 
00258         this_type& operator=(const this_type& a) // copy operator
00259         { common_base_class::operator=(a); return *this; }
00260 
00262         derived_type& operator=(const iplimage_t* src)
00263         { copy_from(src); return this->derived(); }
00265         // sorry, but that's the effect of free template argument
00266         derived_type& operator=(iplimage_t* src)
00267                 { return ((*this) = static_cast<const iplimage_t*>(src)); }
00268 /*
00270         derived_type& operator=(const T& s)
00271                 { return base_class::operator=(s); };
00272 
00274         template<class S, class K>
00275         derived_type& operator=(const array_nd<T, S, K>& a)  { return base_class::operator=(a); }
00276 
00278         template<int M, class S, class K>
00279         derived_type& operator=(const image<T, M, S, K>& a) { return base_class::operator=(a); }
00280 
00282         this_type& operator=(const this_type& a) { return base_class::operator=(a); }
00283 */
00284 
00288         // Member Accessors
00289         using base_class::size_nd;
00291         size_t rows() const { return size_nd()[0]; }
00293         size_t cols() const { return size_nd()[1]; }
00295         size_t channels() const
00296                 { return data::get_channels<N>::from(this->size_nd()); }
00297 
00299         size_t width() const { return cols(); }
00301         size_t height() const { return rows(); }
00302 
00304         inline const_pixel col(size_t row, size_t col) const
00305         {
00306                 return data::get_pixel<
00307                         typename this_type::data_type::has_random_access,
00308                         typename types::t_expr<N == 1>::type>::
00309                         from(*this, row, col);
00310         }
00312         inline pixel col(size_t row, size_t col)
00313         {
00314                 return data::get_pixel<
00315                         typename this_type::data_type::has_random_access,
00316                         typename types::t_expr<N == 1>::type>::
00317                         from(*this, row, col);
00318         }
00320         inline const_pixel col(const const_iterator& it) const { return pixel(it); }
00321 
00323         inline pixel col(const best_iterator& it) { return pixel(it); }
00324 
00326         color_type black() const
00327                 { return color_type(channels(), color_values<T>::min()); }
00328         color_type white() const
00329                 { return color_type(channels(), color_values<T>::max()); }
00330 
00332         iplimage_t* ipl() const
00333         {
00334                 return image_details::cv<true, T>::ipl(*this);
00335         }
00336 
00337         // OpenCV functions
00338         void load(const std::string& filename, image_channels channels = ic_auto)
00339         {
00340                 image_details::cv<true, T>::load(*this, filename, channels);
00341         }
00342         void save(const std::string& filename) const
00343         {
00344                 image_details::cv<true, T>::save(*this, filename);
00345         }
00346 
00347         // Image processing functions
00348 
00351 
00352         derived_type& put_pixel(double_point<2> a, color_type col = ivl::white<T, rgb>()) { this->col(a.y, a.x) = col; }
00354         color_type get_pixel(double_point<2> a) { return this->col(a.y, a.x); }
00355 
00357         derived_type& line(double_point<2> a, double_point<2> b, color_type col = ivl::white<T, rgb>(), double thickness = 1.5, double opacity = 1.)
00358         { line_on(*this, a, b, col, thickness, opacity); return this->derived(); }
00360         derived_type& circle(double_point<2> a, double radius, color_type col = ivl::white<T, rgb>(), double thickness = 1.5, double opacity = 1.)
00361         { return circle_on(*this, a, radius, col, thickness, opacity); }
00363         derived_type& rect(double_point<2> a, double_point<2> b, color_type col = ivl::white<T, rgb>(), double thickness = 1.5, double opacity = 1.)
00364         { return rect_on(*this, a, b, col, thickness, opacity); }
00366         derived_type& ellipse(double_point<2> a, double_point<2> b, double radius, color_type col = ivl::white<T, rgb>(), double thickness = 1.5, double opacity = 1.)
00367         { return ellipse_on(*this, a, b, radius, col, thickness, opacity); }
00370         derived_type& ellipse(double_point<2> c, double radius1, double radius2, double angle, color_type col = ivl::white<T, rgb>(), double thickness = 1.5, double opacity = 1.)
00371         { return ellipse_on(*this, c, radius1, radius2, angle, col, thickness, opacity); }
00372 
00373         derived_type& fill_circle(double_point<2> a, double radius, color_type col = ivl::white<T, rgb>(), double opacity = 1.)
00374         { return fill_circle_on(*this, a, radius, col, opacity); }
00376         derived_type& fill_rect(double_point<2> a, double_point<2> b, color_type col = ivl::white(ivl::color_type<T, rgb>()), double opacity = 1.)
00377         { return fill_rect_on(*this, a, b, col, opacity); }
00379         derived_type& fill_ellipse(double_point<2> a, double_point<2> b, double radius, color_type col = ivl::white(ivl::color_type<T, rgb>()), double opacity = 1.)
00380         { return fill_ellipse_on(*this, a, b, radius, col, opacity); }
00383         derived_type& fill_ellipse(double_point<2> c, double radius1, double radius2, double angle, color_type col = ivl::white(ivl::color_type<T, rgb>()), double opacity = 1.)
00384         { return fill_ellipse_on(*this, c, radius1, radius2, angle, col, opacity); }
00386         derived_type& fill_triangle(double_point<2> a, double_point<2> b, double_point<2> c, color_type col = ivl::white(ivl::color_type<T, rgb>()), double opacity = 1.)
00387         { return fill_triangle_on(*this, a, b, c, col, opacity); }
00389         derived_type& fill_quad(double_point<2> a, double_point<2> b, double_point<2> c, double_point<2> d, color_type col = ivl::white(ivl::color_type<T, rgb>()), double opacity = 1.)
00390         { return fill_quad_on(*this, a, b, c, d, col, opacity); }
00393 };
00394 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations