ivl 679
|
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