00001 /*!@file Image/PixelsTypes.H Basic pixel types version 2.0 */ 00002 00003 // //////////////////////////////////////////////////////////////////// // 00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the // 00005 // 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/Image/PixelsTypes.H $ 00035 // $Id: PixelsTypes.H 12962 2010-03-06 02:13:53Z irock $ 00036 // 00037 00038 #ifndef PIXELSTYPES_H_DEFINED 00039 #define PIXELSTYPES_H_DEFINED 00040 00041 #include "Util/MathFunctions.H" // for clampValue() 00042 #include "Image/PixelsBase.H" 00043 #include "Image/PixelsCommonDef.H" 00044 #include "Util/Promotions.H" 00045 #include "Util/TypeTraits.H" 00046 #include "Util/Assert.H" 00047 #include "Util/Types.H" 00048 #include "Util/log.H" 00049 #include "Image/colorDefs.H" 00050 00051 #include <cmath> 00052 00053 // ###################################################################### 00054 // ###################################################################### 00055 // Derived pixel classes that hold type conversion information 00056 // ###################################################################### 00057 // ###################################################################### 00058 00059 template <class T> class PixRGB; 00060 template <class T> class PixHSV; 00061 template <class T> class PixJpegYUV; 00062 template <class T> class PixVideoYUV; 00063 template <class T> class PixYIQ; 00064 template <class T> class PixHSL; 00065 template <class T> class PixLab; 00066 template <class T> class PixXYZ; 00067 template <class T> class PixH2SV1; 00068 template <class T> class PixH2SV2; 00069 template <class T> class PixH2SV3; 00070 template <class T, size_t dim> class PixHyper; 00071 template <class T> class PixDKL; 00072 00073 //! Specialize TypeTraits to indicate that PixRGB is a "trivial" type. 00074 /*! That is, it is a type that can be safely initialized with memset(), and 00075 safely copied with memcpy(). In practical terms, this means we're 00076 relying on PixRGB not to do anything significant in its copy 00077 constructor or destructor. */ 00078 00079 template <class T> struct TypeTraits<PixRGB<T> > 00080 { 00081 enum { isTrivial = TypeTraits<T>::isTrivial }; 00082 }; 00083 //! Specialize TypeTraits to indicate that PixHSV is a "trivial" type. 00084 template <class T> struct TypeTraits<PixHSV<T> > 00085 { 00086 enum { isTrivial = TypeTraits<T>::isTrivial }; 00087 }; 00088 //! Specialize TypeTraits to indicate that PixJpegYUV is a "trivial" type. 00089 template <class T> struct TypeTraits<PixJpegYUV<T> > 00090 { 00091 enum { isTrivial = TypeTraits<T>::isTrivial }; 00092 }; 00093 //! Specialize TypeTraits to indicate that PixVideoYUV is a "trivial" type. 00094 template <class T> struct TypeTraits<PixVideoYUV<T> > 00095 { 00096 enum { isTrivial = TypeTraits<T>::isTrivial }; 00097 }; 00098 //! Specialize TypeTraits to indicate that PixYIQ is a "trivial" type. 00099 template <class T> struct TypeTraits<PixYIQ<T> > 00100 { 00101 enum { isTrivial = TypeTraits<T>::isTrivial }; 00102 }; 00103 //! Specialize TypeTraits to indicate that PixHSL is a "trivial" type. 00104 template <class T> struct TypeTraits<PixHSL<T> > 00105 { 00106 enum { isTrivial = TypeTraits<T>::isTrivial }; 00107 }; 00108 //! Specialize TypeTraits to indicate that PixLab is a "trivial" type. 00109 template <class T> struct TypeTraits<PixLab<T> > 00110 { 00111 enum { isTrivial = TypeTraits<T>::isTrivial }; 00112 }; 00113 //! Specialize TypeTraits to indicate that PixXYZ is a "trivial" type. 00114 template <class T> struct TypeTraits<PixXYZ<T> > 00115 { 00116 enum { isTrivial = TypeTraits<T>::isTrivial }; 00117 }; 00118 //! Specialize TypeTraits to indicate that PixH2SV1 is a "trivial" type. 00119 template <class T> struct TypeTraits<PixH2SV1<T> > 00120 { 00121 enum { isTrivial = TypeTraits<T>::isTrivial }; 00122 }; 00123 //! Specialize TypeTraits to indicate that PixH2SV2 is a "trivial" type. 00124 template <class T> struct TypeTraits<PixH2SV2<T> > 00125 { 00126 enum { isTrivial = TypeTraits<T>::isTrivial }; 00127 }; 00128 //! Specialize TypeTraits to indicate that PixH2SV3 is a "trivial" type. 00129 template <class T> struct TypeTraits<PixH2SV3<T> > 00130 { 00131 enum { isTrivial = TypeTraits<T>::isTrivial }; 00132 }; 00133 //! Specialize TypeTraits to indicate that PixHyper is a "trivial" type. 00134 template <class T, size_t dim> struct TypeTraits<PixHyper<T,dim> > 00135 { 00136 enum { isTrivial = TypeTraits<T>::isTrivial }; 00137 }; 00138 //! Specialize TypeTraits to indicate that PixDKL is a "trivial" type. 00139 template <class T> struct TypeTraits<PixDKL<T> > 00140 { 00141 enum { isTrivial = TypeTraits<T>::isTrivial }; 00142 }; 00143 00144 00145 namespace ops 00146 { 00147 struct plus 00148 { 00149 template <class T, class U> 00150 typename promote_trait<T,U>::TP 00151 operator()(const T& t, const U& u) { return t+u; } 00152 }; 00153 00154 struct minus 00155 { 00156 template <class T, class U> 00157 typename promote_trait<T,U>::TP 00158 operator()(const T& t, const U& u) { return t-u; } 00159 }; 00160 00161 struct multiplies 00162 { 00163 template <class T, class U> 00164 typename promote_trait<T,U>::TP 00165 operator()(const T& t, const U& u) { return t*u; } 00166 }; 00167 00168 struct divides 00169 { 00170 template <class T, class U> 00171 typename promote_trait<T,U>::TP 00172 operator()(const T& t, const U& u) { return t/u; } 00173 }; 00174 00175 struct modulo 00176 { 00177 template <class T, class U> 00178 typename promote_trait<T,U>::TP 00179 operator()(const T& t, const U& u) { return t%u; } 00180 }; 00181 00182 struct bitwise_and 00183 { 00184 template <class T, class U> 00185 typename promote_trait<T,U>::TP 00186 operator()(const T& t, const U& u) { return t&u; } 00187 }; 00188 00189 struct bitwise_or 00190 { 00191 template <class T, class U> 00192 typename promote_trait<T,U>::TP 00193 operator()(const T& t, const U& u) { return t|u; } 00194 }; 00195 00196 struct bitwise_xor 00197 { 00198 template <class T, class U> 00199 typename promote_trait<T,U>::TP 00200 operator()(const T& t, const U& u) { return t^u; } 00201 }; 00202 00203 } 00204 00205 00206 //! Helper struct to provide a generic way to "rebind" template parameters. 00207 /*! That is, this gives us a way to get Foo<T2> if we are given 00208 Foo<T>, or to get Bar<T2, U> if we are given Bar<T, U>. In 00209 particular, this lets us write generic functions that can deal 00210 with pixel types that have either a single template parameter 00211 (e.g. PixRGB<T>, PixHSV<T>), or more than one template parameter 00212 (e.g. PixHyper<T, dim>). */ 00213 template <class C, class T> 00214 struct rebind 00215 {}; 00216 00217 template <template <class> class C, 00218 class T, class U> 00219 struct rebind<C<T>, U> 00220 { 00221 typedef C<U> type; 00222 }; 00223 00224 template <template <class, size_t> class C, 00225 class T1, size_t T2, class U1> 00226 struct rebind<C<T1, T2>, U1> 00227 { 00228 typedef C<U1, T2> type; 00229 }; 00230 00231 00232 namespace pix_helper 00233 { 00234 // ###################################################################### 00235 // ###################################################################### 00236 // clamp and convert helpers 00237 // ###################################################################### 00238 // ###################################################################### 00239 00240 /* These inline functions are used when setting Pix1 = Pix2 where the 00241 type for Pix1 is the same as Pix2, but its base type (float, int etc) 00242 is different. 00243 00244 As examples: 00245 - PixRGB<float> A = PixRGB<byte> B would use these. 00246 - PixRGB<float> A = PixHSV<int> B would NOT use these. 00247 00248 Since the typing is uncertain in this usege we use clamped_convert for 00249 all copies 00250 */ 00251 00252 template <class pix1, class pix2> 00253 inline void clamped_assign_3(pix1& lhs, const pix2& rhs) 00254 { 00255 lhs.p[0] = clamped_convert<typename pix1::ScalarType>(rhs.p[0]); 00256 lhs.p[1] = clamped_convert<typename pix1::ScalarType>(rhs.p[1]); 00257 lhs.p[2] = clamped_convert<typename pix1::ScalarType>(rhs.p[2]); 00258 } 00259 00260 template <class pix1, class pix2> 00261 inline void clamped_assign_4(pix1& lhs, const pix2& rhs) 00262 { 00263 lhs.p[0] = clamped_convert<typename pix1::ScalarType>(rhs.p[0]); 00264 lhs.p[1] = clamped_convert<typename pix1::ScalarType>(rhs.p[1]); 00265 lhs.p[2] = clamped_convert<typename pix1::ScalarType>(rhs.p[2]); 00266 lhs.p[3] = clamped_convert<typename pix1::ScalarType>(rhs.p[3]); 00267 } 00268 00269 template <class pix1, class pix2> 00270 inline void clamped_assign_n(pix1& lhs, const pix2& rhs) 00271 { 00272 for (size_t i = 0; i < pix1::myDim; ++i) 00273 lhs.p[i] = clamped_convert<typename pix1::ScalarType>(rhs.p[i]); 00274 } 00275 00276 00277 // ###################################################################### 00278 // ###################################################################### 00279 // helper functions for defining operators 00280 // ###################################################################### 00281 // ###################################################################### 00282 00283 // ###################################################################### 00284 //! helper for adding a base type with a pixel where basic type T != T2 00285 /*! EXAMPLE: PixRGB<float> += int */ 00286 00287 template <class insttype, class T2, class functype> 00288 inline insttype& pix_scalar_op_eq(insttype& lhs, 00289 const T2 rhs, 00290 functype func) 00291 { 00292 typedef typename insttype::ScalarType T; 00293 00294 for (size_t i = 0; i < insttype::myDim; i++) 00295 lhs.p[i] = clamped_convert<T>(func(lhs.p[i], rhs)); 00296 00297 return lhs; 00298 } 00299 00300 // ###################################################################### 00301 //! helper for adding a base type with a pixel where basic type T != T2 00302 /*! EXAMPLE: PixRGB<float> + int */ 00303 00304 template <class T, class insttype, class T2, class functype> 00305 inline typename rebind<insttype, 00306 typename promote_trait<T, T2>::TP>::type 00307 pix_scalar_op(const insttype& lhs, const T2 rhs, functype func) 00308 { 00309 typedef typename promote_trait<T, T2>::TP TP; 00310 typename rebind<insttype, TP>::type result; 00311 for (size_t i = 0; i < insttype::myDim; i++) 00312 result.p[i] = clamped_convert<TP>(func(lhs.p[i], rhs)); 00313 return result; 00314 } 00315 00316 // ###################################################################### 00317 //! Apply a x= operation between two pixels where the base type are the same 00318 /*! 4 operations can be performed here. The conditionals are constants so the compiler will pre-compute them 00319 (1) If a pixel type is the same and we will promote the trait and clamp (e.g. PixRGB<byte> += PixRGB<byte> ) 00320 (2) If a pixel type is not the same and we will promote the trait and clamp (e.g. PixHSV<byte> += PixRGB<byte> ) 00321 (3) If a pixel type is the same and we will not promote the trait and clamp (e.g. PixRGB<float> += PixRGB<float> ) 00322 (4) If a pixel type is not the same and we not will promote the trait and clamp (e.g. PixHSV<float> += PixRGB<float> ) 00323 */ 00324 00325 template <class lhstype, class rhstype, class functype> 00326 inline lhstype& pix_pix_op_eq(lhstype& lhs, 00327 const rhstype& rhs, 00328 functype func) 00329 { 00330 ASSERT(lhs.pType == rhs.pType); // since both pixels are pixtype<> 00331 00332 for (size_t i = 0; i < lhstype::myDim; i++) 00333 lhs.p[i] = clamped_convert<typename lhstype::ScalarType> 00334 (func(lhs.p[i], rhs.p[i])); 00335 00336 return lhs; 00337 } 00338 00339 // ###################################################################### 00340 //! Apply a x operation between two pixels where the base type are the same 00341 /*! 2 operations can be performed here. The conditionals are constants so the compiler will pre-compute them 00342 (1) If a pixel type is the same and we will promote the trait (e.g. PixRGB<byte> + PixRGB<byte> ) 00343 (2) If a pixel type is not the same and we will promote the trait (e.g. PixRGB<byte> + PixHSV<byte> ) 00344 */ 00345 00346 template <template <class> class pixtype, class T, class T2, class functype> 00347 inline pixtype<typename promote_trait<T,T2>::TP> 00348 pix_pix_op(const pixtype<T>& lhs, const pixtype<T2>& rhs, functype func) 00349 { 00350 ASSERT(lhs.pType == rhs.pType); // since both pixels are pixtype<> 00351 00352 typedef typename promote_trait<T,T2>::TP TP; 00353 pixtype<TP> result; 00354 for (size_t i = 0; i < pixtype<T>::myDim; i++) 00355 result.p[i] = clamped_convert<TP>(func(lhs.p[i], rhs.p[i])); 00356 return result; 00357 } 00358 00359 template <template <class, size_t> class pixtype, 00360 class T, class T2, size_t dim, class functype> 00361 inline pixtype<typename promote_trait<T,T2>::TP, dim> 00362 pix_pix_op(const pixtype<T, dim>& lhs, const pixtype<T2, dim>& rhs, functype func) 00363 { 00364 ASSERT(lhs.pType == rhs.pType); // since both pixels are pixtype<> 00365 00366 typedef typename promote_trait<T,T2>::TP TP; 00367 pixtype<TP, dim> result; 00368 for (size_t i = 0; i < pixtype<T, dim>::myDim; i++) 00369 result.p[i] = clamped_convert<TP>(func(lhs.p[i], rhs.p[i])); 00370 return result; 00371 } 00372 00373 } 00374 00375 //! A "mix-in" class that injects all arithmetic operators into the class that inherits it. 00376 /*! This is an example of "the curiously recurring template pattern", 00377 in which some class, say Foo, inherits from a template class 00378 instantiated on Foo, say Mixin<Foo>. In our case, we have the 00379 various pixel classes (e.g. PixRGB<T>) inheriting from this mixin 00380 class (e.g. pix_ops_mixin<PixRGB<T>, T>). */ 00381 00382 template <template <class> class pixtype, class T> 00383 struct pix_ops_mixin 00384 { 00385 00386 #define PIX_MATH_OPS_EQ(OPSYM, FUNCTYPE) \ 00387 template <class T2> inline pixtype<T>& operator OPSYM (const pixtype<T2>& A) { return pix_helper::pix_pix_op_eq(static_cast<pixtype<T>&>(*this), A, FUNCTYPE()); } 00388 00389 PIX_MATH_OPS_EQ(+=, ops::plus) 00390 PIX_MATH_OPS_EQ(-=, ops::minus) 00391 PIX_MATH_OPS_EQ(*=, ops::multiplies) 00392 PIX_MATH_OPS_EQ(/=, ops::divides) 00393 PIX_MATH_OPS_EQ(%=, ops::modulo) 00394 PIX_MATH_OPS_EQ(&=, ops::bitwise_and) 00395 PIX_MATH_OPS_EQ(|=, ops::bitwise_or) 00396 PIX_MATH_OPS_EQ(^=, ops::bitwise_xor) 00397 00398 #undef PIX_MATH_OPS_EQ 00399 00400 #define PIX_OPERATOR_EQ(OPSYM, FUNCTYPE) \ 00401 inline pixtype<T>& operator OPSYM (const bool A) { return pix_helper::pix_scalar_op_eq(static_cast<pixtype<T>&>(*this), A, FUNCTYPE()); } \ 00402 inline pixtype<T>& operator OPSYM (const char A) { return pix_helper::pix_scalar_op_eq(static_cast<pixtype<T>&>(*this), A, FUNCTYPE()); } \ 00403 inline pixtype<T>& operator OPSYM (const short A) { return pix_helper::pix_scalar_op_eq(static_cast<pixtype<T>&>(*this), A, FUNCTYPE()); } \ 00404 inline pixtype<T>& operator OPSYM (const int A) { return pix_helper::pix_scalar_op_eq(static_cast<pixtype<T>&>(*this), A, FUNCTYPE()); } \ 00405 inline pixtype<T>& operator OPSYM (const long A) { return pix_helper::pix_scalar_op_eq(static_cast<pixtype<T>&>(*this), A, FUNCTYPE()); } \ 00406 inline pixtype<T>& operator OPSYM (const float A) { return pix_helper::pix_scalar_op_eq(static_cast<pixtype<T>&>(*this), A, FUNCTYPE()); } \ 00407 inline pixtype<T>& operator OPSYM (const double A) { return pix_helper::pix_scalar_op_eq(static_cast<pixtype<T>&>(*this), A, FUNCTYPE()); } \ 00408 inline pixtype<T>& operator OPSYM (const long double A) { return pix_helper::pix_scalar_op_eq(static_cast<pixtype<T>&>(*this), A, FUNCTYPE()); } \ 00409 inline pixtype<T>& operator OPSYM (const unsigned char A) { return pix_helper::pix_scalar_op_eq(static_cast<pixtype<T>&>(*this), A, FUNCTYPE()); } \ 00410 inline pixtype<T>& operator OPSYM (const unsigned short A) { return pix_helper::pix_scalar_op_eq(static_cast<pixtype<T>&>(*this), A, FUNCTYPE()); } \ 00411 inline pixtype<T>& operator OPSYM (const unsigned int A) { return pix_helper::pix_scalar_op_eq(static_cast<pixtype<T>&>(*this), A, FUNCTYPE()); } \ 00412 inline pixtype<T>& operator OPSYM (const unsigned long A) { return pix_helper::pix_scalar_op_eq(static_cast<pixtype<T>&>(*this), A, FUNCTYPE()); } 00413 00414 PIX_OPERATOR_EQ(+=, ops::plus) 00415 PIX_OPERATOR_EQ(-=, ops::minus) 00416 PIX_OPERATOR_EQ(*=, ops::multiplies) 00417 PIX_OPERATOR_EQ(/=, ops::divides) 00418 PIX_OPERATOR_EQ(%=, ops::modulo) 00419 PIX_OPERATOR_EQ(&=, ops::bitwise_and) 00420 PIX_OPERATOR_EQ(|=, ops::bitwise_or) 00421 PIX_OPERATOR_EQ(^=, ops::bitwise_xor) 00422 00423 #undef PIX_OPERATOR_EQ 00424 00425 #define PIX_MATH_OPS(OPSYM, FUNCTYPE) \ 00426 template <class T2> \ 00427 inline typename rebind<pixtype<T>, typename promote_trait<T,T2>::TP>::type \ 00428 operator OPSYM (const pixtype<T2>& rhs) const \ 00429 { return pix_helper::pix_pix_op(static_cast<const pixtype<T>&>(*this), rhs, FUNCTYPE()); } 00430 00431 PIX_MATH_OPS(+, ops::plus) 00432 PIX_MATH_OPS(-, ops::minus) 00433 PIX_MATH_OPS(*, ops::multiplies) 00434 PIX_MATH_OPS(/, ops::divides) 00435 PIX_MATH_OPS(%, ops::modulo) 00436 PIX_MATH_OPS(&, ops::bitwise_and) 00437 PIX_MATH_OPS(|, ops::bitwise_or) 00438 PIX_MATH_OPS(^, ops::bitwise_xor) 00439 00440 #undef PIX_MATH_OPS 00441 00442 #define PIX_OP(T2, OPSYM, FUNC) \ 00443 inline typename rebind<pixtype<T>, typename promote_trait<T, T2>::TP>::type \ 00444 operator OPSYM (const T2 A) const { return pix_helper::pix_scalar_op<T>(static_cast<const pixtype<T>&>(*this), A, FUNC); } 00445 00446 #define PIX_OPERATOR(OPSYM, FUNCTYPE) \ 00447 PIX_OP(bool, OPSYM, FUNCTYPE()) \ 00448 PIX_OP(char, OPSYM, FUNCTYPE()) \ 00449 PIX_OP(short, OPSYM, FUNCTYPE()) \ 00450 PIX_OP(int, OPSYM, FUNCTYPE()) \ 00451 PIX_OP(long, OPSYM, FUNCTYPE()) \ 00452 PIX_OP(float, OPSYM, FUNCTYPE()) \ 00453 PIX_OP(double, OPSYM, FUNCTYPE()) \ 00454 PIX_OP(long double, OPSYM, FUNCTYPE()) \ 00455 PIX_OP(unsigned char, OPSYM, FUNCTYPE()) \ 00456 PIX_OP(unsigned short, OPSYM, FUNCTYPE()) \ 00457 PIX_OP(unsigned int, OPSYM, FUNCTYPE()) \ 00458 PIX_OP(unsigned long, OPSYM, FUNCTYPE()) 00459 00460 PIX_OPERATOR(+, ops::plus) 00461 PIX_OPERATOR(-, ops::minus) 00462 PIX_OPERATOR(*, ops::multiplies) 00463 PIX_OPERATOR(/, ops::divides) 00464 PIX_OPERATOR(%, ops::modulo) 00465 PIX_OPERATOR(&, ops::bitwise_and) 00466 PIX_OPERATOR(|, ops::bitwise_or) 00467 PIX_OPERATOR(^, ops::bitwise_xor) 00468 00469 #undef PIX_OPERATOR 00470 #undef PIX_OP 00471 }; 00472 00473 template <template <class, size_t> class pixtype, class T, size_t dim> 00474 struct pix_ops_mixin_hyper 00475 { 00476 00477 #define PIX_MATH_OPS_EQ(OPSYM, FUNCTYPE) \ 00478 template <class T2> inline pixtype<T, dim>& operator OPSYM (const pixtype<T2, dim>& A) { return pix_helper::pix_pix_op_eq(static_cast<pixtype<T, dim>&>(*this), A, FUNCTYPE()); } 00479 00480 PIX_MATH_OPS_EQ(+=, ops::plus) 00481 PIX_MATH_OPS_EQ(-=, ops::minus) 00482 PIX_MATH_OPS_EQ(*=, ops::multiplies) 00483 PIX_MATH_OPS_EQ(/=, ops::divides) 00484 PIX_MATH_OPS_EQ(%=, ops::modulo) 00485 PIX_MATH_OPS_EQ(&=, ops::bitwise_and) 00486 PIX_MATH_OPS_EQ(|=, ops::bitwise_or) 00487 PIX_MATH_OPS_EQ(^=, ops::bitwise_xor) 00488 00489 #undef PIX_MATH_OPS_EQ 00490 00491 #define PIX_OPERATOR_EQ(OPSYM, FUNCTYPE) \ 00492 inline pixtype<T, dim>& operator OPSYM (const bool A) { return pix_helper::pix_scalar_op_eq(static_cast<pixtype<T, dim>&>(*this), A, FUNCTYPE()); } \ 00493 inline pixtype<T, dim>& operator OPSYM (const char A) { return pix_helper::pix_scalar_op_eq(static_cast<pixtype<T, dim>&>(*this), A, FUNCTYPE()); } \ 00494 inline pixtype<T, dim>& operator OPSYM (const short A) { return pix_helper::pix_scalar_op_eq(static_cast<pixtype<T, dim>&>(*this), A, FUNCTYPE()); } \ 00495 inline pixtype<T, dim>& operator OPSYM (const int A) { return pix_helper::pix_scalar_op_eq(static_cast<pixtype<T, dim>&>(*this), A, FUNCTYPE()); } \ 00496 inline pixtype<T, dim>& operator OPSYM (const long A) { return pix_helper::pix_scalar_op_eq(static_cast<pixtype<T, dim>&>(*this), A, FUNCTYPE()); } \ 00497 inline pixtype<T, dim>& operator OPSYM (const float A) { return pix_helper::pix_scalar_op_eq(static_cast<pixtype<T, dim>&>(*this), A, FUNCTYPE()); } \ 00498 inline pixtype<T, dim>& operator OPSYM (const double A) { return pix_helper::pix_scalar_op_eq(static_cast<pixtype<T, dim>&>(*this), A, FUNCTYPE()); } \ 00499 inline pixtype<T, dim>& operator OPSYM (const long double A) { return pix_helper::pix_scalar_op_eq(static_cast<pixtype<T, dim>&>(*this), A, FUNCTYPE()); } \ 00500 inline pixtype<T, dim>& operator OPSYM (const unsigned char A) { return pix_helper::pix_scalar_op_eq(static_cast<pixtype<T, dim>&>(*this), A, FUNCTYPE()); } \ 00501 inline pixtype<T, dim>& operator OPSYM (const unsigned short A) { return pix_helper::pix_scalar_op_eq(static_cast<pixtype<T, dim>&>(*this), A, FUNCTYPE()); } \ 00502 inline pixtype<T, dim>& operator OPSYM (const unsigned int A) { return pix_helper::pix_scalar_op_eq(static_cast<pixtype<T, dim>&>(*this), A, FUNCTYPE()); } \ 00503 inline pixtype<T, dim>& operator OPSYM (const unsigned long A) { return pix_helper::pix_scalar_op_eq(static_cast<pixtype<T, dim>&>(*this), A, FUNCTYPE()); } 00504 00505 PIX_OPERATOR_EQ(+=, ops::plus) 00506 PIX_OPERATOR_EQ(-=, ops::minus) 00507 PIX_OPERATOR_EQ(*=, ops::multiplies) 00508 PIX_OPERATOR_EQ(/=, ops::divides) 00509 PIX_OPERATOR_EQ(%=, ops::modulo) 00510 PIX_OPERATOR_EQ(&=, ops::bitwise_and) 00511 PIX_OPERATOR_EQ(|=, ops::bitwise_or) 00512 PIX_OPERATOR_EQ(^=, ops::bitwise_xor) 00513 00514 #undef PIX_OPERATOR_EQ 00515 00516 #define PIX_MATH_OPS(OPSYM, FUNCTYPE) \ 00517 template <class T2> \ 00518 inline pixtype<typename promote_trait<T,T2>::TP, dim> \ 00519 operator OPSYM (const pixtype<T2, dim>& rhs) const \ 00520 { return pix_helper::pix_pix_op(static_cast<const pixtype<T, dim>&>(*this), rhs, FUNCTYPE()); } 00521 00522 PIX_MATH_OPS(+, ops::plus) 00523 PIX_MATH_OPS(-, ops::minus) 00524 PIX_MATH_OPS(*, ops::multiplies) 00525 PIX_MATH_OPS(/, ops::divides) 00526 PIX_MATH_OPS(%, ops::modulo) 00527 PIX_MATH_OPS(&, ops::bitwise_and) 00528 PIX_MATH_OPS(|, ops::bitwise_or) 00529 PIX_MATH_OPS(^, ops::bitwise_xor) 00530 00531 #undef PIX_MATH_OPS 00532 00533 #define PIX_OP(T2, OPSYM, FUNC) \ 00534 inline typename rebind<pixtype<T, dim>, typename promote_trait<T, T2>::TP>::type \ 00535 operator OPSYM (const T2 A) const { return pix_helper::pix_scalar_op<T>(static_cast<const pixtype<T, dim>&>(*this), A, FUNC); } 00536 00537 #define PIX_OPERATOR(OPSYM, FUNCTYPE) \ 00538 PIX_OP(bool, OPSYM, FUNCTYPE()) \ 00539 PIX_OP(char, OPSYM, FUNCTYPE()) \ 00540 PIX_OP(short, OPSYM, FUNCTYPE()) \ 00541 PIX_OP(int, OPSYM, FUNCTYPE()) \ 00542 PIX_OP(long, OPSYM, FUNCTYPE()) \ 00543 PIX_OP(float, OPSYM, FUNCTYPE()) \ 00544 PIX_OP(double, OPSYM, FUNCTYPE()) \ 00545 PIX_OP(long double, OPSYM, FUNCTYPE()) \ 00546 PIX_OP(unsigned char, OPSYM, FUNCTYPE()) \ 00547 PIX_OP(unsigned short, OPSYM, FUNCTYPE()) \ 00548 PIX_OP(unsigned int, OPSYM, FUNCTYPE()) \ 00549 PIX_OP(unsigned long, OPSYM, FUNCTYPE()) 00550 00551 PIX_OPERATOR(+, ops::plus) 00552 PIX_OPERATOR(-, ops::minus) 00553 PIX_OPERATOR(*, ops::multiplies) 00554 PIX_OPERATOR(/, ops::divides) 00555 PIX_OPERATOR(%, ops::modulo) 00556 PIX_OPERATOR(&, ops::bitwise_and) 00557 PIX_OPERATOR(|, ops::bitwise_or) 00558 PIX_OPERATOR(^, ops::bitwise_xor) 00559 00560 #undef PIX_OPERATOR 00561 #undef PIX_OP 00562 }; 00563 00564 // ################################# 00565 // ################################# 00566 // ###################################################################### 00567 // ###################################################################### 00568 // --> PIXEL TYPE DECLARATIONS <-- 00569 // ###################################################################### 00570 // ###################################################################### 00571 // ################################# 00572 // ################################# 00573 00574 // ###################################################################### 00575 // ###################################################################### 00576 //! This is the basic RGB pixel class 00577 // ###################################################################### 00578 // ###################################################################### 00579 00580 //! Derived RGB pixel class from Pixels 00581 template <class T> class PixRGB : 00582 public Pixels<T,3>, 00583 public pix_ops_mixin<PixRGB, T> 00584 { 00585 private: 00586 public: 00587 const static enum PixType pType = PixTypeRGB; 00588 const static size_t myDim = 3; 00589 00590 using Pixels<T,3>::p; 00591 00592 inline PixRGB(); 00593 inline ~PixRGB(); 00594 explicit inline PixRGB(const T val); 00595 00596 template <class T2> 00597 explicit inline PixRGB(const T2 val); 00598 00599 template <class T2> explicit inline PixRGB(const PixRGB<T2>& A); 00600 template <class T2> explicit inline PixRGB(const PixHSV<T2>& A); 00601 template <class T2> explicit inline PixRGB(const PixXYZ<T2>& A); 00602 template <class T2> explicit inline PixRGB(const PixLab<T2>& A); 00603 template <class T2> explicit inline PixRGB(const PixJpegYUV<T2>& A); 00604 template <class T2> explicit inline PixRGB(const PixVideoYUV<T2>& A); 00605 template <class T2> explicit inline PixRGB(const PixYIQ<T2>& A); 00606 template <class T2> explicit inline PixRGB(const PixHSL<T2>& A); 00607 template <class T2> explicit inline PixRGB(const PixH2SV1<T2>& A); 00608 template <class T2> explicit inline PixRGB(const PixH2SV2<T2>& A); 00609 template <class T2> explicit inline PixRGB(const PixHyper<T2,3>& A); 00610 00611 // NOTE: default operator=() OK 00612 00613 //! construct pixel from another. Defined here for tech reasons 00614 inline PixRGB(const PixRGB<T>& pix); 00615 //! Construct an RGB pixel with given values red, green, blue 00616 inline PixRGB(const T redval, const T greenval, const T blueval); 00617 //! Construct from given values, clamping & convertPixing as needed 00618 template <class T2, class T3, class T4> inline 00619 PixRGB(const T2 redval, const T3 greenval, const T4 blueval); 00620 00621 // special local access methods 00622 inline void getRGB(T& r, T& g, T& b) const; 00623 00624 //! Access red channel 00625 inline T red() const; 00626 //! Access green channel 00627 inline T green() const; 00628 //! Access blue channel 00629 inline T blue() const; 00630 //! Set red channel value, clamping & convertPixing as necessary 00631 template <class T2> inline void setRed(const T2 redval); 00632 //! Set green channel value, clamping & convertPixing as necessary 00633 template <class T2> inline void setGreen(const T2 greenval); 00634 //! Set blue channel value, clamping & convertPixing as necessary 00635 template <class T2> inline void setBlue(const T2 blueval); 00636 //! Set all channel values, clamping & convertPixing as necessary 00637 template <class T2, class T3, class T4> inline void 00638 set(const T2 redval, const T3 greenval, const T4 blueval); 00639 //! Compute luminance as (r + g + b) / 3 00640 inline T luminance() const; 00641 //! special methods added for backwards compat. 00642 inline void setHSV(const T h1, const T h2, const T s, const T v); 00643 //! special methods added for backwards compat. 00644 inline void getHSV(T& h1, T& h2, T& s, T& v) const; 00645 00646 // Any overrides to Pixels methods 00647 00648 }; 00649 00650 // ###################################################################### 00651 // ###################################################################### 00652 //! This is the basic HSV pixel class 00653 // ###################################################################### 00654 // ###################################################################### 00655 00656 //! Derived HSV pixel class from Pixels 00657 template <class T> class PixHSV : 00658 public Pixels<T,3>, 00659 public pix_ops_mixin<PixHSV, T> 00660 { 00661 private: 00662 public: 00663 const static enum PixType pType = PixTypeHSV; 00664 const static size_t myDim = 3; 00665 using Pixels<T,3>::p; 00666 00667 inline PixHSV(); 00668 inline ~PixHSV(); 00669 explicit inline PixHSV(const T val); 00670 00671 template <class T2> explicit inline PixHSV(const PixRGB<T2>& A); 00672 template <class T2> explicit inline PixHSV(const PixHSV<T2>& A); 00673 template <class T2> explicit inline PixHSV(const PixYIQ<T2>& A); 00674 template <class T2> explicit inline PixHSV(const PixHSL<T2>& A); 00675 template <class T2> explicit inline PixHSV(const PixH2SV1<T2>& A); 00676 template <class T2> explicit inline PixHSV(const PixH2SV2<T2>& A); 00677 template <class T2> explicit inline PixHSV(const PixH2SV3<T2>& A); 00678 template <class T2> explicit inline PixHSV(const PixHyper<T2,3>& A); 00679 00680 // default operator=() OK 00681 00682 //! construct pixel from another. Defined here for tech reasons 00683 inline PixHSV(const PixHSV<T>& pix); 00684 //! Construct an RGB pixel with given values red, green, blue 00685 inline PixHSV(const T Hval, const T Sval, const T Vval); 00686 //! Construct from given values, clamping & convertPixing as needed 00687 template <class T2, class T3, class T4> inline 00688 PixHSV(const T2 Hval, const T3 Sval, const T4 Vval); 00689 00690 // special local methods 00691 00692 inline void getHSV(T& h, T& s, T& v) const; 00693 00694 //! Access hue channel 00695 inline T H() const; 00696 //! Access sat channel 00697 inline T S() const; 00698 //! Access val channel 00699 inline T V() const; 00700 //! Set hue channel value, clamping & converting as necessary 00701 template <class T2> inline void setH(const T2 H); 00702 //! Set sat channel value, clamping & converting as necessary 00703 template <class T2> inline void setS(const T2 S); 00704 //! Set val channel value, clamping & converting as necessary 00705 template <class T2> inline void setV(const T2 V); 00706 00707 // Any overrides to Pixel methods 00708 }; 00709 00710 // ###################################################################### 00711 // ###################################################################### 00712 //! This is the basic jpeg-YUV pixel class 00713 // ###################################################################### 00714 // ###################################################################### 00715 00716 //! Derived YUV pixel class from Pixels 00717 template <class T> class PixJpegYUV : 00718 public Pixels<T,3>, 00719 public pix_ops_mixin<PixJpegYUV, T> 00720 { 00721 private: 00722 public: 00723 const static enum PixType pType = PixTypeYUV; 00724 const static size_t myDim = 3; 00725 using Pixels<T,3>::p; 00726 00727 inline PixJpegYUV(); 00728 inline ~PixJpegYUV(); 00729 explicit inline PixJpegYUV(const T val); 00730 00731 template <class T2> explicit inline PixJpegYUV(const PixJpegYUV<T2>& A); 00732 template <class T2> explicit inline PixJpegYUV(const PixRGB<T2>& A); 00733 template <class T2> explicit inline PixJpegYUV(const PixHyper<T2,3>& A); 00734 00735 // default operator=() OK 00736 00737 inline PixJpegYUV(const PixJpegYUV<T>& pix); 00738 00739 //! Construct an RGB pixel with given values red, green, blue 00740 inline PixJpegYUV(const T Yval, const T Uval, const T Vval); 00741 //! Construct from given values, clamping & converting as needed 00742 template <class T2, class T3, class T4> inline 00743 PixJpegYUV(const T2 Yval, const T3 Uval, const T4 Vval); 00744 00745 //! Access Y channel 00746 inline T Y() const; 00747 //! Access U channel 00748 inline T U() const; 00749 //! Access V channel 00750 inline T V() const; 00751 //! Set Y channel value, clamping & converting as necessary 00752 template <class T2> inline void setY(const T2 Y); 00753 //! Set U channel value, clamping & converting as necessary 00754 template <class T2> inline void setU(const T2 U); 00755 //! Set V channel value, clamping & converting as necessary 00756 template <class T2> inline void setV(const T2 V); 00757 00758 // Any overrides to Pixel methods 00759 }; 00760 00761 // ###################################################################### 00762 // ###################################################################### 00763 //! This is the basic video-YUV pixel class 00764 // ###################################################################### 00765 // ###################################################################### 00766 00767 //! Derived YUV pixel class from Pixels 00768 template <class T> class PixVideoYUV : 00769 public Pixels<T,3>, 00770 public pix_ops_mixin<PixVideoYUV, T> 00771 { 00772 private: 00773 public: 00774 const static enum PixType pType = PixTypeYUV; 00775 const static size_t myDim = 3; 00776 using Pixels<T,3>::p; 00777 00778 inline PixVideoYUV(); 00779 inline ~PixVideoYUV(); 00780 explicit inline PixVideoYUV(const T val); 00781 00782 template <class T2> explicit inline PixVideoYUV(const PixVideoYUV<T2>& A); 00783 template <class T2> explicit inline PixVideoYUV(const PixRGB<T2>& A); 00784 template <class T2> explicit inline PixVideoYUV(const PixHyper<T2,3>& A); 00785 00786 // default operator=() OK 00787 00788 inline PixVideoYUV(const PixVideoYUV<T>& pix); 00789 00790 //! Construct an RGB pixel with given values red, green, blue 00791 inline PixVideoYUV(const T Yval, const T Uval, const T Vval); 00792 //! Construct from given values, clamping & converting as needed 00793 template <class T2, class T3, class T4> inline 00794 PixVideoYUV(const T2 Yval, const T3 Uval, const T4 Vval); 00795 00796 // special local methods 00797 00798 inline void getVideoYUV(T& y, T& u, T& v) const; 00799 00800 //! Access Y channel 00801 inline T Y() const; 00802 //! Access U channel 00803 inline T U() const; 00804 //! Access V channel 00805 inline T V() const; 00806 //! Set Y channel value, clamping & converting as necessary 00807 template <class T2> inline void setY(const T2 Y); 00808 //! Set U channel value, clamping & converting as necessary 00809 template <class T2> inline void setU(const T2 U); 00810 //! Set V channel value, clamping & converting as necessary 00811 template <class T2> inline void setV(const T2 V); 00812 00813 // Any overrides to Pixel methods 00814 }; 00815 00816 // ###################################################################### 00817 // ###################################################################### 00818 //! This is the basic YIQ pixel class 00819 // ###################################################################### 00820 // ###################################################################### 00821 00822 //! Derived YIQ pixel class from Pixels 00823 template <class T> class PixYIQ : 00824 public Pixels<T,3>, 00825 public pix_ops_mixin<PixYIQ, T> 00826 { 00827 private: 00828 public: 00829 const static enum PixType pType = PixTypeYIQ; 00830 const static size_t myDim = 3; 00831 using Pixels<T,3>::p; 00832 00833 inline PixYIQ(); 00834 inline ~PixYIQ(); 00835 explicit inline PixYIQ(const T val); 00836 00837 template <class T2> explicit inline PixYIQ(const PixRGB<T2>& A); 00838 template <class T2> explicit inline PixYIQ(const PixHSV<T2>& A); 00839 template <class T2> explicit inline PixYIQ(const PixYIQ<T2>& A); 00840 template <class T2> explicit inline PixYIQ(const PixHSL<T2>& A); 00841 template <class T2> explicit inline PixYIQ(const PixH2SV1<T2>& A); 00842 template <class T2> explicit inline PixYIQ(const PixH2SV2<T2>& A); 00843 template <class T2> explicit inline PixYIQ(const PixH2SV3<T2>& A); 00844 template <class T2> explicit inline PixYIQ(const PixHyper<T2,3>& A); 00845 00846 // default operator=() OK 00847 00848 //! construct pixel from another. Defined here for tech reasons 00849 inline PixYIQ(const PixYIQ<T>& pix); 00850 //! Construct an RGB pixel with given values red, green, blue 00851 inline PixYIQ(const T Yval, const T Ival, const T Qval); 00852 //! Construct from given values, clamping & converting as needed 00853 template <class T2, class T3, class T4> inline 00854 PixYIQ(const T2 Yval, const T3 Uval, const T4 Vval); 00855 00856 // special local methods 00857 00858 inline void getYIQ(T& y, T& i, T& q) const; 00859 00860 //! Access Y channel 00861 inline T Y() const; 00862 //! Access I channel 00863 inline T I() const; 00864 //! Access Q channel 00865 inline T Q() const; 00866 //! Set Y channel value, clamping & converting as necessary 00867 template <class T2> inline void setY(const T2 Y); 00868 //! Set I channel value, clamping & converting as necessary 00869 template <class T2> inline void setI(const T2 I); 00870 //! Set Q channel value, clamping & converting as necessary 00871 template <class T2> inline void setQ(const T2 Q); 00872 00873 // Any overrides to Pixel methods 00874 }; 00875 00876 // ###################################################################### 00877 // ###################################################################### 00878 //! This is the basic HSL pixel class 00879 // ###################################################################### 00880 // ###################################################################### 00881 00882 //! Derived HSL pixel class from Pixels 00883 template <class T> class PixHSL : 00884 public Pixels<T,3>, 00885 public pix_ops_mixin<PixHSL, T> 00886 { 00887 private: 00888 public: 00889 const static enum PixType pType = PixTypeHSL; 00890 const static size_t myDim = 3; 00891 using Pixels<T,3>::p; 00892 00893 inline PixHSL(); 00894 inline ~PixHSL(); 00895 explicit inline PixHSL(const T val); 00896 00897 template <class T2> explicit inline PixHSL(const PixRGB<T2>& A); 00898 template <class T2> explicit inline PixHSL(const PixHSV<T2>& A); 00899 template <class T2> explicit inline PixHSL(const PixYIQ<T2>& A); 00900 template <class T2> explicit inline PixHSL(const PixHSL<T2>& A); 00901 template <class T2> explicit inline PixHSL(const PixH2SV1<T2>& A); 00902 template <class T2> explicit inline PixHSL(const PixH2SV2<T2>& A); 00903 template <class T2> explicit inline PixHSL(const PixH2SV3<T2>& A); 00904 template <class T2> explicit inline PixHSL(const PixHyper<T2,3>& A); 00905 00906 // default operator=() OK 00907 00908 //! construct pixel from another. Defined here for tech reasons 00909 inline PixHSL(const PixHSL<T>& pix); 00910 //! Construct an RGB pixel with given values red, green, blue 00911 inline PixHSL(const T Hval, const T Sval, const T Lval); 00912 //! Construct from given values, clamping & convertPixing as needed 00913 template <class T2, class T3, class T4> inline 00914 PixHSL(const T2 Hval, const T3 Sval, const T4 Lval); 00915 00916 // special local methods 00917 00918 inline void getHSL(T& h, T& s, T& l) const; 00919 00920 //! Access hue channel 00921 inline T H() const; 00922 //! Access sat channel 00923 inline T S() const; 00924 //! Access val channel 00925 inline T L() const; 00926 //! Set hue channel value, clamping & converting as necessary 00927 template <class T2> inline void setH(const T2 H); 00928 //! Set sat channel value, clamping & converting as necessary 00929 template <class T2> inline void setS(const T2 S); 00930 //! Set val channel value, clamping & converting as necessary 00931 template <class T2> inline void setL(const T2 L); 00932 00933 // Any overrides to Pixel methods 00934 }; 00935 00936 // ###################################################################### 00937 // ###################################################################### 00938 //! This is the basic Lab pixel class 00939 // ###################################################################### 00940 // ###################################################################### 00941 00942 //! Derived Lab pixel class from Pixels 00943 template <class T> class PixLab : 00944 public Pixels<T,3>, 00945 public pix_ops_mixin<PixLab, T> 00946 { 00947 private: 00948 public: 00949 const static enum PixType pType = PixTypeLab; 00950 const static size_t myDim = 3; 00951 using Pixels<T,3>::p; 00952 00953 inline PixLab(); 00954 inline ~PixLab(); 00955 explicit inline PixLab(const T val); 00956 00957 template <class T2> explicit inline PixLab(const PixRGB<T2>& A); 00958 template <class T2> explicit inline PixLab(const PixLab<T2>& A); 00959 template <class T2> explicit inline PixLab(const PixHyper<T2,3>& A); 00960 00961 // default operator=() OK 00962 00963 //! construct pixel from another. Defined here for tech reasons 00964 inline PixLab(const PixLab<T>& pix); 00965 //! Construct an RGB pixel with given values red, green, blue 00966 inline PixLab(const T Lval, const T Aval, const T Bval); 00967 //! Construct from given values, clamping & convertPixing as needed 00968 template <class T2, class T3, class T4> inline 00969 PixLab(const T2 Lval, const T3 Aval, const T4 Bval); 00970 00971 // special local methods 00972 00973 inline void getLab(T& l, T& a, T& b) const; 00974 00975 //! Access hue channel 00976 inline T L() const; 00977 //! Access sat channel 00978 inline T A() const; 00979 //! Access val channel 00980 inline T B() const; 00981 //! Set hue channel value, clamping & converting as necessary 00982 template <class T2> inline void setL(const T2 L); 00983 //! Set sat channel value, clamping & converting as necessary 00984 template <class T2> inline void setA(const T2 A); 00985 //! Set val channel value, clamping & converting as necessary 00986 template <class T2> inline void setB(const T2 B); 00987 00988 // Any overrides to Pixel methods 00989 }; 00990 00991 // ###################################################################### 00992 // ###################################################################### 00993 //! This is the basic XYZ pixel class 00994 // ###################################################################### 00995 // ###################################################################### 00996 00997 //! Derived XYZ pixel class from Pixels 00998 template <class T> class PixXYZ : 00999 public Pixels<T,3>, 01000 public pix_ops_mixin<PixXYZ, T> 01001 { 01002 private: 01003 public: 01004 const static enum PixType pType = PixTypeXYZ; 01005 const static size_t myDim = 3; 01006 using Pixels<T,3>::p; 01007 01008 inline PixXYZ(); 01009 inline ~PixXYZ(); 01010 explicit inline PixXYZ(const T val); 01011 01012 template <class T2> explicit inline PixXYZ(const PixRGB<T2>& A); 01013 template <class T2> explicit inline PixXYZ(const PixXYZ<T2>& A); 01014 template <class T2> explicit inline PixXYZ(const PixHyper<T2,3>& A); 01015 01016 // default operator=() OK 01017 01018 //! construct pixel from another. Defined here for tech reasons 01019 inline PixXYZ(const PixXYZ<T>& pix); 01020 //! Construct an RGB pixel with given values red, green, blue 01021 inline PixXYZ(const T Xval, const T Yval, const T Zval); 01022 //! Construct from given values, clamping & convertPixing as needed 01023 template <class T2, class T3, class T4> inline 01024 PixXYZ(const T2 Xval, const T3 Yval, const T4 Zval); 01025 01026 // special local methods 01027 01028 inline void getXYZ(T& x, T& y, T& z) const; 01029 01030 //! Access hue channel 01031 inline T X() const; 01032 //! Access sat channel 01033 inline T Y() const; 01034 //! Access val channel 01035 inline T Z() const; 01036 //! Set hue channel value, clamping & converting as necessary 01037 template <class T2> inline void setX(const T2 X); 01038 //! Set sat channel value, clamping & converting as necessary 01039 template <class T2> inline void setY(const T2 Y); 01040 //! Set val channel value, clamping & converting as necessary 01041 template <class T2> inline void setZ(const T2 Z); 01042 01043 // Any overrides to Pixel methods 01044 }; 01045 01046 // ###################################################################### 01047 // ###################################################################### 01048 //! This is the H2SV1 pixel class 01049 /*! This is the HSV color space normalized and de-modulized into 01050 components H1 H2 S and V. This is used since the modulus nature 01051 of hue makes it hard to deal with in many types of computation. 01052 PixH2SV1 is a very linear transforamtion. 01053 PixH2SV2 is linear but is B/Y R/G opponent in nature 01054 PixH2SV3 is as bio as this can get but is less linear 01055 */ 01056 // ###################################################################### 01057 // ###################################################################### 01058 01059 //! Derived H2SV1 pixel class from Pixels 01060 template <class T> class PixH2SV1 : 01061 public Pixels<T,4>, 01062 public pix_ops_mixin<PixH2SV1, T> 01063 { 01064 private: 01065 public: 01066 const static enum PixType pType = PixTypeH2SV1; 01067 const static size_t myDim = 4; 01068 using Pixels<T,4>::p; 01069 01070 inline PixH2SV1(); 01071 inline ~PixH2SV1(); 01072 explicit inline PixH2SV1(const T val); 01073 01074 template <class T2> explicit inline PixH2SV1(const PixRGB<T2>& A); 01075 template <class T2> explicit inline PixH2SV1(const PixHSV<T2>& A); 01076 template <class T2> explicit inline PixH2SV1(const PixYIQ<T2>& A); 01077 template <class T2> explicit inline PixH2SV1(const PixHSL<T2>& A); 01078 template <class T2> explicit inline PixH2SV1(const PixH2SV1<T2>& A); 01079 template <class T2> explicit inline PixH2SV1(const PixH2SV2<T2>& A); 01080 template <class T2> explicit inline PixH2SV1(const PixH2SV3<T2>& A); 01081 template <class T2> explicit inline PixH2SV1(const PixHyper<T2,4>& A); 01082 01083 // default operator=() OK 01084 01085 //! construct pixel from another. Defined here for tech reasons 01086 inline PixH2SV1(const PixH2SV1<T>& pix); 01087 //! Construct an RGB pixel with given values red, green, blue 01088 inline PixH2SV1(const T H1val, const T H2val, const T Sval, const T Vval); 01089 //! Construct from given values, clamping & converting as needed 01090 template <class T2, class T3, class T4, class T5> inline 01091 PixH2SV1(const T2 H1val, const T3 H2val, const T4 Sval, const T5 Vval ); 01092 01093 // special local methods 01094 inline void getH2SV1(T& h1, T& h2, T& s, T& v) const; 01095 01096 //! Access H1 channel 01097 inline T H1() const; 01098 //! Access H2 channel 01099 inline T H2() const; 01100 //! Access S channel 01101 inline T S() const; 01102 //! Access V channel 01103 inline T V() const; 01104 //! Set H1 channel value, clamping & converting as necessary 01105 template <class T2> inline void setH1(const T2 H1); 01106 //! Set H2 channel value, clamping & converting as necessary 01107 template <class T2> inline void setH2(const T2 H2); 01108 //! Set S channel value, clamping & converting as necessary 01109 template <class T2> inline void setS(const T2 S); 01110 //! Set V channel value, clamping & converting as necessary 01111 template <class T2> inline void setV(const T2 V); 01112 01113 // Any overrides to Pixel methods 01114 }; 01115 01116 // ###################################################################### 01117 // ###################################################################### 01118 //! This is the H2SV2 pixel class 01119 /*! This is the HSV color space normalized and de-modulized into 01120 components H1 H2 S and V. This is used since the modulus nature 01121 of hue makes it hard to deal with in many types of computation. 01122 PixH2SV1 is a very linear transforamtion. 01123 PixH2SV2 is linear but is B/Y R/G opponent in nature 01124 PixH2SV3 is as bio as this can get but is less linear 01125 */ 01126 // ###################################################################### 01127 // ###################################################################### 01128 01129 //! Derived H2SV2 pixel class from Pixels 01130 template <class T> class PixH2SV2 : 01131 public Pixels<T,4>, 01132 public pix_ops_mixin<PixH2SV2, T> 01133 { 01134 private: 01135 public: 01136 const static enum PixType pType = PixTypeH2SV2; 01137 const static size_t myDim = 4; 01138 using Pixels<T,4>::p; 01139 01140 inline PixH2SV2(); 01141 inline ~PixH2SV2(); 01142 explicit inline PixH2SV2(const T val); 01143 01144 template <class T2> explicit inline PixH2SV2(const PixRGB<T2>& A); 01145 template <class T2> explicit inline PixH2SV2(const PixHSV<T2>& A); 01146 template <class T2> explicit inline PixH2SV2(const PixYIQ<T2>& A); 01147 template <class T2> explicit inline PixH2SV2(const PixHSL<T2>& A); 01148 template <class T2> explicit inline PixH2SV2(const PixH2SV1<T2>& A); 01149 template <class T2> explicit inline PixH2SV2(const PixH2SV2<T2>& A); 01150 template <class T2> explicit inline PixH2SV2(const PixH2SV3<T2>& A); 01151 template <class T2> explicit inline PixH2SV2(const PixHyper<T2,4>& A); 01152 01153 // default operator=() OK 01154 01155 //! construct pixel from another. Defined here for tech reasons 01156 inline PixH2SV2(const PixH2SV2<T>& pix); 01157 //! Construct an RGB pixel with given values red, green, blue 01158 inline PixH2SV2(const T H1val, const T H2val, const T Sval, const T Vval); 01159 //! Construct from given values, clamping & converting as needed 01160 template <class T2, class T3, class T4, class T5> inline 01161 PixH2SV2(const T2 H1val, const T3 H2val, const T4 Sval, const T5 Vval ); 01162 01163 // special local methods 01164 01165 inline void getH2SV2(T& h1, T& h2, T& s, T& v) const; 01166 01167 //! Access H1 channel 01168 inline T H1() const; 01169 //! Access H2 channel 01170 inline T H2() const; 01171 //! Access S channel 01172 inline T S() const; 01173 //! Access V channel 01174 inline T V() const; 01175 //! Set H1 channel value, clamping & converting as necessary 01176 template <class T2> inline void setH1(const T2 H1); 01177 //! Set H2 channel value, clamping & converting as necessary 01178 template <class T2> inline void setH2(const T2 H2); 01179 //! Set S channel value, clamping & converting as necessary 01180 template <class T2> inline void setS(const T2 S); 01181 //! Set V channel value, clamping & converting as necessary 01182 template <class T2> inline void setV(const T2 V); 01183 01184 // Any overrides to Pixel methods 01185 }; 01186 01187 // ###################################################################### 01188 // ###################################################################### 01189 //! This is the H2SV3 pixel class 01190 /*! This is the HSV color space normalized and de-modulized into 01191 components H1 H2 S and V. This is used since the modulus nature 01192 of hue makes it hard to deal with in many types of computation. 01193 PixH2SV1 is a very linear transforamtion. 01194 PixH2SV2 is linear but is B/Y R/G opponent in nature 01195 PixH2SV3 is as bio as this can get but is less linear 01196 */ 01197 // ###################################################################### 01198 // ###################################################################### 01199 01200 //! Derived H2SV3 pixel class from Pixels 01201 template <class T> class PixH2SV3 : 01202 public Pixels<T,4>, 01203 public pix_ops_mixin<PixH2SV3, T> 01204 { 01205 private: 01206 public: 01207 const static enum PixType pType = PixTypeH2SV3; 01208 const static size_t myDim = 4; 01209 using Pixels<T,4>::p; 01210 01211 inline PixH2SV3(); 01212 inline ~PixH2SV3(); 01213 explicit inline PixH2SV3(const T val); 01214 01215 template <class T2> explicit inline PixH2SV3(const PixYIQ<T2>& A); 01216 template <class T2> explicit inline PixH2SV3(const PixH2SV1<T2>& A); 01217 template <class T2> explicit inline PixH2SV3(const PixH2SV2<T2>& A); 01218 template <class T2> explicit inline PixH2SV3(const PixH2SV3<T2>& A); 01219 template <class T2> explicit inline PixH2SV3(const PixHyper<T2,4>& A); 01220 01221 // default operator=() OK 01222 01223 //! construct pixel from another. Defined here for tech reasons 01224 inline PixH2SV3(const PixH2SV3<T>& pix); 01225 //! Construct an RGB pixel with given values red, green, blue 01226 inline PixH2SV3(const T H1val, const T H2val, const T Sval, const T Vval); 01227 //! Construct from given values, clamping & converting as needed 01228 template <class T2, class T3, class T4, class T5> inline 01229 PixH2SV3(const T2 H1val, const T3 H2val, const T4 Sval, const T5 Vval ); 01230 01231 // special local methods 01232 01233 inline void getH2SV3(T& h1, T& h2, T& s, T& v) const; 01234 01235 //! Access H1 channel 01236 inline T H1() const; 01237 //! Access H2 channel 01238 inline T H2() const; 01239 //! Access S channel 01240 inline T S() const; 01241 //! Access V channel 01242 inline T V() const; 01243 //! Set H1 channel value, clamping & converting as necessary 01244 template <class T2> inline void setH1(const T2 H1); 01245 //! Set H2 channel value, clamping & converting as necessary 01246 template <class T2> inline void setH2(const T2 H2); 01247 //! Set S channel value, clamping & converting as necessary 01248 template <class T2> inline void setS(const T2 S); 01249 //! Set V channel value, clamping & converting as necessary 01250 template <class T2> inline void setV(const T2 V); 01251 01252 // Any overrides to Pixel methods 01253 }; 01254 01255 // ###################################################################### 01256 // ###################################################################### 01257 //! This is the hyper pixel class 01258 // ###################################################################### 01259 // ###################################################################### 01260 01261 //! Derived Hyper spectral pixel class from Pixels 01262 template <class T, size_t dim> class PixHyper : 01263 public Pixels<T,dim>, 01264 public pix_ops_mixin_hyper<PixHyper, T, dim> 01265 { 01266 private: 01267 public: 01268 const static enum PixType pType = PixTypeHyper; 01269 const static size_t myDim = dim; 01270 01271 using Pixels<T,dim>::p; 01272 01273 inline PixHyper(); 01274 inline ~PixHyper(); 01275 explicit inline PixHyper(const T val); 01276 01277 template <class T2> explicit inline PixHyper(const PixRGB<T2>& A); 01278 template <class T2> explicit inline PixHyper(const PixHSV<T2>& A); 01279 template <class T2> explicit inline PixHyper(const PixJpegYUV<T2>& A); 01280 template <class T2> explicit inline PixHyper(const PixVideoYUV<T2>& A); 01281 template <class T2> explicit inline PixHyper(const PixYIQ<T2>& A); 01282 template <class T2> explicit inline PixHyper(const PixHSL<T2>& A); 01283 template <class T2> explicit inline PixHyper(const PixH2SV1<T2>& A); 01284 template <class T2> explicit inline PixHyper(const PixH2SV2<T2>& A); 01285 template <class T2> explicit inline PixHyper(const PixH2SV3<T2>& A); 01286 template <class T2> explicit inline PixHyper(const PixHyper<T2,dim>& A); 01287 01288 //! construct pixel from another. Defined here for tech reasons 01289 inline PixHyper(const PixHyper<T,dim>& pix); 01290 }; 01291 01292 // ###################################################################### 01293 // ###################################################################### 01294 //! This is the basic DKL pixel class 01295 // ###################################################################### 01296 // ###################################################################### 01297 01298 //! Derived DKL pixel class from Pixels 01299 template <class T> class PixDKL : 01300 public Pixels<T,3>, 01301 public pix_ops_mixin<PixDKL, T> 01302 { 01303 private: 01304 public: 01305 const static enum PixType pType = PixTypeDKL; 01306 const static size_t myDim = 3; 01307 using Pixels<T,3>::p; 01308 01309 inline PixDKL(); 01310 inline ~PixDKL(); 01311 explicit inline PixDKL(const T val); 01312 01313 template <class T2> explicit inline PixDKL(const PixRGB<T2>& A); 01314 template <class T2> explicit inline PixDKL(const PixDKL<T2>& A); 01315 01316 // default operator=() OK 01317 01318 //! construct pixel from another. Defined here for tech reasons 01319 inline PixDKL(const PixDKL<T>& pix); 01320 //! Construct a pixel with given values for D, K, L 01321 inline PixDKL(const T Dval, const T Kval, const T Lval); 01322 //! Construct from given values, clamping & convertPixing as needed 01323 template <class T2, class T3, class T4> inline 01324 PixDKL(const T2 Dval, const T3 Kval, const T4 Lval); 01325 01326 // special local methods 01327 01328 inline void getDKL(T& d, T& k, T& l) const; 01329 01330 //! Access hue channel 01331 inline T D() const; 01332 //! Access sat channel 01333 inline T K() const; 01334 //! Access val channel 01335 inline T L() const; 01336 //! Set hue channel value, clamping & converting as necessary 01337 template <class T2> inline void setD(const T2 D); 01338 //! Set sat channel value, clamping & converting as necessary 01339 template <class T2> inline void setK(const T2 K); 01340 //! Set val channel value, clamping & converting as necessary 01341 template <class T2> inline void setL(const T2 L); 01342 01343 // Any overrides to Pixel methods 01344 }; 01345 01346 // ################################# 01347 // ################################# 01348 // ###################################################################### 01349 // ###################################################################### 01350 // --> PIXEL METHODS <-- 01351 // ###################################################################### 01352 // ###################################################################### 01353 // ################################# 01354 // ################################# 01355 01356 // ###################################################################### 01357 // ###################################################################### 01358 // Pixels RGB 01359 // ###################################################################### 01360 // ###################################################################### 01361 01362 // ###################################################################### 01363 // constructors for where Pix<T> != Pix<T2> - with conversion 01364 // ###################################################################### 01365 01366 template <class T> 01367 template <class T2> inline PixRGB<T>::PixRGB(const PixRGB<T2>& A) 01368 : Pixels<T,3>() 01369 { 01370 pix_helper::clamped_assign_3(*this, A); 01371 } 01372 01373 // ###################################################################### 01374 template <class T> 01375 template <class T2> inline PixRGB<T>::PixRGB(const PixHSV<T2>& A1) 01376 : Pixels<T,3>() 01377 { 01378 const PixHSV<double> A( A1 ); 01379 01380 // p[0] = r : p[1] = g : p[2] = b 01381 // A[0] = h : A[1] = s : A[2] = v 01382 01383 const double vf = A[2] / HSV_V_UPPER; 01384 const double sf = A[1] / HSV_S_UPPER; 01385 01386 // SEE PixelsCommonDef.H 01387 PIX_HSV_TO_RGB_COMMON(A[0],sf,vf,p[0],p[1],p[2]) 01388 01389 } 01390 01391 // ###################################################################### 01392 template <class T> 01393 template <class T2> inline PixRGB<T>::PixRGB(const PixXYZ<T2>& A1) 01394 : Pixels<T,3>() 01395 { 01396 const PixXYZ<double> A( A1 ); 01397 01398 // p[0] = r : p[1] = g : p[2] = b 01399 // A[0] = x : A[1] = y : A[2] = z 01400 01401 // SEE PixelsCommonDef.H 01402 double r,g,b; 01403 01404 PIX_XYZ_TO_RGB_OPENCV_COMMON(A[0],A[1],A[2],r,g,b) 01405 01406 p[0] = clamped_convert<T>(r); 01407 p[1] = clamped_convert<T>(g); 01408 p[2] = clamped_convert<T>(b); 01409 } 01410 01411 // ###################################################################### 01412 template <class T> 01413 template <class T2> inline PixRGB<T>::PixRGB(const PixLab<T2>& A1) 01414 : Pixels<T,3>() 01415 { 01416 const PixLab<double> A( A1 ); 01417 01418 // p[0] = r : p[1] = g : p[2] = b 01419 // A[0] = l : A[1] = a : A[2] = b 01420 01421 double X,Y,Z,r,g,b; 01422 01423 // SEE PixelsCommonDef.H 01424 PIX_LAB_TO_XYZ_OPENCV_COMMON(A[0],A[1],A[2],X,Y,Z) 01425 // SEE PixelsCommonDef.H 01426 PIX_XYZ_TO_RGB_OPENCV_COMMON(X,Y,Z,r,g,b) 01427 01428 p[0] = clamped_convert<T>(r); 01429 p[1] = clamped_convert<T>(g); 01430 p[2] = clamped_convert<T>(b); 01431 } 01432 01433 // ###################################################################### 01434 template <class T> 01435 template <class T2> inline PixRGB<T>::PixRGB(const PixJpegYUV<T2>& A) 01436 : Pixels<T,3>() 01437 { 01438 // p[0] = r : p[1] = g : p[2] = b 01439 // A[0] = y : A[1] = u : A[2] = v 01440 const double yf = double(A[0]) - JPEGYUV_Y_OFFSET; 01441 const double uf = double(A[1]) - JPEGYUV_UV_OFFSET; 01442 const double vf = double(A[2]) - JPEGYUV_UV_OFFSET; 01443 01444 const double rf = yf + JPEGYUV_R_V*vf; 01445 const double gf = yf + JPEGYUV_G_U*uf + JPEGYUV_G_V*vf; 01446 const double bf = yf + JPEGYUV_B_U*uf; 01447 01448 this->p[0] = clamped_rounded_convert<T>(clampValue(rf, 0.0, 255.0)); 01449 this->p[1] = clamped_rounded_convert<T>(clampValue(gf, 0.0, 255.0)); 01450 this->p[2] = clamped_rounded_convert<T>(clampValue(bf, 0.0, 255.0)); 01451 } 01452 01453 // ###################################################################### 01454 template <class T> 01455 template <class T2> inline PixRGB<T>::PixRGB(const PixVideoYUV<T2>& A) 01456 : Pixels<T,3>() 01457 { 01458 // p[0] = r : p[1] = g : p[2] = b 01459 // A[0] = y : A[1] = u : A[2] = v 01460 const double yf = double(A[0]) - VIDEOYUV_Y_OFFSET; 01461 const double uf = double(A[1]) - VIDEOYUV_UV_OFFSET; 01462 const double vf = double(A[2]) - VIDEOYUV_UV_OFFSET; 01463 01464 const double rf = VIDEOYUV_RGB_Y*yf + VIDEOYUV_R_V*vf; 01465 const double gf = VIDEOYUV_RGB_Y*yf + VIDEOYUV_G_U*uf + VIDEOYUV_G_V*vf; 01466 const double bf = VIDEOYUV_RGB_Y*yf + VIDEOYUV_B_U*uf; 01467 01468 this->p[0] = clamped_rounded_convert<T>(clampValue(rf, 0.0, 255.0)); 01469 this->p[1] = clamped_rounded_convert<T>(clampValue(gf, 0.0, 255.0)); 01470 this->p[2] = clamped_rounded_convert<T>(clampValue(bf, 0.0, 255.0)); 01471 } 01472 01473 // ###################################################################### 01474 template <class T> 01475 template <class T2> inline PixRGB<T>::PixRGB(const PixYIQ<T2>& A1) 01476 : Pixels<T,3>() 01477 { 01478 const PixYIQ<double> A( A1 ); 01479 01480 // p[0] = r : p[1] = g : p[2] = b 01481 // A[0] = y : A[1] = i : A[2] = q 01482 p[0] = clamped_rounded_convert<T>(1.0 * A[0] + 0.956 * A[1] + 0.621 * A[2]); 01483 p[1] = clamped_rounded_convert<T>(1.0 * A[0] - 0.272 * A[1] - 0.647 * A[2]); 01484 p[2] = clamped_rounded_convert<T>(1.0 * A[0] - 1.105 * A[1] + 1.702 * A[2]); 01485 } 01486 01487 // ###################################################################### 01488 template <class T> 01489 template <class T2> inline PixRGB<T>::PixRGB(const PixHSL<T2>& A1) 01490 : Pixels<T,3>() 01491 { 01492 const PixHSL<double> A( A1 ); 01493 01494 // p[0] = r : p[1] = g : p[2] = b 01495 // A[0] = h : A[1] = s : A[2] = l 01496 const double H = A[0]; 01497 const double S = A[1]; 01498 const double L = A[2]; 01499 01500 if(S == 0) 01501 { 01502 p[0] = clamped_convert<T>(L*RGB_R_UPPER); 01503 p[1] = clamped_convert<T>(L*RGB_G_UPPER); 01504 p[2] = clamped_convert<T>(L*RGB_B_UPPER); 01505 } 01506 else 01507 { 01508 double r,g,b; 01509 double t2; 01510 if(L < 0.5) t2 = L * (1.0 + S); 01511 else t2 = L + S - (L * S); 01512 const double t1 = 2.0 * L - t2; 01513 const double hk = H/360; 01514 01515 // Set RED 01516 const double tr = hk + 1.0/3.0; 01517 if (tr < 0) tr = tr + 1; 01518 else if (tr > 1) tr = tr - 1; 01519 if (tr < 1.0/6.0) r = t1 + ((t2 - t1) * 6.0 * tr); 01520 else if (tr < 1.0/2.0) r = t2; 01521 else if (tr < 2.0/3.0) r = t1 + ((t2 - t1) * 6.0 * (2.0/3.0 - tr)); 01522 else r = t1; 01523 r *= RGB_R_UPPER; p[0] = clamped_convert<T>(r); 01524 01525 // set GREEN 01526 const double tg = hk; 01527 if (tg < 0) tg = tr + 1; 01528 else if (tg > 1) tg = tg - 1; 01529 if (tg < 1.0/6.0) g = t1 + ((t2 - t1) * 6.0 * tg); 01530 else if (tg < 1.0/2.0) g = t2; 01531 else if (tg < 2.0/3.0) g = t1 + ((t2 - t1) * 6.0 * (2.0/3.0 - tg)); 01532 else g = t1; 01533 g *= RGB_G_UPPER; p[1] = clamped_convert<T>(g); 01534 01535 // set BLUE 01536 const double tb = hk - 1.0/3.0; 01537 if (tb < 0) tb = tb + 1; 01538 else if (tb > 1) tb = tb - 1; 01539 if (tb < 1.0/6.0) b = t1 + ((t2 - t1) * 6.0 * tb); 01540 else if (tb < 1.0/2.0) b = t2; 01541 else if (tb < 2.0/3.0) b = t1 + ((t2 - t1) * 6.0 * (2.0/3.0 - tb)); 01542 else b = t1; 01543 b *= RGB_B_UPPER; p[2] = clamped_convert<T>(b); 01544 } 01545 01546 01547 } 01548 01549 // ###################################################################### 01550 template <class T> 01551 template <class T2> inline PixRGB<T>::PixRGB(const PixH2SV1<T2>& A1) 01552 : Pixels<T,3>() 01553 { 01554 const PixH2SV1<double> A( A1 ); 01555 01556 // p[0] = r : p[1] = g : p[2] = b 01557 // A[0] = h1 : A[1] = h2 : A[2] = s : A[3] = v 01558 01559 double h = 0; 01560 01561 // SEE PixelsCommonDef.H 01562 PIX_H2SV1_TO_HSV_SIMPLE_COMMON(A[0],A[1],h) 01563 // SEE PixelsCommonDef.H 01564 PIX_HSV_TO_RGB_COMMON(h,A[2],A[3],p[0],p[1],p[2]) 01565 } 01566 01567 // ###################################################################### 01568 template <class T> 01569 template <class T2> inline PixRGB<T>::PixRGB(const PixH2SV2<T2>& A1) 01570 : Pixels<T,3>() 01571 { 01572 01573 const PixH2SV2<double> A( A1 ); 01574 01575 // p[0] = r : p[1] = g : p[2] = b 01576 // A[0] = h1 : A[1] = h2 : A[2] = s : A[3] = v 01577 01578 double h = 0; 01579 double sf = 0; 01580 01581 // SEE PixelsCommonDef.H 01582 PIX_H2SV2_TO_HSV_ROBUST_COMMON(A[0],A[1],A[2],h,sf) 01583 // SEE PixelsCommonDef.H 01584 PIX_HSV_TO_RGB_COMMON(h,sf,A[3],p[0],p[1],p[2]) 01585 } 01586 01587 // ###################################################################### 01588 template <class T> 01589 template <class T2> inline PixRGB<T>::PixRGB(const PixHyper<T2,3>& A) 01590 : Pixels<T,3>() 01591 { 01592 pix_helper::clamped_assign_3(*this, A); 01593 } 01594 01595 // ###################################################################### 01596 // Standard Constructors / Destrcutor 01597 // ###################################################################### 01598 01599 template <class T> 01600 inline PixRGB<T>::PixRGB() : Pixels<T,3>() 01601 {} 01602 01603 // ###################################################################### 01604 template <class T> 01605 inline PixRGB<T>::~PixRGB() 01606 {} 01607 01608 // ###################################################################### 01609 template <class T> 01610 inline PixRGB<T>::PixRGB(const T val) : Pixels<T,3>(val) 01611 {} 01612 01613 // ###################################################################### 01614 template <class T> 01615 template <class T2> 01616 inline PixRGB<T>::PixRGB(const T2 val) 01617 : 01618 Pixels<T,3>(clamped_convert<T>(val)) 01619 {} 01620 01621 // ###################################################################### 01622 // Special methods for this class 01623 // ###################################################################### 01624 01625 template <class T> 01626 inline void PixRGB<T>::getRGB(T& r, T& g, T& b) const 01627 { 01628 r = p[0]; g = p[1]; b = p[2]; 01629 } 01630 01631 template <class T> 01632 inline PixRGB<T>::PixRGB(const PixRGB<T>& pix) : Pixels<T,3>(pix) 01633 {} 01634 01635 // ###################################################################### 01636 template <class T> 01637 inline PixRGB<T>::PixRGB(const T redval, const T greenval, const T blueval) : Pixels<T,3>() 01638 { 01639 p[0] = redval; p[1] = greenval; p[2] = blueval; 01640 } 01641 01642 // ###################################################################### 01643 template <class T> template <class T2, class T3, class T4> inline 01644 PixRGB<T>::PixRGB(const T2 redval, const T3 greenval, const T4 blueval) : Pixels<T,3>() 01645 { 01646 p[0] = clamped_convert<T>(redval); 01647 p[1] = clamped_convert<T>(greenval); 01648 p[2] = clamped_convert<T>(blueval); 01649 } 01650 01651 // ###################################################################### 01652 template <class T> inline T PixRGB<T>::red() const 01653 { 01654 return p[0]; 01655 } 01656 01657 // ###################################################################### 01658 template <class T> inline T PixRGB<T>::green() const 01659 { 01660 return p[1]; 01661 } 01662 01663 // ###################################################################### 01664 template <class T> inline T PixRGB<T>::blue() const 01665 { 01666 return p[2]; 01667 } 01668 01669 // ###################################################################### 01670 template <class T> 01671 template <class T2> inline void PixRGB<T>::setRed(const T2 redval) 01672 { 01673 p[0] = clamped_convert<T>(redval); 01674 } 01675 01676 // ###################################################################### 01677 template <class T> 01678 template <class T2> inline void PixRGB<T>::setGreen(const T2 greenval) 01679 { 01680 p[1] = clamped_convert<T>(greenval); 01681 } 01682 01683 // ###################################################################### 01684 template <class T> 01685 template <class T2> inline void PixRGB<T>::setBlue(const T2 blueval) 01686 { 01687 p[2] = clamped_convert<T>(blueval); 01688 } 01689 01690 // ###################################################################### 01691 template <class T> template <class T2, class T3, class T4> inline void 01692 PixRGB<T>::set(const T2 redval, const T3 greenval, const T4 blueval) 01693 { 01694 p[0] = clamped_convert<T>(redval); 01695 p[1] = clamped_convert<T>(greenval); 01696 p[2] = clamped_convert<T>(blueval); 01697 } 01698 01699 // ###################################################################### 01700 template <class T> inline T PixRGB<T>::luminance() const 01701 { 01702 return clamped_convert<T>( (double(p[0]) + double(p[1]) + double(p[2])) 01703 / 3.0 ); 01704 } 01705 01706 // ###################################################################### 01707 template <class T> 01708 inline void PixRGB<T>::getHSV(T& h1, T& h2, T& s, T& v) const 01709 { 01710 const PixH2SV1<double> temph2sv1(*this); 01711 h1 = temph2sv1.p[0]; 01712 h2 = temph2sv1.p[1]; 01713 s = temph2sv1.p[2]; 01714 v = temph2sv1.p[3]; 01715 } 01716 01717 // ###################################################################### 01718 template <class T> 01719 inline void PixRGB<T>::setHSV(const T h1, const T h2, const T s, const T v) 01720 { 01721 T H1 = h1; T H2 = h2; T S = s; T V = v; 01722 PixH2SV1<T> A(H1,H2,S,V); 01723 *this = A; 01724 } 01725 01726 // ###################################################################### 01727 // ###################################################################### 01728 // Pixels HSV 01729 // ###################################################################### 01730 // ###################################################################### 01731 01732 // ###################################################################### 01733 // constructors for where Pix<T> != Pix<T2> - with conversion 01734 // ###################################################################### 01735 01736 template <class T> 01737 template <class T2> inline PixHSV<T>::PixHSV(const PixRGB<T2>& A1) 01738 : Pixels<T,3>() 01739 { 01740 const PixRGB<double> A( A1 ); 01741 01742 // p[0] = h : p[1] = s : p[2] = v 01743 // A[0] = r : A[1] = g : A[2] = b 01744 01745 PIX_RGB_TO_HSV_COMMON(A[0],A[1],A[2],p[0],p[1],p[2],true) 01746 01747 } 01748 01749 // ###################################################################### 01750 template <class T> 01751 template <class T2> inline PixHSV<T>::PixHSV(const PixHSV<T2>& A) 01752 : Pixels<T,3>() 01753 { 01754 pix_helper::clamped_assign_3(*this, A); 01755 } 01756 01757 // ###################################################################### 01758 template <class T> 01759 template <class T2> inline PixHSV<T>::PixHSV(const PixYIQ<T2>& A1) 01760 : Pixels<T,3>() 01761 { 01762 const PixYIQ<double> A( A1 ); 01763 const PixRGB<double> B( A ); 01764 const PixHSV<double> C( B ); 01765 pix_helper::clamped_assign_3(*this, C); 01766 } 01767 01768 // ###################################################################### 01769 template <class T> 01770 template <class T2> inline PixHSV<T>::PixHSV(const PixHSL<T2>& A1) 01771 : Pixels<T,3>() 01772 { 01773 const PixHSL<double> A( A1 ); 01774 const PixRGB<double> B( A ); 01775 const PixHSV<double> C( B ); 01776 pix_helper::clamped_assign_3(*this, C); 01777 } 01778 01779 // ###################################################################### 01780 template <class T> 01781 template <class T2> inline PixHSV<T>::PixHSV(const PixH2SV1<T2>& A1) 01782 : Pixels<T,3>() 01783 { 01784 const PixH2SV1<double> A( A1 ); 01785 // A[0] = H1, A[1] = H2 01786 01787 // SEE PixelsCommonDef.H 01788 PIX_H2SV1_TO_HSV_SIMPLE_COMMON(A[0],A[1],p[0]) 01789 01790 p[1] = clamped_convert<T>(A[2]*HSV_S_UPPER); 01791 p[2] = clamped_convert<T>(A[3]*HSV_V_UPPER); 01792 } 01793 01794 // ###################################################################### 01795 template <class T> 01796 template <class T2> inline PixHSV<T>::PixHSV(const PixH2SV2<T2>& A1) 01797 : Pixels<T,3>() 01798 { 01799 const PixH2SV2<double> A( A1 ); 01800 01801 double h = 0; 01802 double sf = 0; 01803 01804 // SEE PixelsCommonDef.H 01805 PIX_H2SV2_TO_HSV_ROBUST_COMMON(A[0],A[1],A[2],p[0],sf) 01806 01807 p[1] = clamped_convert<T>(sf*HSV_S_UPPER); 01808 p[2] = clamped_convert<T>(A[3]*HSV_V_UPPER); 01809 } 01810 01811 // ###################################################################### 01812 template <class T> 01813 template <class T2> inline PixHSV<T>::PixHSV(const PixHyper<T2,3>& A) 01814 : Pixels<T,3>() 01815 { 01816 pix_helper::clamped_assign_3(*this, A); 01817 } 01818 01819 // ###################################################################### 01820 // Standard Constructors / Destrcutor 01821 // ###################################################################### 01822 01823 template <class T> 01824 inline PixHSV<T>::PixHSV() : Pixels<T,3>() 01825 {} 01826 01827 // ###################################################################### 01828 template <class T> 01829 inline PixHSV<T>::~PixHSV() 01830 {} 01831 01832 // ###################################################################### 01833 template <class T> 01834 inline PixHSV<T>::PixHSV(const T val) : Pixels<T,3>(val) 01835 {} 01836 01837 // ###################################################################### 01838 template <class T> 01839 inline PixHSV<T>::PixHSV(const PixHSV<T>& pix) : Pixels<T,3>(pix) 01840 {} 01841 01842 // ###################################################################### 01843 // Special methods for this class 01844 // ###################################################################### 01845 01846 template <class T> 01847 inline void PixHSV<T>::getHSV(T& h, T& s, T& v) const 01848 { 01849 h = p[0]; s = p[1]; v = p[2]; 01850 } 01851 01852 // ###################################################################### 01853 template <class T> 01854 inline PixHSV<T>::PixHSV(const T Hval, const T Sval, const T Vval) : Pixels<T,3>() 01855 { 01856 p[0] = Hval; p[1] = Sval; p[2] = Vval; 01857 } 01858 01859 // ###################################################################### 01860 template <class T> template <class T2, class T3, class T4> inline 01861 PixHSV<T>::PixHSV(const T2 Hval, const T3 Sval, const T4 Vval) : Pixels<T,3>() 01862 { 01863 p[0] = clamped_convert<T>(Hval); 01864 p[1] = clamped_convert<T>(Sval); 01865 p[2] = clamped_convert<T>(Vval); 01866 } 01867 01868 // ###################################################################### 01869 template <class T> 01870 inline T PixHSV<T>::H() const 01871 { 01872 return p[0]; 01873 } 01874 01875 // ###################################################################### 01876 template <class T> 01877 inline T PixHSV<T>::S() const 01878 { 01879 return p[1]; 01880 } 01881 01882 // ###################################################################### 01883 template <class T> 01884 inline T PixHSV<T>::V() const 01885 { 01886 return p[2]; 01887 } 01888 01889 // ###################################################################### 01890 template <class T> 01891 template <class T2> inline void PixHSV<T>::setH(const T2 hh) 01892 { 01893 p[0] = clamped_convert<T>(hh); 01894 } 01895 01896 // ###################################################################### 01897 template <class T> 01898 template <class T2> inline void PixHSV<T>::setS(const T2 ss) 01899 { 01900 p[1] = clamped_convert<T>(ss); 01901 } 01902 01903 // ###################################################################### 01904 template <class T> 01905 template <class T2> inline void PixHSV<T>::setV(const T2 vv) 01906 { 01907 p[2] = clamped_convert<T>(vv); 01908 } 01909 01910 // ###################################################################### 01911 // ###################################################################### 01912 // Pixels YUV 01913 // ###################################################################### 01914 // ###################################################################### 01915 01916 // ###################################################################### 01917 // constructors for where Pix<T> != Pix<T2> - with conversion 01918 // ###################################################################### 01919 01920 // ###################################################################### 01921 template <class T> 01922 template <class T2> inline PixJpegYUV<T>::PixJpegYUV(const PixJpegYUV<T2>& A) 01923 : Pixels<T,3>() 01924 { 01925 pix_helper::clamped_assign_3(*this, A); 01926 } 01927 01928 template <class T> 01929 template <class T2> inline PixJpegYUV<T>::PixJpegYUV(const PixRGB<T2>& A) 01930 : Pixels<T,3>() 01931 { 01932 // p[0] = y : p[1] = u : p[2] = v 01933 // A[0] = r : A[1] = g : A[2] = b 01934 const double yf = 01935 JPEGYUV_Y_R*A[0] + JPEGYUV_Y_G*A[1] + JPEGYUV_Y_B*A[2]; 01936 const double uf = 01937 JPEGYUV_U_R*A[0] + JPEGYUV_U_G*A[1] + JPEGYUV_U_B*A[2] 01938 + JPEGYUV_UV_OFFSET; 01939 const double vf = 01940 JPEGYUV_V_R*A[0] + JPEGYUV_V_G*A[1] + JPEGYUV_V_B*A[2] 01941 + JPEGYUV_UV_OFFSET; 01942 01943 p[0] = clamped_rounded_convert<T>(clampValue(yf, 0.0, 255.0)); 01944 p[1] = clamped_rounded_convert<T>(clampValue(uf, 0.0, 255.0)); 01945 p[2] = clamped_rounded_convert<T>(clampValue(vf, 0.0, 255.0)); 01946 } 01947 01948 // ###################################################################### 01949 template <class T> 01950 template <class T2> inline PixJpegYUV<T>::PixJpegYUV(const PixHyper<T2,3>& A) 01951 : Pixels<T,3>() 01952 { 01953 pix_helper::clamped_assign_3(*this, A); 01954 } 01955 01956 // ###################################################################### 01957 // Standard Constructors / Destrcutor 01958 // ###################################################################### 01959 01960 template <class T> 01961 inline PixJpegYUV<T>::PixJpegYUV() : Pixels<T,3>() 01962 {} 01963 01964 // ###################################################################### 01965 template <class T> 01966 inline PixJpegYUV<T>::~PixJpegYUV() 01967 {} 01968 01969 // ###################################################################### 01970 template <class T> 01971 inline PixJpegYUV<T>::PixJpegYUV(const T val) : Pixels<T,3>(val) 01972 {} 01973 01974 // ###################################################################### 01975 template <class T> 01976 inline PixJpegYUV<T>::PixJpegYUV(const PixJpegYUV<T>& pix) 01977 : Pixels<T,3>(pix) 01978 {} 01979 01980 01981 // ###################################################################### 01982 // Special methods for this class 01983 // ###################################################################### 01984 01985 template <class T> 01986 inline PixJpegYUV<T>::PixJpegYUV(const T Yval, const T Uval, const T Vval) 01987 : Pixels<T,3>() 01988 { 01989 p[0] = Yval; p[1] = Uval; p[2] = Vval; 01990 } 01991 01992 // ###################################################################### 01993 template <class T> template <class T2, class T3, class T4> inline 01994 PixJpegYUV<T>::PixJpegYUV(const T2 Yval, const T3 Uval, const T4 Vval) : Pixels<T,3>() 01995 { 01996 p[0] = clamped_convert<T>(Yval); 01997 p[1] = clamped_convert<T>(Uval); 01998 p[2] = clamped_convert<T>(Vval); 01999 } 02000 02001 // ###################################################################### 02002 template <class T> 02003 inline T PixJpegYUV<T>::Y() const 02004 { 02005 return p[0]; 02006 } 02007 02008 // ###################################################################### 02009 template <class T> 02010 inline T PixJpegYUV<T>::U() const 02011 { 02012 return p[1]; 02013 } 02014 02015 // ###################################################################### 02016 template <class T> 02017 inline T PixJpegYUV<T>::V() const 02018 { 02019 return p[2]; 02020 } 02021 02022 // ###################################################################### 02023 template <class T> 02024 template <class T2> inline void PixJpegYUV<T>::setY(const T2 yy) 02025 { 02026 p[0] = clamped_convert<T>(yy); 02027 } 02028 02029 // ###################################################################### 02030 template <class T> 02031 template <class T2> inline void PixJpegYUV<T>::setU(const T2 uu) 02032 { 02033 p[1] = clamped_convert<T>(uu); 02034 } 02035 02036 // ###################################################################### 02037 template <class T> 02038 template <class T2> inline void PixJpegYUV<T>::setV(const T2 vv) 02039 { 02040 p[2] = clamped_convert<T>(vv); 02041 } 02042 02043 // ###################################################################### 02044 // ###################################################################### 02045 // Pixels YUV 02046 // ###################################################################### 02047 // ###################################################################### 02048 02049 // ###################################################################### 02050 // constructors for where Pix<T> != Pix<T2> - with conversion 02051 // ###################################################################### 02052 02053 // ###################################################################### 02054 template <class T> 02055 template <class T2> inline PixVideoYUV<T>::PixVideoYUV(const PixVideoYUV<T2>& A) 02056 : Pixels<T,3>() 02057 { 02058 pix_helper::clamped_assign_3(*this, A); 02059 } 02060 02061 template <class T> 02062 template <class T2> inline PixVideoYUV<T>::PixVideoYUV(const PixRGB<T2>& A) 02063 : Pixels<T,3>() 02064 { 02065 // p[0] = y : p[1] = u : p[2] = v 02066 // A[0] = r : A[1] = g : A[2] = b 02067 02068 const double yf = 02069 VIDEOYUV_Y_R*A[0] + VIDEOYUV_Y_G*A[1] + VIDEOYUV_Y_B*A[2] 02070 + double(VIDEOYUV_Y_OFFSET); 02071 const double uf = 02072 VIDEOYUV_U_R*A[0] + VIDEOYUV_U_G*A[1] + VIDEOYUV_U_B*A[2] 02073 + double(VIDEOYUV_UV_OFFSET); 02074 const double vf = 02075 VIDEOYUV_V_R*A[0] + VIDEOYUV_V_G*A[1] + VIDEOYUV_V_B*A[2] 02076 + double(VIDEOYUV_UV_OFFSET); 02077 02078 p[0] = clamped_rounded_convert<T>(clampValue(yf, 0.0, 255.0)); 02079 p[1] = clamped_rounded_convert<T>(clampValue(uf, 0.0, 255.0)); 02080 p[2] = clamped_rounded_convert<T>(clampValue(vf, 0.0, 255.0)); 02081 } 02082 02083 // ###################################################################### 02084 template <class T> 02085 template <class T2> inline PixVideoYUV<T>::PixVideoYUV(const PixHyper<T2,3>& A) 02086 : Pixels<T,3>() 02087 { 02088 pix_helper::clamped_assign_3(*this, A); 02089 } 02090 02091 // ###################################################################### 02092 // Standard Constructors / Destrcutor 02093 // ###################################################################### 02094 02095 template <class T> 02096 inline PixVideoYUV<T>::PixVideoYUV() : Pixels<T,3>() 02097 {} 02098 02099 // ###################################################################### 02100 template <class T> 02101 inline PixVideoYUV<T>::~PixVideoYUV() 02102 {} 02103 02104 // ###################################################################### 02105 template <class T> 02106 inline PixVideoYUV<T>::PixVideoYUV(const T val) : Pixels<T,3>(val) 02107 {} 02108 02109 // ###################################################################### 02110 template <class T> 02111 inline PixVideoYUV<T>::PixVideoYUV(const PixVideoYUV<T>& pix) 02112 : Pixels<T,3>(pix) 02113 {} 02114 02115 02116 // ###################################################################### 02117 // Special methods for this class 02118 // ###################################################################### 02119 02120 template <class T> 02121 inline void PixVideoYUV<T>::getVideoYUV(T& y, T& u, T& v) const 02122 { 02123 y = p[0]; u = p[1]; v = p[2]; 02124 } 02125 02126 template <class T> 02127 inline PixVideoYUV<T>::PixVideoYUV(const T Yval, const T Uval, const T Vval) 02128 : Pixels<T,3>() 02129 { 02130 p[0] = Yval; p[1] = Uval; p[2] = Vval; 02131 } 02132 02133 // ###################################################################### 02134 template <class T> template <class T2, class T3, class T4> inline 02135 PixVideoYUV<T>::PixVideoYUV(const T2 Yval, const T3 Uval, const T4 Vval) : Pixels<T,3>() 02136 { 02137 p[0] = clamped_convert<T>(Yval); 02138 p[1] = clamped_convert<T>(Uval); 02139 p[2] = clamped_convert<T>(Vval); 02140 } 02141 02142 // ###################################################################### 02143 template <class T> 02144 inline T PixVideoYUV<T>::Y() const 02145 { 02146 return p[0]; 02147 } 02148 02149 // ###################################################################### 02150 template <class T> 02151 inline T PixVideoYUV<T>::U() const 02152 { 02153 return p[1]; 02154 } 02155 02156 // ###################################################################### 02157 template <class T> 02158 inline T PixVideoYUV<T>::V() const 02159 { 02160 return p[2]; 02161 } 02162 02163 // ###################################################################### 02164 template <class T> 02165 template <class T2> inline void PixVideoYUV<T>::setY(const T2 yy) 02166 { 02167 p[0] = clamped_convert<T>(yy); 02168 } 02169 02170 // ###################################################################### 02171 template <class T> 02172 template <class T2> inline void PixVideoYUV<T>::setU(const T2 uu) 02173 { 02174 p[1] = clamped_convert<T>(uu); 02175 } 02176 02177 // ###################################################################### 02178 template <class T> 02179 template <class T2> inline void PixVideoYUV<T>::setV(const T2 vv) 02180 { 02181 p[2] = clamped_convert<T>(vv); 02182 } 02183 02184 // ###################################################################### 02185 // ###################################################################### 02186 // Pixels YIQ 02187 // ###################################################################### 02188 // ###################################################################### 02189 02190 // ###################################################################### 02191 // constructors for where Pix<T> != Pix<T2> - with conversion 02192 // ###################################################################### 02193 02194 template <class T> 02195 template <class T2> inline PixYIQ<T>::PixYIQ(const PixRGB<T2>& A1) 02196 : Pixels<T,3>() 02197 { 02198 const PixRGB<double> A( A1 ); 02199 // coeffs from Foley & Van Dam 02200 // p[0] = y : p[1] = i : p[2] = q 02201 // A[0] = r : A[1] = g : A[2] = b 02202 p[0] = clamped_rounded_convert<T>(0.299 * A[0] + 0.587 * A[1] + 0.114 * A[2]); 02203 p[1] = clamped_rounded_convert<T>(0.596 * A[0] - 0.275 * A[1] - 0.321 * A[2]); 02204 p[2] = clamped_rounded_convert<T>(0.212 * A[0] - 0.523 * A[1] + 0.311 * A[2]); 02205 } 02206 02207 // ###################################################################### 02208 template <class T> 02209 template <class T2> inline PixYIQ<T>::PixYIQ(const PixHSV<T2>& A1) 02210 : Pixels<T,3>() 02211 { 02212 const PixHSV<double> A( A1 ); 02213 const PixRGB<double> B( A ); 02214 const PixYIQ<double> C( B ); 02215 pix_helper::clamped_assign_3(*this, C); 02216 } 02217 02218 // ###################################################################### 02219 template <class T> 02220 template <class T2> inline PixYIQ<T>::PixYIQ(const PixYIQ<T2>& A) 02221 : Pixels<T,3>() 02222 { 02223 pix_helper::clamped_assign_3(*this, A); 02224 } 02225 02226 // ###################################################################### 02227 template <class T> 02228 template <class T2> inline PixYIQ<T>::PixYIQ(const PixHSL<T2>& A1) 02229 : Pixels<T,3>() 02230 { 02231 const PixHSL<double> A( A1 ); 02232 const PixRGB<double> B( A ); 02233 const PixYIQ<double> C( B ); 02234 pix_helper::clamped_assign_3(*this, C); 02235 } 02236 02237 // ###################################################################### 02238 template <class T> 02239 template <class T2> inline PixYIQ<T>::PixYIQ(const PixH2SV1<T2>& A1) 02240 : Pixels<T,3>() 02241 { 02242 const PixH2SV1<double> A( A1 ); 02243 const PixRGB<double> B( A ); 02244 const PixYIQ<double> C( B ); 02245 pix_helper::clamped_assign_3(*this, C); 02246 } 02247 02248 // ###################################################################### 02249 template <class T> 02250 template <class T2> inline PixYIQ<T>::PixYIQ(const PixH2SV2<T2>& A1) 02251 : Pixels<T,3>() 02252 { 02253 const PixH2SV2<double> A( A1 ); 02254 const PixRGB<double> B( A ); 02255 const PixYIQ<double> C( B ); 02256 pix_helper::clamped_assign_3(*this, C); 02257 } 02258 02259 // ###################################################################### 02260 template <class T> 02261 template <class T2> inline PixYIQ<T>::PixYIQ(const PixH2SV3<T2>& A1) 02262 : Pixels<T,3>() 02263 { 02264 const PixH2SV3<double> A( A1 ); 02265 const PixRGB<double> B( A ); 02266 const PixYIQ<double> C( B ); 02267 pix_helper::clamped_assign_3(*this, C); 02268 } 02269 02270 // ###################################################################### 02271 template <class T> 02272 template <class T2> inline PixYIQ<T>::PixYIQ(const PixHyper<T2,3>& A) 02273 : Pixels<T,3>() 02274 { 02275 pix_helper::clamped_assign_3(*this, A); 02276 } 02277 02278 // ###################################################################### 02279 // Standard Constructors / Destructor 02280 // ###################################################################### 02281 02282 template <class T> 02283 inline PixYIQ<T>::PixYIQ() : Pixels<T,3>() 02284 {} 02285 02286 // ###################################################################### 02287 template <class T> 02288 inline PixYIQ<T>::~PixYIQ() 02289 {} 02290 02291 // ###################################################################### 02292 template <class T> 02293 inline PixYIQ<T>::PixYIQ(const T val) : Pixels<T,3>(val) 02294 {} 02295 02296 // ###################################################################### 02297 template <class T> 02298 inline PixYIQ<T>::PixYIQ(const PixYIQ<T>& pix) : Pixels<T,3>(pix) 02299 {} 02300 02301 // ###################################################################### 02302 // Special methods for this class 02303 // ###################################################################### 02304 02305 template <class T> 02306 inline void PixYIQ<T>::getYIQ(T& y, T& i, T& q) const 02307 { 02308 y = p[0]; i = p[1]; q = p[2]; 02309 } 02310 02311 // ###################################################################### 02312 template <class T> 02313 inline PixYIQ<T>::PixYIQ(const T Yval, const T Ival, const T Qval) : Pixels<T,3>() 02314 { 02315 p[0] = Yval; p[1] = Ival; p[2] = Qval; 02316 } 02317 02318 // ###################################################################### 02319 template <class T> template <class T2, class T3, class T4> inline 02320 PixYIQ<T>::PixYIQ(const T2 Yval, const T3 Ival, const T4 Qval) : Pixels<T,3>() 02321 { 02322 p[0] = clamped_convert<T>(Yval); 02323 p[1] = clamped_convert<T>(Ival); 02324 p[2] = clamped_convert<T>(Qval); 02325 } 02326 02327 // ###################################################################### 02328 template <class T> 02329 inline T PixYIQ<T>::Y() const 02330 { 02331 return p[0]; 02332 } 02333 02334 // ###################################################################### 02335 template <class T> 02336 inline T PixYIQ<T>::I() const 02337 { 02338 return p[1]; 02339 } 02340 02341 // ###################################################################### 02342 template <class T> 02343 inline T PixYIQ<T>::Q() const 02344 { 02345 return p[2]; 02346 } 02347 02348 // ###################################################################### 02349 template <class T> 02350 template <class T2> inline void PixYIQ<T>::setY(const T2 yy) 02351 { 02352 p[0] = clamped_convert<T>(yy); 02353 } 02354 02355 // ###################################################################### 02356 template <class T> 02357 template <class T2> inline void PixYIQ<T>::setI(const T2 ii) 02358 { 02359 p[1] = clamped_convert<T>(ii); 02360 } 02361 02362 // ###################################################################### 02363 template <class T> 02364 template <class T2> inline void PixYIQ<T>::setQ(const T2 qq) 02365 { 02366 p[2] = clamped_convert<T>(qq); 02367 } 02368 02369 02370 // ###################################################################### 02371 // ###################################################################### 02372 // Pixels HSL 02373 // ###################################################################### 02374 // ###################################################################### 02375 02376 // ###################################################################### 02377 // constructors for where Pix<T> != Pix<T2> - with conversion 02378 // ###################################################################### 02379 02380 template <class T> 02381 template <class T2> inline PixHSL<T>::PixHSL(const PixRGB<T2>& A1) 02382 : Pixels<T,3>() 02383 { 02384 const PixRGB<double> A( A1 ); 02385 02386 // p[0] = h : p[1] = s : p[2] = l 02387 // A[0] = r : A[1] = g : A[2] = b 02388 02389 const double R = A[0]/RGB_R_UPPER; 02390 const double G = A[1]/RGB_G_UPPER; 02391 const double B = A[2]/RGB_B_UPPER; 02392 02393 double h,s,l; 02394 02395 //Note: HSL is very much like HSV. For instance hue is computed in 02396 // exactly the same way. 02397 02398 if((B > G) && (B > R)) 02399 { 02400 const double max = B; 02401 double min; 02402 if(R > G) min = G; 02403 else min = R; 02404 const double posDelta = max + min; 02405 const double negDelta = max - min; 02406 l = posDelta/2; 02407 if(l > 0.5) s = negDelta/(2 - posDelta); 02408 else s = negDelta/posDelta; 02409 if(negDelta != 0) h = 4 + (R - G) / negDelta; 02410 else h = 4 + (R - G); 02411 h *= 60; if(h < 0) h += 360; 02412 } 02413 else if(G > R) 02414 { 02415 const double max = G; 02416 double min; 02417 if(R > B) min = B; 02418 else min = R; 02419 const double posDelta = max + min; 02420 const double negDelta = max - min; 02421 l = posDelta/2; 02422 if(l > 0.5) s = negDelta/(2 - posDelta); 02423 else s = negDelta/posDelta; 02424 if(negDelta != 0) h = 2 + (B - R) / negDelta; 02425 else h = 2 + (B - R); 02426 h *= 60; if(h < 0) h += 360; 02427 } 02428 else 02429 { 02430 const double max = R; 02431 double min; 02432 if(G > B) min = B; 02433 else min = G; 02434 const double posDelta = max + min; 02435 const double negDelta = max - min; 02436 l = posDelta/2; 02437 if(l > 0.5) s = negDelta/(2 - posDelta); 02438 else s = negDelta/posDelta; 02439 if(negDelta != 0) h = (G - B) / negDelta; 02440 else h = (G - B); 02441 h *= 60; if(h < 0) h += 360; 02442 } 02443 02444 p[0] = clamped_convert<T>(h); 02445 p[1] = clamped_convert<T>(s); 02446 p[2] = clamped_convert<T>(l); 02447 } 02448 02449 // ###################################################################### 02450 template <class T> 02451 template <class T2> inline PixHSL<T>::PixHSL(const PixHSV<T2>& A1) 02452 : Pixels<T,3>() 02453 { 02454 const PixHSV<double> A( A1 ); 02455 const PixRGB<double> B( A ); 02456 const PixHSL<double> C( B ); 02457 pix_helper::clamped_assign_3(*this, C); 02458 } 02459 02460 // ###################################################################### 02461 template <class T> 02462 template <class T2> inline PixHSL<T>::PixHSL(const PixYIQ<T2>& A1) 02463 : Pixels<T,3>() 02464 { 02465 const PixYIQ<double> A( A1 ); 02466 const PixRGB<double> B( A ); 02467 const PixHSL<double> C( B ); 02468 pix_helper::clamped_assign_3(*this, C); 02469 } 02470 02471 // ###################################################################### 02472 template <class T> 02473 template <class T2> inline PixHSL<T>::PixHSL(const PixHSL<T2>& A) 02474 : Pixels<T,3>() 02475 { 02476 pix_helper::clamped_assign_3(*this, A); 02477 } 02478 02479 // ###################################################################### 02480 template <class T> 02481 template <class T2> inline PixHSL<T>::PixHSL(const PixH2SV1<T2>& A1) 02482 : Pixels<T,3>() 02483 { 02484 const PixH2SV1<double> A( A1 ); 02485 // A[0] = H1, A[1] = H2 02486 02487 PIX_H2SV1_TO_HSV_SIMPLE_COMMON(A[0],A[1],p[0]) 02488 02489 p[1] = clamped_convert<T>(A[2]*HSL_S_UPPER); 02490 p[2] = clamped_convert<T>(A[3]*HSL_L_UPPER); 02491 } 02492 02493 // ###################################################################### 02494 template <class T> 02495 template <class T2> inline PixHSL<T>::PixHSL(const PixH2SV2<T2>& A1) 02496 : Pixels<T,3>() 02497 { 02498 const PixH2SV2<double> A( A1 ); 02499 02500 double h = 0; 02501 double sf = 0; 02502 02503 // SEE PixelsCommonDef.H 02504 PIX_H2SV2_TO_HSV_ROBUST_COMMON(A[0],A[1],A[2],p[0],sf) 02505 02506 p[1] = clamped_convert<T>(sf*HSL_S_UPPER); 02507 p[2] = clamped_convert<T>(A[3]*HSL_L_UPPER); 02508 } 02509 02510 // ###################################################################### 02511 template <class T> 02512 template <class T2> inline PixHSL<T>::PixHSL(const PixHyper<T2,3>& A) 02513 : Pixels<T,3>() 02514 { 02515 pix_helper::clamped_assign_3(*this, A); 02516 } 02517 02518 // ###################################################################### 02519 // Standard Constructors / Destrcutor 02520 // ###################################################################### 02521 02522 template <class T> 02523 inline PixHSL<T>::PixHSL() : Pixels<T,3>() 02524 {} 02525 02526 // ###################################################################### 02527 template <class T> 02528 inline PixHSL<T>::~PixHSL() 02529 {} 02530 02531 // ###################################################################### 02532 template <class T> 02533 inline PixHSL<T>::PixHSL(const T val) : Pixels<T,3>(val) 02534 {} 02535 02536 // ###################################################################### 02537 template <class T> 02538 inline PixHSL<T>::PixHSL(const PixHSL<T>& pix) : Pixels<T,3>(pix) 02539 {} 02540 02541 // ###################################################################### 02542 // Special methods for this class 02543 // ###################################################################### 02544 02545 template <class T> 02546 inline void PixHSL<T>::getHSL(T& h, T& s, T& l) const 02547 { 02548 h = p[0]; s = p[1]; l = p[2]; 02549 } 02550 02551 // ###################################################################### 02552 template <class T> 02553 inline PixHSL<T>::PixHSL(const T Hval, const T Sval, const T Lval) : Pixels<T,3>() 02554 { 02555 p[0] = Hval; p[1] = Sval; p[2] = Lval; 02556 } 02557 02558 // ###################################################################### 02559 template <class T> template <class T2, class T3, class T4> inline 02560 PixHSL<T>::PixHSL(const T2 Hval, const T3 Sval, const T4 Lval) : Pixels<T,3>() 02561 { 02562 p[0] = clamped_convert<T>(Hval); 02563 p[1] = clamped_convert<T>(Sval); 02564 p[2] = clamped_convert<T>(Lval); 02565 } 02566 02567 // ###################################################################### 02568 template <class T> 02569 inline T PixHSL<T>::H() const 02570 { 02571 return p[0]; 02572 } 02573 02574 // ###################################################################### 02575 template <class T> 02576 inline T PixHSL<T>::S() const 02577 { 02578 return p[1]; 02579 } 02580 02581 // ###################################################################### 02582 template <class T> 02583 inline T PixHSL<T>::L() const 02584 { 02585 return p[2]; 02586 } 02587 02588 // ###################################################################### 02589 template <class T> 02590 template <class T2> inline void PixHSL<T>::setH(const T2 hh) 02591 { 02592 p[0] = clamped_convert<T>(hh); 02593 } 02594 02595 // ###################################################################### 02596 template <class T> 02597 template <class T2> inline void PixHSL<T>::setS(const T2 ss) 02598 { 02599 p[1] = clamped_convert<T>(ss); 02600 } 02601 02602 // ###################################################################### 02603 template <class T> 02604 template <class T2> inline void PixHSL<T>::setL(const T2 ll) 02605 { 02606 p[2] = clamped_convert<T>(ll); 02607 } 02608 // ###################################################################### 02609 // ###################################################################### 02610 // Pixels Lab 02611 // ###################################################################### 02612 // ###################################################################### 02613 02614 // ###################################################################### 02615 // constructors for where Pix<T> != Pix<T2> - with conversion 02616 // ###################################################################### 02617 02618 template <class T> 02619 template <class T2> inline PixLab<T>::PixLab(const PixRGB<T2>& A1) 02620 : Pixels<T,3>() 02621 { 02622 const PixRGB<double> A( A1 ); 02623 02624 // p[0] = l : p[1] = a : p[2] = b 02625 // A[0] = r : A[1] = g : A[2] = b 02626 02627 double X,Y,Z,L,a,b; 02628 02629 // SEE PixelsCommonDef.H 02630 PIX_RGB_TO_XYZ_OPENCV_COMMON(A[0],A[1],A[2],X,Y,Z) 02631 // SEE PixelsCommonDef.H 02632 PIX_XYZ_TO_LAB_OPENCV_COMMON(X,Y,Z,L,a,b) 02633 //PIX_XYZ_TO_LAB_AUGMENT_COMMON(X,Y,Z,L,a,b) 02634 02635 p[0] = clamped_convert<T>(L); 02636 p[1] = clamped_convert<T>(a); 02637 p[2] = clamped_convert<T>(b); 02638 } 02639 02640 // ###################################################################### 02641 template <class T> 02642 template <class T2> inline PixLab<T>::PixLab(const PixLab<T2>& A) 02643 : Pixels<T,3>() 02644 { 02645 pix_helper::clamped_assign_3(*this, A); 02646 } 02647 02648 // ###################################################################### 02649 template <class T> 02650 template <class T2> inline PixLab<T>::PixLab(const PixHyper<T2,3>& A) 02651 : Pixels<T,3>() 02652 { 02653 pix_helper::clamped_assign_3(*this, A); 02654 } 02655 02656 // ###################################################################### 02657 // Standard Constructors / Destrcutor 02658 // ###################################################################### 02659 02660 template <class T> 02661 inline PixLab<T>::PixLab() : Pixels<T,3>() 02662 {} 02663 02664 // ###################################################################### 02665 template <class T> 02666 inline PixLab<T>::~PixLab() 02667 {} 02668 02669 // ###################################################################### 02670 template <class T> 02671 inline PixLab<T>::PixLab(const T val) : Pixels<T,3>(val) 02672 {} 02673 02674 // ###################################################################### 02675 template <class T> 02676 inline PixLab<T>::PixLab(const PixLab<T>& pix) : Pixels<T,3>(pix) 02677 {} 02678 02679 // ###################################################################### 02680 // Special methods for this class 02681 // ###################################################################### 02682 02683 template <class T> 02684 inline void PixLab<T>::getLab(T& l, T& a, T& b) const 02685 { 02686 l = p[0]; a = p[1]; b = p[2]; 02687 } 02688 02689 // ###################################################################### 02690 template <class T> 02691 inline PixLab<T>::PixLab(const T Lval, const T Aval, const T Bval) : Pixels<T,3>() 02692 { 02693 p[0] = Lval; p[1] = Aval; p[2] = Bval; 02694 } 02695 02696 // ###################################################################### 02697 template <class T> template <class T2, class T3, class T4> inline 02698 PixLab<T>::PixLab(const T2 Lval, const T3 Aval, const T4 Bval) : Pixels<T,3>() 02699 { 02700 p[0] = clamped_convert<T>(Lval); 02701 p[1] = clamped_convert<T>(Aval); 02702 p[2] = clamped_convert<T>(Bval); 02703 } 02704 02705 // ###################################################################### 02706 template <class T> 02707 inline T PixLab<T>::L() const 02708 { 02709 return p[0]; 02710 } 02711 02712 // ###################################################################### 02713 template <class T> 02714 inline T PixLab<T>::A() const 02715 { 02716 return p[1]; 02717 } 02718 02719 // ###################################################################### 02720 template <class T> 02721 inline T PixLab<T>::B() const 02722 { 02723 return p[2]; 02724 } 02725 02726 // ###################################################################### 02727 template <class T> 02728 template <class T2> inline void PixLab<T>::setL(const T2 L) 02729 { 02730 p[0] = clamped_convert<T>(L); 02731 } 02732 02733 // ###################################################################### 02734 template <class T> 02735 template <class T2> inline void PixLab<T>::setA(const T2 A) 02736 { 02737 p[1] = clamped_convert<T>(A); 02738 } 02739 02740 // ###################################################################### 02741 template <class T> 02742 template <class T2> inline void PixLab<T>::setB(const T2 B) 02743 { 02744 p[2] = clamped_convert<T>(B); 02745 } 02746 02747 // ###################################################################### 02748 // ###################################################################### 02749 // Pixels XYZ 02750 // ###################################################################### 02751 // ###################################################################### 02752 02753 // ###################################################################### 02754 // constructors for where Pix<T> != Pix<T2> - with conversion 02755 // ###################################################################### 02756 02757 template <class T> 02758 template <class T2> inline PixXYZ<T>::PixXYZ(const PixRGB<T2>& A1) 02759 : Pixels<T,3>() 02760 { 02761 const PixRGB<double> A( A1 ); 02762 02763 // p[0] = l : p[1] = a : p[2] = b 02764 // A[0] = r : A[1] = g : A[2] = b 02765 02766 double X,Y,Z; 02767 02768 // SEE PixelsCommonDef.H 02769 PIX_RGB_TO_XYZ_OPENCV_COMMON(A[0],A[1],A[2],X,Y,Z) 02770 02771 p[0] = clamped_convert<T>(X); 02772 p[1] = clamped_convert<T>(Y); 02773 p[2] = clamped_convert<T>(Z); 02774 } 02775 02776 // ###################################################################### 02777 template <class T> 02778 template <class T2> inline PixXYZ<T>::PixXYZ(const PixXYZ<T2>& A) 02779 : Pixels<T,3>() 02780 { 02781 pix_helper::clamped_assign_3(*this, A); 02782 } 02783 02784 // ###################################################################### 02785 template <class T> 02786 template <class T2> inline PixXYZ<T>::PixXYZ(const PixHyper<T2,3>& A) 02787 : Pixels<T,3>() 02788 { 02789 pix_helper::clamped_assign_3(*this, A); 02790 } 02791 02792 // ###################################################################### 02793 // Standard Constructors / Destrcutor 02794 // ###################################################################### 02795 02796 template <class T> 02797 inline PixXYZ<T>::PixXYZ() : Pixels<T,3>() 02798 {} 02799 02800 // ###################################################################### 02801 template <class T> 02802 inline PixXYZ<T>::~PixXYZ() 02803 {} 02804 02805 // ###################################################################### 02806 template <class T> 02807 inline PixXYZ<T>::PixXYZ(const T val) : Pixels<T,3>(val) 02808 {} 02809 02810 // ###################################################################### 02811 template <class T> 02812 inline PixXYZ<T>::PixXYZ(const PixXYZ<T>& pix) : Pixels<T,3>(pix) 02813 {} 02814 02815 // ###################################################################### 02816 // Special methods for this class 02817 // ###################################################################### 02818 02819 template <class T> 02820 inline void PixXYZ<T>::getXYZ(T& x, T& y, T& z) const 02821 { 02822 x = p[0]; y = p[1]; z = p[2]; 02823 } 02824 02825 // ###################################################################### 02826 template <class T> 02827 inline PixXYZ<T>::PixXYZ(const T Xval, const T Yval, const T Zval) : Pixels<T,3>() 02828 { 02829 p[0] = Xval; p[1] = Yval; p[2] = Zval; 02830 } 02831 02832 // ###################################################################### 02833 template <class T> template <class T2, class T3, class T4> inline 02834 PixXYZ<T>::PixXYZ(const T2 Xval, const T3 Yval, const T4 Zval) : Pixels<T,3>() 02835 { 02836 p[0] = clamped_convert<T>(Xval); 02837 p[1] = clamped_convert<T>(Yval); 02838 p[2] = clamped_convert<T>(Zval); 02839 } 02840 02841 // ###################################################################### 02842 template <class T> 02843 inline T PixXYZ<T>::X() const 02844 { 02845 return p[0]; 02846 } 02847 02848 // ###################################################################### 02849 template <class T> 02850 inline T PixXYZ<T>::Y() const 02851 { 02852 return p[1]; 02853 } 02854 02855 // ###################################################################### 02856 template <class T> 02857 inline T PixXYZ<T>::Z() const 02858 { 02859 return p[2]; 02860 } 02861 02862 // ###################################################################### 02863 template <class T> 02864 template <class T2> inline void PixXYZ<T>::setX(const T2 X) 02865 { 02866 p[0] = clamped_convert<T>(X); 02867 } 02868 02869 // ###################################################################### 02870 template <class T> 02871 template <class T2> inline void PixXYZ<T>::setY(const T2 Y) 02872 { 02873 p[1] = clamped_convert<T>(Y); 02874 } 02875 02876 // ###################################################################### 02877 template <class T> 02878 template <class T2> inline void PixXYZ<T>::setZ(const T2 Z) 02879 { 02880 p[2] = clamped_convert<T>(Z); 02881 } 02882 02883 // ###################################################################### 02884 // ###################################################################### 02885 // Pixels H2SV1 02886 // ###################################################################### 02887 // ###################################################################### 02888 02889 // ###################################################################### 02890 // constructors for where Pix<T> != Pix<T2> - with conversion 02891 // ###################################################################### 02892 02893 template <class T> 02894 template <class T2> inline PixH2SV1<T>::PixH2SV1(const PixRGB<T2>& A1) 02895 : Pixels<T,4>() 02896 { 02897 const PixRGB<double> A( A1 ); 02898 02899 // p[0] = h1 : p[1] = h2 : p[2] = s : p[3] = v 02900 // A[0] = r : A[1] = g : A[2] = b 02901 02902 double h = 0; 02903 02904 // SEE PixelsCommonDef.H 02905 PIX_RGB_TO_HSV_COMMON(A[0],A[1],A[2],h,p[2],p[3],false) 02906 // SEE PixelsCommonDef.H 02907 PIX_HSV_TO_H2SV1_COMMON(h,p[2],p[0],p[1]) 02908 02909 } 02910 02911 // ###################################################################### 02912 template <class T> 02913 template <class T2> inline PixH2SV1<T>::PixH2SV1(const PixHSV<T2>& A1) 02914 : Pixels<T,4>() 02915 { 02916 const PixHSV<double> A( A1 ); 02917 02918 // p[0] = h1 : p[1] = h2 : p[2] = s : p[3] = v 02919 // A[0] = h : A[1] = s : A[2] = v 02920 02921 // demoduloize hue into two components 02922 02923 // SEE PixelsCommonDef.H 02924 PIX_HSV_TO_H2SV1_COMMON(A[0],A[1],p[0],p[1]) 02925 02926 p[2] = clamped_convert<T>(A[1]/HSV_S_UPPER); 02927 p[3] = clamped_convert<T>(A[2]/HSV_V_UPPER); 02928 } 02929 02930 // ###################################################################### 02931 template <class T> 02932 template <class T2> inline PixH2SV1<T>::PixH2SV1(const PixYIQ<T2>& A1) 02933 : Pixels<T,4>() 02934 { 02935 const PixYIQ<double> A( A1 ); 02936 const PixRGB<double> B( A ); 02937 const PixH2SV1<double> C( B ); 02938 pix_helper::clamped_assign_4(*this, C); 02939 } 02940 02941 // ###################################################################### 02942 template <class T> 02943 template <class T2> inline PixH2SV1<T>::PixH2SV1(const PixHSL<T2>& A1) 02944 : Pixels<T,4>() 02945 { 02946 const PixHSL<double> A( A1 ); 02947 02948 // p[0] = h1 : p[1] = h2 : p[2] = s : p[3] = v 02949 // A[0] = h : A[1] = s : A[2] = l 02950 02951 // demoduloize hue into two components 02952 02953 // SEE PixelsCommonDef.H 02954 PIX_HSV_TO_H2SV1_COMMON(A[0],A[1],p[0],p[1]) 02955 02956 p[2] = clamped_convert<T>(A[1]/HSL_S_UPPER); 02957 p[3] = clamped_convert<T>(A[2]/HSL_L_UPPER); 02958 } 02959 02960 // ###################################################################### 02961 template <class T> 02962 template <class T2> inline PixH2SV1<T>::PixH2SV1(const PixH2SV1<T2>& A) 02963 : Pixels<T,4>() 02964 { 02965 pix_helper::clamped_assign_4(*this, A); 02966 } 02967 02968 // ###################################################################### 02969 template <class T> 02970 template <class T2> inline PixH2SV1<T>::PixH2SV1(const PixH2SV2<T2>& A1) 02971 : Pixels<T,4>() 02972 { 02973 const PixH2SV2<double> A( A1 ); 02974 const PixRGB<double> B( A ); 02975 const PixH2SV1<double> C( B ); 02976 pix_helper::clamped_assign_4(*this, C); 02977 } 02978 02979 // ###################################################################### 02980 template <class T> 02981 template <class T2> inline PixH2SV1<T>::PixH2SV1(const PixH2SV3<T2>& A1) 02982 : Pixels<T,4>() 02983 { 02984 const PixH2SV3<double> A( A1 ); 02985 const PixRGB<double> B( A ); 02986 const PixH2SV1<double> C( B ); 02987 pix_helper::clamped_assign_4(*this, C); 02988 } 02989 02990 // ###################################################################### 02991 template <class T> 02992 template <class T2> inline PixH2SV1<T>::PixH2SV1(const PixHyper<T2,4>& A) 02993 : Pixels<T,4>() 02994 { 02995 pix_helper::clamped_assign_4(*this, A); 02996 } 02997 02998 // ###################################################################### 02999 // Standard Constructors / Destructor 03000 // ###################################################################### 03001 03002 template <class T> 03003 inline PixH2SV1<T>::PixH2SV1() : Pixels<T,4>() 03004 {} 03005 03006 // ###################################################################### 03007 template <class T> 03008 inline PixH2SV1<T>::~PixH2SV1() 03009 {} 03010 03011 // ###################################################################### 03012 template <class T> 03013 inline PixH2SV1<T>::PixH2SV1(T val) : Pixels<T,4>(val) 03014 {} 03015 03016 // ###################################################################### 03017 template <class T> 03018 inline PixH2SV1<T>::PixH2SV1(const PixH2SV1<T>& pix) : Pixels<T,4>(pix) 03019 {} 03020 03021 03022 // ###################################################################### 03023 // Special methods for this class 03024 // ###################################################################### 03025 03026 template <class T> 03027 inline void PixH2SV1<T>::getH2SV1(T& h1, T& h2, T& s, T& v) const 03028 { 03029 h1 = p[0]; h2 = p[1]; s = p[2]; v = p[3]; 03030 } 03031 03032 // ###################################################################### 03033 template <class T> 03034 inline PixH2SV1<T>::PixH2SV1(const T H1val, const T H2val, const T Sval, const T Vval) : Pixels<T,4>() 03035 { 03036 p[0] = H1val; p[1] = H2val; p[2] = Sval; p[3] = Vval; 03037 } 03038 03039 // ###################################################################### 03040 template <class T> 03041 template <class T2, class T3, class T4, class T5> inline 03042 PixH2SV1<T>::PixH2SV1(const T2 H1val, const T3 H2val, const T4 Sval, const T5 Vval ) : Pixels<T,4>() 03043 { 03044 p[0] = clamped_convert<T>(H1val); 03045 p[1] = clamped_convert<T>(H2val); 03046 p[2] = clamped_convert<T>(Sval); 03047 p[3] = clamped_convert<T>(Vval); 03048 } 03049 03050 // ###################################################################### 03051 template <class T> 03052 inline T PixH2SV1<T>::H1() const 03053 { 03054 return p[0]; 03055 } 03056 03057 // ###################################################################### 03058 template <class T> 03059 inline T PixH2SV1<T>::H2() const 03060 { 03061 return p[1]; 03062 } 03063 03064 // ###################################################################### 03065 template <class T> 03066 inline T PixH2SV1<T>::S() const 03067 { 03068 return p[2]; 03069 } 03070 03071 // ###################################################################### 03072 template <class T> 03073 inline T PixH2SV1<T>::V() const 03074 { 03075 return p[3]; 03076 } 03077 03078 // ###################################################################### 03079 template <class T> 03080 template <class T2> inline void PixH2SV1<T>::setH1(const T2 hh1) 03081 { 03082 p[0] = clamped_convert<T>(hh1); 03083 } 03084 // ###################################################################### 03085 template <class T> 03086 template <class T2> inline void PixH2SV1<T>::setH2(const T2 hh2) 03087 { 03088 p[1] = clamped_convert<T>(hh2); 03089 } 03090 // ###################################################################### 03091 template <class T> 03092 template <class T2> inline void PixH2SV1<T>::setS(const T2 ss) 03093 { 03094 p[2] = clamped_convert<T>(ss); 03095 } 03096 // ###################################################################### 03097 template <class T> 03098 template <class T2> inline void PixH2SV1<T>::setV(const T2 vv) 03099 { 03100 p[3] = clamped_convert<T>(vv); 03101 } 03102 03103 // ###################################################################### 03104 // ###################################################################### 03105 // Pixels H2SV2 03106 // ###################################################################### 03107 // ###################################################################### 03108 03109 // ###################################################################### 03110 // constructors for where Pix<T> != Pix<T2> - with conversion 03111 // ###################################################################### 03112 03113 template <class T> 03114 template <class T2> inline PixH2SV2<T>::PixH2SV2(const PixRGB<T2>& A1) 03115 : Pixels<T,4>() 03116 { 03117 03118 const PixRGB<double> A( A1 ); 03119 03120 // p[0] = h1 : p[1] = h2 : p[2] = s : p[3] = v 03121 // A[0] = r : A[1] = g : A[2] = b 03122 double h = 0; 03123 03124 // SEE PixelsCommonDef.H 03125 PIX_RGB_TO_HSV_COMMON(A[0],A[1],A[2],h,p[2],p[3],false) 03126 // SEE PixelsCommonDef.H 03127 PIX_HSV_TO_H2SV2_COMMON(h,p[2],p[0],p[1]) 03128 } 03129 03130 // ###################################################################### 03131 template <class T> 03132 template <class T2> inline PixH2SV2<T>::PixH2SV2(const PixHSV<T2>& A1) 03133 : Pixels<T,4>() 03134 { 03135 const PixH2SV2<double> A( A1 ); 03136 03137 // p[0] = h1 : p[1] = h2 : p[2] = s : p[3] = v 03138 // A[0] = h : A[1] = s : A[2] = v 03139 03140 // demoduloize hue into two components B/Y and R/G like 03141 03142 // SEE PixelsCommonDef.H 03143 PIX_HSV_TO_H2SV2_COMMON(A[0],A[1],p[0],p[1]) 03144 03145 p[2] = clamped_convert<T>(A[1]/HSV_S_UPPER); 03146 p[3] = clamped_convert<T>(A[2]/HSV_V_UPPER); 03147 } 03148 03149 // ###################################################################### 03150 template <class T> 03151 template <class T2> inline PixH2SV2<T>::PixH2SV2(const PixYIQ<T2>& A1) 03152 : Pixels<T,4>() 03153 { 03154 const PixYIQ<double> A( A1 ); 03155 const PixRGB<double> B( A ); 03156 const PixH2SV2<double> C( B ); // FIXME shouldn't this be PixH2SV2??? 03157 pix_helper::clamped_assign_4(*this, C); 03158 } 03159 03160 // ###################################################################### 03161 template <class T> 03162 template <class T2> inline PixH2SV2<T>::PixH2SV2(const PixHSL<T2>& A1) 03163 : Pixels<T,4>() 03164 { 03165 const PixH2SV2<double> A( A1 ); 03166 03167 // p[0] = h1 : p[1] = h2 : p[2] = s : p[3] = v 03168 // A[0] = h : A[1] = s : A[2] = l 03169 03170 // demoduloize hue into two components B/Y and R/G like 03171 03172 // SEE PixelsCommonDef.H 03173 PIX_HSV_TO_H2SV2_COMMON(A[0],A[1],p[0],p[1]) 03174 03175 p[2] = clamped_convert<T>(A[1]/HSL_S_UPPER); 03176 p[3] = clamped_convert<T>(A[2]/HSL_L_UPPER); 03177 } 03178 03179 // ###################################################################### 03180 template <class T> 03181 template <class T2> inline PixH2SV2<T>::PixH2SV2(const PixH2SV1<T2>& A1) 03182 : Pixels<T,4>() 03183 { 03184 const PixH2SV1<double> A( A1 ); 03185 const PixRGB<double> B( A ); 03186 const PixH2SV2<double> C( B ); // FIXME shouldn't this be PixH2SV2??? 03187 pix_helper::clamped_assign_4(*this, C); 03188 } 03189 03190 // ###################################################################### 03191 template <class T> 03192 template <class T2> inline PixH2SV2<T>::PixH2SV2(const PixH2SV2<T2>& A) 03193 : Pixels<T,4>() 03194 { 03195 pix_helper::clamped_assign_4(*this, A); 03196 } 03197 03198 // ###################################################################### 03199 template <class T> 03200 template <class T2> inline PixH2SV2<T>::PixH2SV2(const PixH2SV3<T2>& A1) 03201 : Pixels<T,4>() 03202 { 03203 const PixH2SV3<double> A( A1 ); 03204 const PixRGB<double> B( A ); 03205 const PixH2SV2<double> C( B ); // FIXME shouldn't this be PixH2SV2??? 03206 pix_helper::clamped_assign_4(*this, C); 03207 } 03208 03209 // ###################################################################### 03210 template <class T> 03211 template <class T2> inline PixH2SV2<T>::PixH2SV2(const PixHyper<T2,4>& A) 03212 : Pixels<T,4>() 03213 { 03214 pix_helper::clamped_assign_4(*this, A); 03215 } 03216 03217 // ###################################################################### 03218 // Standard Constructors / Destructor 03219 // ###################################################################### 03220 03221 template <class T> 03222 inline PixH2SV2<T>::PixH2SV2() : Pixels<T,4>() 03223 {} 03224 03225 // ###################################################################### 03226 template <class T> 03227 inline PixH2SV2<T>::~PixH2SV2() 03228 {} 03229 03230 // ###################################################################### 03231 template <class T> 03232 inline PixH2SV2<T>::PixH2SV2(const T val) : Pixels<T,4>(val) 03233 {} 03234 03235 // ###################################################################### 03236 template <class T> 03237 inline PixH2SV2<T>::PixH2SV2(const PixH2SV2<T>& pix) : Pixels<T,4>(pix) 03238 {} 03239 03240 // ###################################################################### 03241 // Special methods for this class 03242 // ###################################################################### 03243 03244 template <class T> 03245 inline void PixH2SV2<T>::getH2SV2(T& h1, T& h2, T& s, T& v) const 03246 { 03247 h1 = p[0]; h2 = p[1]; s = p[2]; v = p[3]; 03248 } 03249 03250 template <class T> 03251 inline PixH2SV2<T>::PixH2SV2(const T H1val, const T H2val, const T Sval, const T Vval) : Pixels<T,4>() 03252 { 03253 p[0] = H1val; p[1] = H2val; p[2] = Sval; p[3] = Vval; 03254 } 03255 03256 // ###################################################################### 03257 template <class T> template <class T2, class T3, class T4, class T5> inline 03258 PixH2SV2<T>::PixH2SV2(const T2 H1val, const T3 H2val, const T4 Sval, const T5 Vval ) : Pixels<T,4>() 03259 { 03260 p[0] = clamped_convert<T>(H1val); 03261 p[1] = clamped_convert<T>(H2val); 03262 p[2] = clamped_convert<T>(Sval); 03263 p[3] = clamped_convert<T>(Vval); 03264 } 03265 03266 // ###################################################################### 03267 template <class T> 03268 inline T PixH2SV2<T>::H1() const 03269 { 03270 return p[0]; 03271 } 03272 03273 // ###################################################################### 03274 template <class T> 03275 inline T PixH2SV2<T>::H2() const 03276 { 03277 return p[1]; 03278 } 03279 03280 // ###################################################################### 03281 template <class T> 03282 inline T PixH2SV2<T>::S() const 03283 { 03284 return p[2]; 03285 } 03286 03287 // ###################################################################### 03288 template <class T> 03289 inline T PixH2SV2<T>::V() const 03290 { 03291 return p[3]; 03292 } 03293 03294 // ###################################################################### 03295 template <class T> 03296 template <class T2> inline void PixH2SV2<T>::setH1(const T2 hh1) 03297 { 03298 p[0] = clamped_convert<T>(hh1); 03299 } 03300 // ###################################################################### 03301 template <class T> 03302 template <class T2> inline void PixH2SV2<T>::setH2(const T2 hh2) 03303 { 03304 p[1] = clamped_convert<T>(hh2); 03305 } 03306 // ###################################################################### 03307 template <class T> 03308 template <class T2> inline void PixH2SV2<T>::setS(const T2 ss) 03309 { 03310 p[2] = clamped_convert<T>(ss); 03311 } 03312 // ###################################################################### 03313 template <class T> 03314 template <class T2> inline void PixH2SV2<T>::setV(const T2 vv) 03315 { 03316 p[3] = clamped_convert<T>(vv); 03317 } 03318 03319 // ###################################################################### 03320 // ###################################################################### 03321 // Pixels H2SV3 03322 // ###################################################################### 03323 // ###################################################################### 03324 03325 // ###################################################################### 03326 // constructors for where Pix<T> != Pix<T2> - with conversion 03327 // ###################################################################### 03328 03329 // ###################################################################### 03330 template <class T> 03331 template <class T2> inline PixH2SV3<T>::PixH2SV3(const PixYIQ<T2>& A1) 03332 : Pixels<T,4>() 03333 { 03334 const PixYIQ<double> A( A1 ); 03335 const PixRGB<double> B( A ); 03336 const PixH2SV3<double> C( B ); 03337 pix_helper::clamped_assign_4(*this, C); 03338 } 03339 03340 // ###################################################################### 03341 template <class T> 03342 template <class T2> inline PixH2SV3<T>::PixH2SV3(const PixH2SV1<T2>& A1) 03343 : Pixels<T,4>() 03344 { 03345 const PixH2SV1<double> A( A1 ); 03346 const PixRGB<double> B( A ); 03347 const PixH2SV3<double> C( B ); 03348 pix_helper::clamped_assign_4(*this, C); 03349 } 03350 03351 // ###################################################################### 03352 template <class T> 03353 template <class T2> inline PixH2SV3<T>::PixH2SV3(const PixH2SV2<T2>& A1) 03354 : Pixels<T,4>() 03355 { 03356 const PixH2SV2<double> A( A1 ); 03357 const PixRGB<double> B( A ); 03358 const PixH2SV3<double> C( B ); 03359 pix_helper::clamped_assign_4(*this, C); 03360 } 03361 03362 // ###################################################################### 03363 template <class T> 03364 template <class T2> inline PixH2SV3<T>::PixH2SV3(const PixH2SV3<T2>& A) 03365 : Pixels<T,4>() 03366 { 03367 pix_helper::clamped_assign_4(*this, A); 03368 } 03369 03370 // ###################################################################### 03371 template <class T> 03372 template <class T2> inline PixH2SV3<T>::PixH2SV3(const PixHyper<T2,4>& A) 03373 : Pixels<T,4>() 03374 { 03375 pix_helper::clamped_assign_4(*this, A); 03376 } 03377 03378 // ###################################################################### 03379 // Standard Constructors / Destructor 03380 // ###################################################################### 03381 03382 template <class T> 03383 inline PixH2SV3<T>::PixH2SV3() : Pixels<T,4>() 03384 {} 03385 03386 // ###################################################################### 03387 template <class T> 03388 inline PixH2SV3<T>::~PixH2SV3() 03389 {} 03390 03391 // ###################################################################### 03392 template <class T> 03393 inline PixH2SV3<T>::PixH2SV3(const T val) : Pixels<T,4>(val) 03394 {} 03395 03396 // ###################################################################### 03397 template <class T> 03398 inline PixH2SV3<T>::PixH2SV3(const PixH2SV3<T>& pix) : Pixels<T,4>(pix) 03399 {} 03400 03401 // ###################################################################### 03402 // Special methods for this class 03403 // ###################################################################### 03404 03405 template <class T> 03406 inline void PixH2SV3<T>::getH2SV3(T& h1, T& h2, T& s, T& v) const 03407 { 03408 h1 = p[0]; h2 = p[1]; s = p[2]; v = p[3]; 03409 } 03410 03411 template <class T> 03412 inline PixH2SV3<T>::PixH2SV3(const T H1val, const T H2val, const T Sval, const T Vval) : Pixels<T,4>() 03413 { 03414 p[0] = H1val; p[1] = H2val; p[2] = Sval; p[3] = Vval; 03415 } 03416 03417 // ###################################################################### 03418 template <class T> template <class T2, class T3, class T4, class T5> inline 03419 PixH2SV3<T>::PixH2SV3(const T2 H1val, const T3 H2val, const T4 Sval, const T5 Vval ) : Pixels<T,4>() 03420 { 03421 p[0] = clamped_convert<T>(H1val); 03422 p[1] = clamped_convert<T>(H2val); 03423 p[2] = clamped_convert<T>(Sval); 03424 p[3] = clamped_convert<T>(Vval); 03425 } 03426 03427 // ###################################################################### 03428 template <class T> 03429 inline T PixH2SV3<T>::H1() const 03430 { 03431 return p[0]; 03432 } 03433 03434 // ###################################################################### 03435 template <class T> 03436 inline T PixH2SV3<T>::H2() const 03437 { 03438 return p[1]; 03439 } 03440 03441 // ###################################################################### 03442 template <class T> 03443 inline T PixH2SV3<T>::S() const 03444 { 03445 return p[2]; 03446 } 03447 03448 // ###################################################################### 03449 template <class T> 03450 inline T PixH2SV3<T>::V() const 03451 { 03452 return p[3]; 03453 } 03454 03455 // ###################################################################### 03456 template <class T> 03457 template <class T2> inline void PixH2SV3<T>::setH1(const T2 hh1) 03458 { 03459 p[0] = clamped_convert<T>(hh1); 03460 } 03461 // ###################################################################### 03462 template <class T> 03463 template <class T2> inline void PixH2SV3<T>::setH2(const T2 hh2) 03464 { 03465 p[1] = clamped_convert<T>(hh2); 03466 } 03467 // ###################################################################### 03468 template <class T> 03469 template <class T2> inline void PixH2SV3<T>::setS(const T2 ss) 03470 { 03471 p[2] = clamped_convert<T>(ss); 03472 } 03473 // ###################################################################### 03474 template <class T> 03475 template <class T2> inline void PixH2SV3<T>::setV(const T2 vv) 03476 { 03477 p[3] = clamped_convert<T>(vv); 03478 } 03479 03480 // ###################################################################### 03481 // ###################################################################### 03482 // Pixels Hyper 03483 // ###################################################################### 03484 // ###################################################################### 03485 03486 // ###################################################################### 03487 // constructors for where Pix<T> != Pix<T2> - with conversion 03488 // ###################################################################### 03489 03490 template <class T, size_t dim> 03491 template <class T2> inline PixHyper<T,dim>::PixHyper(const PixRGB<T2>& A) 03492 : Pixels<T,dim>() 03493 { 03494 pix_helper::clamped_assign_3(*this, A); 03495 } 03496 03497 // ###################################################################### 03498 template <class T, size_t dim> 03499 template <class T2> inline PixHyper<T,dim>::PixHyper(const PixHSV<T2>& A) 03500 : Pixels<T,dim>() 03501 { 03502 pix_helper::clamped_assign_3(*this, A); 03503 } 03504 03505 // ###################################################################### 03506 template <class T, size_t dim> 03507 template <class T2> inline PixHyper<T,dim>::PixHyper(const PixJpegYUV<T2>& A) 03508 : Pixels<T,dim>() 03509 { 03510 pix_helper::clamped_assign_3(*this, A); 03511 } 03512 03513 // ###################################################################### 03514 template <class T, size_t dim> 03515 template <class T2> inline PixHyper<T,dim>::PixHyper(const PixVideoYUV<T2>& A) 03516 : Pixels<T,dim>() 03517 { 03518 pix_helper::clamped_assign_3(*this, A); 03519 } 03520 03521 // ###################################################################### 03522 template <class T, size_t dim> 03523 template <class T2> inline PixHyper<T,dim>::PixHyper(const PixYIQ<T2>& A) 03524 : Pixels<T,dim>() 03525 { 03526 pix_helper::clamped_assign_3(*this, A); 03527 } 03528 03529 // ###################################################################### 03530 template <class T, size_t dim> 03531 template <class T2> inline PixHyper<T,dim>::PixHyper(const PixHSL<T2>& A) 03532 : Pixels<T,dim>() 03533 { 03534 pix_helper::clamped_assign_3(*this, A); 03535 } 03536 03537 // ###################################################################### 03538 template <class T, size_t dim> 03539 template <class T2> inline PixHyper<T,dim>::PixHyper(const PixH2SV1<T2>& A) 03540 : Pixels<T,dim>() 03541 { 03542 pix_helper::clamped_assign_4(*this, A); 03543 } 03544 03545 // ###################################################################### 03546 template <class T, size_t dim> 03547 template <class T2> inline PixHyper<T,dim>::PixHyper(const PixH2SV2<T2>& A) 03548 : Pixels<T,dim>() 03549 { 03550 pix_helper::clamped_assign_4(*this, A); 03551 } 03552 03553 // ###################################################################### 03554 template <class T, size_t dim> 03555 template <class T2> inline PixHyper<T,dim>::PixHyper(const PixH2SV3<T2>& A) 03556 : Pixels<T,dim>() 03557 { 03558 pix_helper::clamped_assign_4(*this, A); 03559 } 03560 03561 // ###################################################################### 03562 template <class T, size_t dim> 03563 template <class T2> inline PixHyper<T,dim>::PixHyper(const PixHyper<T2,dim>& A) 03564 : Pixels<T,dim>() 03565 { 03566 pix_helper::clamped_assign_n(*this, A); 03567 } 03568 03569 // ###################################################################### 03570 // Standard Constructors / Destructor 03571 // ###################################################################### 03572 03573 template <class T, size_t dim> 03574 inline PixHyper<T,dim>::PixHyper() : Pixels<T,dim>() 03575 {} 03576 03577 // ###################################################################### 03578 template <class T, size_t dim> 03579 inline PixHyper<T,dim>::~PixHyper() 03580 {} 03581 03582 // ###################################################################### 03583 template <class T, size_t dim> 03584 inline PixHyper<T,dim>::PixHyper(const T val) : Pixels<T,dim>(val) 03585 {} 03586 03587 // ###################################################################### 03588 template <class T, size_t dim> 03589 inline PixHyper<T,dim>::PixHyper(const PixHyper<T,dim>& pix) : Pixels<T,dim>(pix) 03590 {} 03591 03592 03593 // ###################################################################### 03594 // ###################################################################### 03595 // Pixels DKL 03596 // ###################################################################### 03597 // ###################################################################### 03598 03599 template <class T> 03600 template <class T2> inline PixDKL<T>::PixDKL(const PixRGB<T2>& A1) 03601 : Pixels<T,3>() 03602 { 03603 // bunch of constants used for RGB -> DKL conversion: 03604 static const double lut_rgb[256*3] = { 03605 0.024935, 0.0076954, 0.042291, 03606 0.024974, 0.0077395, 0.042346, 03607 0.025013, 0.0077836, 0.042401, 03608 0.025052, 0.0078277, 0.042456, 03609 0.025091, 0.0078717, 0.042511, 03610 0.02513, 0.0079158, 0.042566, 03611 0.025234, 0.007992, 0.042621, 03612 0.025338, 0.0080681, 0.042676, 03613 0.025442, 0.0081443, 0.042731, 03614 0.025545, 0.0082204, 0.042786, 03615 0.025649, 0.0082966, 0.042841, 03616 0.025747, 0.0084168, 0.042952, 03617 0.025844, 0.0085371, 0.043062, 03618 0.025942, 0.0086573, 0.043172, 03619 0.026039, 0.0087776, 0.043282, 03620 0.026136, 0.0088978, 0.043392, 03621 0.026234, 0.0090581, 0.043502, 03622 0.026331, 0.0092184, 0.043612, 03623 0.026429, 0.0093788, 0.043722, 03624 0.026526, 0.0095391, 0.043833, 03625 0.026623, 0.0096994, 0.043943, 03626 0.026818, 0.0099198, 0.044141, 03627 0.027013, 0.01014, 0.044339, 03628 0.027208, 0.010361, 0.044537, 03629 0.027403, 0.010581, 0.044736, 03630 0.027597, 0.010802, 0.044934, 03631 0.027857, 0.010994, 0.04522, 03632 0.028117, 0.011186, 0.045507, 03633 0.028377, 0.011379, 0.045793, 03634 0.028636, 0.011571, 0.046079, 03635 0.028896, 0.011764, 0.046366, 03636 0.029104, 0.012068, 0.046652, 03637 0.029312, 0.012373, 0.046938, 03638 0.029519, 0.012677, 0.047225, 03639 0.029727, 0.012982, 0.047511, 03640 0.029935, 0.013287, 0.047797, 03641 0.030273, 0.013663, 0.048326, 03642 0.03061, 0.01404, 0.048855, 03643 0.030948, 0.014417, 0.049383, 03644 0.031286, 0.014794, 0.049912, 03645 0.031623, 0.01517, 0.050441, 03646 0.032156, 0.015707, 0.051035, 03647 0.032688, 0.016244, 0.05163, 03648 0.033221, 0.016782, 0.052225, 03649 0.033753, 0.017319, 0.052819, 03650 0.034286, 0.017856, 0.053414, 03651 0.034961, 0.018693, 0.054493, 03652 0.035636, 0.019531, 0.055573, 03653 0.036312, 0.020369, 0.056652, 03654 0.036987, 0.021206, 0.057731, 03655 0.037662, 0.022044, 0.058811, 03656 0.038623, 0.023246, 0.060044, 03657 0.039584, 0.024449, 0.061278, 03658 0.040545, 0.025651, 0.062511, 03659 0.041506, 0.026854, 0.063744, 03660 0.042468, 0.028056, 0.064978, 03661 0.043857, 0.029659, 0.066806, 03662 0.045247, 0.031263, 0.068634, 03663 0.046636, 0.032866, 0.070463, 03664 0.048026, 0.034469, 0.072291, 03665 0.049416, 0.036072, 0.074119, 03666 0.051221, 0.038156, 0.076476, 03667 0.053026, 0.04024, 0.078833, 03668 0.054831, 0.042325, 0.081189, 03669 0.056636, 0.044409, 0.083546, 03670 0.058442, 0.046493, 0.085903, 03671 0.06039, 0.048737, 0.087996, 03672 0.062338, 0.050982, 0.090088, 03673 0.064286, 0.053226, 0.092181, 03674 0.066234, 0.055471, 0.094273, 03675 0.068182, 0.057715, 0.096366, 03676 0.070519, 0.06012, 0.098921, 03677 0.072857, 0.062525, 0.10148, 03678 0.075195, 0.06493, 0.10403, 03679 0.077532, 0.067335, 0.10659, 03680 0.07987, 0.069739, 0.10914, 03681 0.082208, 0.072345, 0.11176, 03682 0.084545, 0.07495, 0.11438, 03683 0.086883, 0.077555, 0.117, 03684 0.089221, 0.08016, 0.11963, 03685 0.091558, 0.082766, 0.12225, 03686 0.094026, 0.085611, 0.12533, 03687 0.096494, 0.088457, 0.12841, 03688 0.098961, 0.091303, 0.1315, 03689 0.10143, 0.094148, 0.13458, 03690 0.1039, 0.096994, 0.13767, 03691 0.10688, 0.10028, 0.14119, 03692 0.10987, 0.10357, 0.14471, 03693 0.11286, 0.10685, 0.14824, 03694 0.11584, 0.11014, 0.15176, 03695 0.11883, 0.11343, 0.15529, 03696 0.12208, 0.11695, 0.15903, 03697 0.12532, 0.12048, 0.16278, 03698 0.12857, 0.12401, 0.16652, 03699 0.13182, 0.12754, 0.17026, 03700 0.13506, 0.13106, 0.17401, 03701 0.1387, 0.13499, 0.17819, 03702 0.14234, 0.13892, 0.18238, 03703 0.14597, 0.14285, 0.18656, 03704 0.14961, 0.14677, 0.19075, 03705 0.15325, 0.1507, 0.19493, 03706 0.15727, 0.15519, 0.19956, 03707 0.1613, 0.15968, 0.20419, 03708 0.16532, 0.16417, 0.20881, 03709 0.16935, 0.16866, 0.21344, 03710 0.17338, 0.17315, 0.21806, 03711 0.17805, 0.17796, 0.22291, 03712 0.18273, 0.18277, 0.22775, 03713 0.1874, 0.18758, 0.2326, 03714 0.19208, 0.19238, 0.23744, 03715 0.19675, 0.19719, 0.24229, 03716 0.20156, 0.20224, 0.24758, 03717 0.20636, 0.20729, 0.25286, 03718 0.21117, 0.21234, 0.25815, 03719 0.21597, 0.21739, 0.26344, 03720 0.22078, 0.22244, 0.26872, 03721 0.2261, 0.22806, 0.27423, 03722 0.23143, 0.23367, 0.27974, 03723 0.23675, 0.23928, 0.28524, 03724 0.24208, 0.24489, 0.29075, 03725 0.2474, 0.2505, 0.29626, 03726 0.25299, 0.25651, 0.3022, 03727 0.25857, 0.26253, 0.30815, 03728 0.26416, 0.26854, 0.3141, 03729 0.26974, 0.27455, 0.32004, 03730 0.27532, 0.28056, 0.32599, 03731 0.28156, 0.28697, 0.33238, 03732 0.28779, 0.29339, 0.33877, 03733 0.29403, 0.2998, 0.34515, 03734 0.30026, 0.30621, 0.35154, 03735 0.30649, 0.31263, 0.35793, 03736 0.3126, 0.31904, 0.36388, 03737 0.3187, 0.32545, 0.36982, 03738 0.32481, 0.33186, 0.37577, 03739 0.33091, 0.33828, 0.38172, 03740 0.33701, 0.34469, 0.38767, 03741 0.34325, 0.3511, 0.39361, 03742 0.34948, 0.35752, 0.39956, 03743 0.35571, 0.36393, 0.40551, 03744 0.36195, 0.37034, 0.41145, 03745 0.36818, 0.37675, 0.4174, 03746 0.37429, 0.38317, 0.42313, 03747 0.38039, 0.38958, 0.42885, 03748 0.38649, 0.39599, 0.43458, 03749 0.3926, 0.4024, 0.44031, 03750 0.3987, 0.40882, 0.44604, 03751 0.40494, 0.41523, 0.45198, 03752 0.41117, 0.42164, 0.45793, 03753 0.4174, 0.42806, 0.46388, 03754 0.42364, 0.43447, 0.46982, 03755 0.42987, 0.44088, 0.47577, 03756 0.43623, 0.44689, 0.48128, 03757 0.4426, 0.45291, 0.48678, 03758 0.44896, 0.45892, 0.49229, 03759 0.45532, 0.46493, 0.4978, 03760 0.46169, 0.47094, 0.5033, 03761 0.46792, 0.47695, 0.50837, 03762 0.47416, 0.48297, 0.51344, 03763 0.48039, 0.48898, 0.5185, 03764 0.48662, 0.49499, 0.52357, 03765 0.49286, 0.501, 0.52863, 03766 0.49805, 0.50701, 0.53392, 03767 0.50325, 0.51303, 0.53921, 03768 0.50844, 0.51904, 0.54449, 03769 0.51364, 0.52505, 0.54978, 03770 0.51883, 0.53106, 0.55507, 03771 0.52442, 0.53667, 0.55969, 03772 0.53, 0.54228, 0.56432, 03773 0.53558, 0.5479, 0.56894, 03774 0.54117, 0.55351, 0.57357, 03775 0.54675, 0.55912, 0.57819, 03776 0.55182, 0.56433, 0.58304, 03777 0.55688, 0.56954, 0.58789, 03778 0.56195, 0.57475, 0.59273, 03779 0.56701, 0.57996, 0.59758, 03780 0.57208, 0.58517, 0.60242, 03781 0.57675, 0.58998, 0.60639, 03782 0.58143, 0.59479, 0.61035, 03783 0.5861, 0.5996, 0.61432, 03784 0.59078, 0.60441, 0.61828, 03785 0.59545, 0.60922, 0.62225, 03786 0.60065, 0.61403, 0.62709, 03787 0.60584, 0.61884, 0.63194, 03788 0.61104, 0.62365, 0.63678, 03789 0.61623, 0.62846, 0.64163, 03790 0.62143, 0.63327, 0.64648, 03791 0.62584, 0.63808, 0.65088, 03792 0.63026, 0.64289, 0.65529, 03793 0.63468, 0.6477, 0.65969, 03794 0.63909, 0.65251, 0.6641, 03795 0.64351, 0.65731, 0.6685, 03796 0.64857, 0.66132, 0.67269, 03797 0.65364, 0.66533, 0.67687, 03798 0.6587, 0.66934, 0.68106, 03799 0.66377, 0.67335, 0.68524, 03800 0.66883, 0.67735, 0.68943, 03801 0.67273, 0.68136, 0.69361, 03802 0.67662, 0.68537, 0.6978, 03803 0.68052, 0.68938, 0.70198, 03804 0.68442, 0.69339, 0.70617, 03805 0.68831, 0.69739, 0.71035, 03806 0.69221, 0.7022, 0.7141, 03807 0.6961, 0.70701, 0.71784, 03808 0.7, 0.71182, 0.72159, 03809 0.7039, 0.71663, 0.72533, 03810 0.70779, 0.72144, 0.72907, 03811 0.71169, 0.72505, 0.73348, 03812 0.71558, 0.72866, 0.73789, 03813 0.71948, 0.73226, 0.74229, 03814 0.72338, 0.73587, 0.7467, 03815 0.72727, 0.73948, 0.7511, 03816 0.73247, 0.74349, 0.75507, 03817 0.73766, 0.74749, 0.75903, 03818 0.74286, 0.7515, 0.763, 03819 0.74805, 0.75551, 0.76696, 03820 0.75325, 0.75952, 0.77093, 03821 0.75714, 0.76393, 0.77599, 03822 0.76104, 0.76834, 0.78106, 03823 0.76494, 0.77275, 0.78612, 03824 0.76883, 0.77715, 0.79119, 03825 0.77273, 0.78156, 0.79626, 03826 0.77792, 0.78677, 0.80132, 03827 0.78312, 0.79198, 0.80639, 03828 0.78831, 0.79719, 0.81145, 03829 0.79351, 0.8024, 0.81652, 03830 0.7987, 0.80762, 0.82159, 03831 0.80519, 0.81283, 0.82687, 03832 0.81169, 0.81804, 0.83216, 03833 0.81818, 0.82325, 0.83744, 03834 0.82468, 0.82846, 0.84273, 03835 0.83117, 0.83367, 0.84802, 03836 0.83636, 0.83888, 0.85286, 03837 0.84156, 0.84409, 0.85771, 03838 0.84675, 0.8493, 0.86256, 03839 0.85195, 0.85451, 0.8674, 03840 0.85714, 0.85972, 0.87225, 03841 0.86364, 0.86613, 0.87819, 03842 0.87013, 0.87255, 0.88414, 03843 0.87662, 0.87896, 0.89009, 03844 0.88312, 0.88537, 0.89604, 03845 0.88961, 0.89178, 0.90198, 03846 0.8961, 0.8986, 0.90947, 03847 0.9026, 0.90541, 0.91696, 03848 0.90909, 0.91222, 0.92445, 03849 0.91558, 0.91904, 0.93194, 03850 0.92208, 0.92585, 0.93943, 03851 0.92857, 0.93307, 0.94493, 03852 0.93506, 0.94028, 0.95044, 03853 0.94156, 0.94749, 0.95595, 03854 0.94805, 0.95471, 0.96145, 03855 0.95455, 0.96192, 0.96696, 03856 0.96364, 0.96954, 0.97357, 03857 0.97273, 0.97715, 0.98018, 03858 0.98182, 0.98477, 0.98678, 03859 0.99091, 0.99238, 0.99339, 03860 1, 1, 1 }; 03861 03862 static const double lms0[3] = { 34.918538957799996, 19.314796676499999, 0.585610818500000 }; 03863 03864 static const double m[9] = { 18.32535, 44.60077, 7.46216, 03865 4.09544, 28.20135, 6.66066, 03866 0.02114, 0.10325, 1.05258 }; 03867 03868 static const double fac = 1.0 / (lms0[0] + lms0[1]); 03869 03870 static const double mm[9] = { 03871 sqrt(3.0)*fac, sqrt(3.0)*fac, 0.0, 03872 sqrt(lms0[0]*lms0[0]+lms0[1]*lms0[1])/lms0[0]*fac, -sqrt(lms0[0]*lms0[0]+lms0[1]*lms0[1])/lms0[1]*fac, 0.0, 03873 -fac, -fac, (lms0[0] + lms0[1]) / lms0[2] * fac }; 03874 03875 // convert RGB values to bytes, with clamping: 03876 const PixRGB<byte> A(A1); 03877 03878 // do a lookup RGB -> rgb: 03879 const double aa1 = lut_rgb[A[0] * 3]; 03880 const double aa2 = lut_rgb[A[1] * 3 + 1]; 03881 const double aa3 = lut_rgb[A[2] * 3 + 2]; 03882 03883 // now convert to LMS: 03884 const double lms1 = m[0] * aa1 + m[1] * aa2 + m[2] * aa3 - lms0[0]; 03885 const double lms2 = m[3] * aa1 + m[4] * aa2 + m[5] * aa3 - lms0[1]; 03886 const double lms3 = m[6] * aa1 + m[7] * aa2 + m[8] * aa3 - lms0[2]; 03887 03888 // finally to DKL: 03889 const double dkl1 = mm[0] * lms1 + mm[1] * lms2 + mm[2] * lms3; 03890 const double dkl2 = mm[3] * lms1 + mm[4] * lms2 + mm[5] * lms3; 03891 const double dkl3 = mm[6] * lms1 + mm[7] * lms2 + mm[8] * lms3; 03892 03893 // finally to DKLn: 03894 p[0] = clamped_convert<T>(dkl1 * 0.5774); 03895 p[1] = clamped_convert<T>(dkl2 * 2.7525); 03896 p[2] = clamped_convert<T>(dkl3 * 0.4526); 03897 } 03898 03899 // ###################################################################### 03900 // Standard Constructors / Destrcutor 03901 // ###################################################################### 03902 03903 template <class T> 03904 inline PixDKL<T>::PixDKL() : Pixels<T,3>() 03905 {} 03906 03907 // ###################################################################### 03908 template <class T> 03909 inline PixDKL<T>::~PixDKL() 03910 {} 03911 03912 // ###################################################################### 03913 template <class T> 03914 inline PixDKL<T>::PixDKL(const T val) : Pixels<T,3>(val) 03915 {} 03916 03917 // ###################################################################### 03918 template <class T> 03919 inline PixDKL<T>::PixDKL(const PixDKL<T>& pix) : Pixels<T,3>(pix) 03920 {} 03921 03922 // ###################################################################### 03923 template <class T> 03924 template <class T2> inline PixDKL<T>::PixDKL(const PixDKL<T2>& A1) 03925 : Pixels<T,3>() 03926 { 03927 p[0] = clamped_convert<T>(A1[0]); 03928 p[1] = clamped_convert<T>(A1[1]); 03929 p[2] = clamped_convert<T>(A1[2]); 03930 } 03931 03932 // ###################################################################### 03933 // Special methods for this class 03934 // ###################################################################### 03935 03936 template <class T> 03937 inline void PixDKL<T>::getDKL(T& d, T& k, T& l) const 03938 { 03939 d = p[0]; k = p[1]; l = p[2]; 03940 } 03941 03942 // ###################################################################### 03943 template <class T> 03944 inline PixDKL<T>::PixDKL(const T Dval, const T Kval, const T Lval) : Pixels<T,3>() 03945 { 03946 p[0] = Dval; p[1] = Kval; p[2] = Lval; 03947 } 03948 03949 // ###################################################################### 03950 template <class T> template <class T2, class T3, class T4> inline 03951 PixDKL<T>::PixDKL(const T2 Dval, const T3 Kval, const T4 Lval) : Pixels<T,3>() 03952 { 03953 p[0] = clamped_convert<T>(Dval); 03954 p[1] = clamped_convert<T>(Kval); 03955 p[2] = clamped_convert<T>(Lval); 03956 } 03957 03958 // ###################################################################### 03959 template <class T> 03960 inline T PixDKL<T>::D() const 03961 { 03962 return p[0]; 03963 } 03964 03965 // ###################################################################### 03966 template <class T> 03967 inline T PixDKL<T>::K() const 03968 { 03969 return p[1]; 03970 } 03971 03972 // ###################################################################### 03973 template <class T> 03974 inline T PixDKL<T>::L() const 03975 { 03976 return p[2]; 03977 } 03978 03979 // ###################################################################### 03980 template <class T> 03981 template <class T2> inline void PixDKL<T>::setD(const T2 dd) 03982 { 03983 p[0] = clamped_convert<T>(dd); 03984 } 03985 03986 // ###################################################################### 03987 template <class T> 03988 template <class T2> inline void PixDKL<T>::setK(const T2 kk) 03989 { 03990 p[1] = clamped_convert<T>(kk); 03991 } 03992 03993 // ###################################################################### 03994 template <class T> 03995 template <class T2> inline void PixDKL<T>::setL(const T2 ll) 03996 { 03997 p[2] = clamped_convert<T>(ll); 03998 } 03999 04000 // ###################################################################### 04001 // Specialize promote_trait for pixel types 04002 // ###################################################################### 04003 04004 /* The SPECIALIZE_PROMOTE_TRAIT macro is defined in 04005 Util/Promotions.H. Note that these SPECIALIZE_PROMOTE_TRAIT() macro 04006 calls should NOT go in Util/Promotions.H, since the Util/ directory 04007 is supposed to be independent of pixels, images, etc. */ 04008 04009 //! Quickie macro for escaping the comma out of a macro argument. 04010 #define LIST_2(p1, p2) p1, p2 04011 04012 /* If you need to add a dim to a hyper pixel you can add it here */ 04013 SPECIALIZE_PROMOTE_TRAIT(PixHyper, LIST_2(class T, size_t dim), LIST_2(, 3)) 04014 SPECIALIZE_PROMOTE_TRAIT(PixHyper, LIST_2(class T, size_t dim), LIST_2(, 4)) 04015 04016 #undef LIST_2 04017 04018 SPECIALIZE_PROMOTE_TRAIT(PixRGB, class T, ) 04019 SPECIALIZE_PROMOTE_TRAIT(PixHSV, class T, ) 04020 SPECIALIZE_PROMOTE_TRAIT(PixJpegYUV, class T, ) 04021 SPECIALIZE_PROMOTE_TRAIT(PixVideoYUV, class T, ) 04022 SPECIALIZE_PROMOTE_TRAIT(PixYIQ, class T, ) 04023 SPECIALIZE_PROMOTE_TRAIT(PixHSL, class T, ) 04024 SPECIALIZE_PROMOTE_TRAIT(PixH2SV1, class T, ) 04025 SPECIALIZE_PROMOTE_TRAIT(PixH2SV2, class T, ) 04026 SPECIALIZE_PROMOTE_TRAIT(PixH2SV3, class T, ) 04027 SPECIALIZE_PROMOTE_TRAIT(PixDKL, class T, ) 04028 04029 #endif