SLAMflex SE  0.1.0
SLAMflex provides detection and tracking of dominant planes for smartphone devices. This plane can then be used to show AR content relative to the plane orientation. The detection of plane is performed in the field of view of the smartphone camera. In subsequent frames it is tracked. The interface returns the plane position and orientation.
convert_pixel_types.h
Go to the documentation of this file.
1 /*
2  This file is part of the CVD Library.
3 
4  Copyright (C) 2005 The Authors
5 
6  This library is free software; you can redistribute it and/or
7  modify it under the terms of the GNU Lesser General Public
8  License as published by the Free Software Foundation; either
9  version 2.1 of the License, or (at your option) any later version.
10 
11  This library is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  Lesser General Public License for more details.
15 
16  You should have received a copy of the GNU Lesser General Public
17  License along with this library; if not, write to the Free Software
18  Foundation, Inc.,
19  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21 #ifndef CVD_CONVERT_PIXEL_TYPES_H
22 #define CVD_CONVERT_PIXEL_TYPES_H
23 
24 #include <math.h>
25 
26 #include "abs.h"
27 #include "scalar_convert.h"
28 #include "builtin_components.h"
29 #include "rgb_components.h"
30 #include "is_pod.h"
31 #include <limits>
32 
33 namespace CVD{namespace Pixel
34 {
35  //All "conversion" classes must have a "void convert_pixel(from, to)"
36  //nonstatic templated member.
37 
38  //This conversion knows how to convert from any size pixel to any other.
39 
40  template <class From, class To, int CF=Pixel::Component<From>::count, int CT=Pixel::Component<To>::count> struct GenericConversion;
41 
42  template <class From, class To> struct GenericConversion<From,To,1,1> {
43  static inline void convert(const From& from, To& to) {
44  to = scalar_convert<To,From>(from);
45  }
46  };
47 
48  template <class From, class To, int N> struct GenericConversion<From,To,N,N> {
50  typedef typename Pixel::Component<To>::type ToS;
51  static inline void convert(const From& from, To& to) {
52  for (int i=0; i<N; i++)
53  Pixel::Component<To>::get(to,i) = scalar_convert<ToS,FromS>(Pixel::Component<From>::get(from,i));
54  }
55  };
56 
57  template <class T, int N> struct GenericConversion<T,T,N,N> {
58  static inline void convert(const T& from, T& to) {
59  to = from;
60  }
61  };
62 
63  template <class T, int N> struct GenericConversion<T[N],T[N], N, N> {
64  typedef T array[N];
65  static inline void convert(const array& from, array& to) {
66  for (int i=0; i<N; i++)
67  to[i] = from[i];
68  }
69  };
70 
71  template <class Rgbish, class Scalar> struct CIE {
72  static inline void convert(const Rgbish& from, Scalar& to) {
73  // "Correct" values are:
74  // const double wr=0.299, wg=0.587, wb=0.114;
75  // Since these are not representable as floating point values
76  // They do not sum exactly to 1.
77  // Instead, convert them using floor(x * 0x10000 + 0.5)/0x10000
78  // So that they use exactly 16 bits of precision.
79  // This should be OK for pretty mych everything
80  // 0.299 ~= 19595/0x10000 == 0x4c8bp-16 == 0.2989959716796875
81  // 0.587 ~= 38470/0x10000 == 0x9646p-16 == 0.587005615234375
82  // 0.114 ~= 7471/0x10000 == 0x1d2fp-16 == 0.1139984130859375
83  // These will sum exactly to 1. C++ does not yet allow hex floating point
84  // literals
85  const double wr=0.2989959716796875, wg=0.587005615234375, wb=0.1139984130859375;
86 
87  /*
88  The old method does not work properly because the conversion to double from int_type
89  is inexact. Ttuncation of this causes errors. However, it is unnecessary to convert
90  to the double pixel type first: the arithmetic merely needs to be done with doubles.
91 
92  to = scalar_convert<Scalar,double>(wr*scalar_convert<double,typename Pixel::Component<Rgbish>::type>(from.red) +
93  wg*scalar_convert<double,typename Pixel::Component<Rgbish>::type>(from.green) +
94  wb*scalar_convert<double,typename Pixel::Component<Rgbish>::type>(from.blue));
95 
96  Fortunately, we have forseen this eventuality, and scalar_convert can convert from
97  type A, to type B when pixel type B is held in a variable of type C
98  */
99  to = scalar_convert<Scalar,typename Pixel::Component<Rgbish>::type,double>(wr*from.red + wg*from.green + wb*from.blue);
100 
101  /* The following method could be used (for speed):
102 
103  to = scalar_convert<Scalar,typename Pixel::Component<Rgbish>::type>(
104  static_cast<typename Pixel::Component<Rgbish>::type>(wr*from.red + wg*from.green + wb*from.blue));
105 
106  but this looses precision and may produce odd results for rgb(x,y,z) (x!=y!=z). Does this matter? Bear
107  in mind that wr, wg, wb are only approximations of "average" human eye response anyway.
108  */
109 
110  }
111  };
112 
113  template <class P, class Scalar> struct Uniform {
114  static inline void convert(const P& from, Scalar& to) {
115  typedef typename Pixel::Component<P>::type T;
116  typename traits<T>::wider_type sum = Pixel::Component<P>::get(from,0);
117  for (unsigned int i=1; i<Pixel::Component<P>::count; i++)
118  sum += Pixel::Component<P>::get(from,i);
119  to = scalar_convert<Scalar,T>(sum/Pixel::Component<P>::count);
120  }
121  };
122 
123  template <class P, class Scalar> struct RMS {
124  static inline void convert(const P& from, Scalar& to) {
125  typedef typename Pixel::Component<P>::type T;
126  double sum = Pixel::Component<P>::get(from,0);
127  sum *= sum;
128  for (unsigned int i=1; i<Pixel::Component<P>::count; i++) {
129  double w = Pixel::Component<P>::get(from,i);
130  sum += w*w;
131  }
132  to = scalar_convert<Scalar,T,double>(sqrt(sum/(Pixel::Component<P>::count)));
133  }
134  };
135 
136  template <class P, class Scalar> struct AverageAbs {
137  static inline void convert(const P& from, Scalar& to) {
138  typedef typename Pixel::Component<P>::type T;
139  typedef typename Pixel::traits<T>::wider_type sum_type;
140  sum_type sum = CVD::abs(Pixel::Component<P>::get(from,0));
141  for (unsigned int i=1; i<Pixel::Component<P>::count; i++) {
142  sum += CVD::abs(Pixel::Component<P>::get(from,i));
143  }
144  to = scalar_convert<Scalar,T,sum_type>(sum/Pixel::Component<P>::count);
145  }
146  };
147 
148  template <class P, class Scalar> struct L2Norm {
149  static inline void convert(const P& from, Scalar& to) {
150  typedef typename Pixel::Component<P>::type T;
151  double sum = Pixel::Component<P>::get(from,0);
152  sum *= sum;
153  for (unsigned int i=1; i<Pixel::Component<P>::count; i++) {
154  double w = Pixel::Component<P>::get(from,i);
155  sum += w*w;
156  }
157  to = scalar_convert<Scalar,T,double>(sqrt(sum));
158  }
159  };
160 
161  template <class P, class Scalar> struct SumOfSquares {
162  static inline void convert(const P& from, Scalar& to) {
163  typedef typename Pixel::Component<P>::type T;
164  double sum = Pixel::Component<P>::get(from,0);
165  sum *= sum;
166  for (unsigned int i=1; i<Pixel::Component<P>::count; i++) {
167  double w = Pixel::Component<P>::get(from,i);
168  sum += w*w;
169  }
170  to = scalar_convert<Scalar,T,double>(sum);
171  }
172  };
173 
174  template <class Scalar, class Vec> struct Replicate {
175  static inline void convert(const Scalar& from, Vec& to) {
176  typedef typename Pixel::Component<Vec>::type T;
177  Pixel::Component<Vec>::get(to,0) = scalar_convert<T, Scalar>(from);
178  for (size_t i=1; i<Pixel::Component<Vec>::count; i++)
180  }
181  };
182 
183  template <class Scalar, class T> struct GreyToRgba {
184  static inline void convert(const Scalar& from, Rgba<T>& to) {
185  to.red = to.green = to.blue = scalar_convert<T, Scalar>(from);
187  }
188  };
189 
190  template <class A, class B> inline void RgbToRgb(const A& from, B& to) {
191  typedef typename Pixel::Component<A>::type T;
192  typedef typename Pixel::Component<B>::type S;
193  to.red = scalar_convert<S,T>(from.red);
194  to.green = scalar_convert<S,T>(from.green);
195  to.blue = scalar_convert<S,T>(from.blue);
196  }
197 
198  template <class A, class B> struct RgbishToRgbish {
199  static inline void convert(const A& from, B& to) {
200  RgbToRgb(from,to);
201  }
202  };
203 
204  template <class A,class T> struct RgbishToRgbish<A,Rgba<T> > {
205  static inline void convert(const A& from, Rgba<T>& to) {
206  RgbToRgb(from,to);
208  }
209  };
210 
211 
212  template <class S,class T> struct RgbishToRgbish<Rgba<S>,Rgba<T> > {
213  static inline void convert(const Rgba<S>& from, Rgba<T>& to) {
214  RgbToRgb(from,to);
215  to.alpha = scalar_convert<T,S>(from.alpha);
216  }
217  };
218 
219 
220 
221 
222 
223  // Default conversions
224 
225  template <class From, class To, int FN=Pixel::Component<From>::count, int TN=Pixel::Component<To>::count> struct DefaultConversion {
227  };
228 
229  // Scalar to X
230  template <class S, class T> struct DefaultConversion<S,Rgb<T>,1,3> { typedef Replicate<S,Rgb<T> > type; };
231  template <class S> struct DefaultConversion<S,Rgb8,1,3> { typedef Replicate<S,Rgb8> type; };
232  template <class S, class T> struct DefaultConversion<S,Rgba<T>,1,4> { typedef GreyToRgba<S,T> type; };
233 
234  // Rgb<T> to X
235  template <class T, class S> struct DefaultConversion<Rgb<T>,S,3,1> { typedef CIE<Rgb<T>,S> type; };
236  template <class T> struct DefaultConversion<Rgb<T>,Rgb8, 3,3> { typedef RgbishToRgbish<Rgb<T>, Rgb8> type; };
237  template <class T, class S> struct DefaultConversion<Rgb<T>,Rgba<S>,3,4> { typedef RgbishToRgbish<Rgb<T>, Rgba<S> > type; };
238  template <class T, class S> struct DefaultConversion<Rgb<T>,Rgb<S>,3,3> { typedef RgbishToRgbish<Rgb<T>, Rgb<S> > type; };
239  template <class T> struct DefaultConversion<Rgb<T>,Rgb<T>,3,3> { typedef GenericConversion<Rgb<T>, Rgb<T> > type; };
240  // Rgb8 to X
241  template <class S> struct DefaultConversion<Rgb8,S,3,1> { typedef CIE<Rgb8,S> type; };
242  template <class S> struct DefaultConversion<Rgb8,Rgb<S>,3,3> { typedef RgbishToRgbish<Rgb8, Rgb<S> > type; };
243  template <class S> struct DefaultConversion<Rgb8,Rgba<S>,3,4> { typedef RgbishToRgbish<Rgb8, Rgba<S> > type; };
244  template <> struct DefaultConversion<Rgb8,Rgb8,3,3> { typedef GenericConversion<Rgb8, Rgb8> type; };
245 
246  // Rgba<T> to X
247  template <class T, class S> struct DefaultConversion<Rgba<T>,S,4,1> { typedef CIE<Rgba<T>,S> type; };
248  template <class T, class S> struct DefaultConversion<Rgba<T>,Rgb<S>,4,3> { typedef RgbishToRgbish<Rgba<T>, Rgb<S> > type; };
249  template <class T> struct DefaultConversion<Rgba<T>,Rgb8,4,3> { typedef RgbishToRgbish<Rgba<T>, Rgb8> type; };
250  template <class T, class S> struct DefaultConversion<Rgba<T>,Rgba<S>,4,4> { typedef RgbishToRgbish<Rgba<T>, Rgba<S> > type; };
251  template <class T> struct DefaultConversion<Rgba<T>,Rgba<T>,4,4> { typedef GenericConversion<Rgba<T>, Rgba<T> > type; };
252 
253 
254  template <class From, class To, class Conv=typename DefaultConversion<From,To>::type,
256  static inline void convert(const From* from, To* to, size_t count) {
257  for (size_t i=0; i<count; i++)
258  Conv::convert(from[i], to[i]);
259  }
260  };
261 
262  template <class T> struct ConvertPixels<T,T,GenericConversion<T,T>,true> {
263  static inline void convert(const T* from, T* to, size_t count) {
264  memcpy(to, from, count*sizeof(T));
265  }
266  };
267 
272  template<class C> struct DefaultConvertible
273  {
274  static const int is = std::numeric_limits<C>::is_specialized;
275  };
276 
277  template<class C> struct DefaultConvertible<Rgb<C> >
278  {
279  static const int is = std::numeric_limits<C>::is_specialized;
280  };
281 
282 
283  template<class C> struct DefaultConvertible<Rgba<C> >
284  {
285  static const int is = std::numeric_limits<C>::is_specialized;
286  };
287 
288 
289  template<> struct DefaultConvertible<Rgb8>
290  {
291  static const int is = 1;
292  };
293 
294 }}
295 #endif
static void convert(const Scalar &from, Vec &to)
static const P & get(const P &pixel, size_t)
Definition: rgb.h:45
void RgbToRgb(const A &from, B &to)
Definition: rgba.h:38
static void convert(const T *from, T *to, size_t count)
T green
The green component.
Definition: rgba.h:51
static void convert(const From &from, To &to)
static void convert(const From &from, To &to)
Definition: abs.h:24
T abs(T t)
Definition: abs.h:30
static void convert(const P &from, Scalar &to)
static void convert(const P &from, Scalar &to)
T red
The red component.
Definition: rgba.h:50
T alpha
The alpha component.
Definition: rgba.h:53
static void convert(const Scalar &from, Rgba< T > &to)
static void convert(const P &from, Scalar &to)
static void convert(const Rgbish &from, Scalar &to)
static void convert(const Rgba< S > &from, Rgba< T > &to)
GenericConversion< From, To > type
static void convert(const P &from, Scalar &to)
static void convert(const array &from, array &to)
static void convert(const P &from, Scalar &to)
static void convert(const A &from, B &to)
Definition: rgb8.h:33
static void convert(const T &from, T &to)
static void convert(const A &from, Rgba< T > &to)
static void convert(const From *from, To *to, size_t count)
T blue
The blue component.
Definition: rgba.h:52