Hugintrunk  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
lut.h
Go to the documentation of this file.
1 // -*- c-basic-offset: 4 -*-
24 #ifndef _VIGRA_EXT_LUT_H
25 #define _VIGRA_EXT_LUT_H
26 
27 #include <vector>
28 #include <functional>
29 
30 #include <hugin_math/hugin_math.h>
31 
32 #include <vigra/stdimage.hxx>
33 #include <vigra/numerictraits.hxx>
34 //#include <vigra/transformimage.hxx>
35 //#include <vigra/combineimages.hxx>
36 //#include <vigra/functorexpression.hxx>
37 #include <vigra/array_vector.hxx>
38 
39 #include <vigra_ext/utils.h>
40 #include <vigra_ext/HDRUtils.h>
41 #include <vigra_ext/emor.h>
42 //#include <boost/random/mersenne_twister.hpp>
43 
44 
45 //#define DEBUG_WRITE_FILES
46 
47 namespace vigra_ext{
48 
49 template <class VECTOR>
50 inline void createGammaLUT(double gamma, VECTOR & lut)
51 {
52  typedef typename VECTOR::value_type VT;
54 
55  // lookup tables
56  for (size_t i=0; i<lut.size(); ++i) {
57  double x = i*1.0/(lut.size() -1);
58  lut[i] = vigra::NumericTraits<VT>::fromRealPromote(pow(x, gamma)*s);
59  }
60 }
61 
62 
63 template <class VEC, class VEC2>
64 void resizeLUT(const VEC & iLUT, VEC2 & oLUT)
65 {
66  assert(iLUT.size());
67  assert(oLUT.size());
68 
69  for(size_t oIdx = 0; oIdx < oLUT.size(); oIdx++) {
70  double ix = oIdx/(oLUT.size()-1.0) * (iLUT.size()-1);
71  unsigned iIdx = unsigned(ix);
72  double deltaix = ix-iIdx;
73  if (deltaix == 0.0) {
74  // no interpolation required.
75  oLUT[oIdx] = iLUT[iIdx];
76  } else if (iIdx+1 <= iLUT.size()){
77  // linear interpolation
78  oLUT[oIdx] = (1-deltaix) * iLUT[iIdx] + deltaix * iLUT[iIdx+1];
79  } else {
80  oLUT[oIdx] = iLUT.back();
81  }
82  }
83 }
84 
86 template <class LUT>
87 void enforceMonotonicity(LUT & lut)
88 {
89  typedef typename LUT::value_type lut_type;
90  int lutsize = lut.size();
91 
92  if (lutsize) {
93  lut_type max = lut.back();
94  for (int j=0; j < lutsize-1; j++)
95  {
96  if (lut[j+1] > max) {
97  lut[j+1] = max;
98  } else if (lut[j+1] < lut[j]) {
99  lut[j+1] = lut[j];
100  }
101  }
102  }
103 }
104 
117 template <class VTIn, class LUT>
119 {
121 
124  //typedef VT1 first_argument_type;
125 
126  typedef typename LUT::value_type lut_type;
127 
130  //typedef typename vigra::NumericTraits<VT1>::RealPromote result_type;
131 
133  {
134 
135  }
136 
138  LUTFunctor(LUT & lut)
139  : m_lut(lut)
140  {
141  /*
142  if (sizeof(VT1) ==1)
143  assert(m_lut.size() >= 256);
144  else
145  assert(m_lut.size() >= 1<<10);
146  */
147  }
148 
150  {
151  // lut type.
152  assert(!m_lut.empty());
153  if (m_lut.size() == LUTTraits<VT1>::max()) {
154  return m_lut[v];
155  } else {
156  // calculate new index
157  double m = LUTTraits<VT1>::max();
158  double x=v/m*(m_lut.size()-1);
159  unsigned i = unsigned(x);
160  x = x-i;
161  if ( x != 0 && i+1 < m_lut.size()) {
162  // linear interpolation
163  return ((1-x)*m_lut[i]+x*m_lut[i+1]);
164  } else {
165  return m_lut[i];
166  }
167  }
168  }
169 
170  lut_type applyLutFloat(double v) const
171  {
172  assert(!m_lut.empty());
173  if (v > 1) return m_lut.back();
174  if (v < 0) return 0;
175  double x=v*(m_lut.size()-1);
176  unsigned i = unsigned(x);
177  // interpolate
178  x = x-i;
179  if ( i+1 < m_lut.size()) {
180  // linear interpolation
181  return vigra::NumericTraits<lut_type>::fromRealPromote((1-x)*m_lut[i]+x*m_lut[i+1]);
182  } else {
183  return m_lut[i];
184  }
185  }
186 
187  // lookup on floating point values, interpolate if nessecary
188  vigra::RGBValue<lut_type> applyVector( vigra::RGBValue<VT1> v, vigra::VigraFalseType) const
189  {
190  vigra::RGBValue<VT1> ret;
191  for (size_t i=0; i < v.size(); i++) {
192  ret[i] = applyLutFloat((v[i]));
193  }
194  return ret;
195  }
196 
197  // lookup vector types (the lut needs to be long enought!)
198  vigra::RGBValue<lut_type> applyVector(vigra::RGBValue<VT1> v, vigra::VigraTrueType) const
199  {
200  assert(!m_lut.empty());
201  vigra::RGBValue<lut_type> ret;
202  for (size_t i=0; i < v.size(); i++) {
203  ret[i] = applyLutInteger(v[i]);
204  }
205  return ret;
206  }
207 
208  // lookup floating point types
209  lut_type applyScalar(VT1 v, vigra::VigraFalseType) const
210  {
211  return applyLutFloat(v);
212  }
213 
214  // lookup scalar types
215  lut_type applyScalar(VT1 v, vigra::VigraTrueType) const
216  {
217  return applyLutInteger(v);
218  }
219 
220  lut_type apply(VT1 v, vigra::VigraTrueType) const
221  {
222  typedef typename vigra::NumericTraits<VT1>::isIntegral isIntegral;
223  return applyScalar(v, isIntegral());
224  }
225 
226  vigra::RGBValue<lut_type> apply(vigra::RGBValue<VT1> v, vigra::VigraFalseType) const
227  {
228  typedef typename vigra::NumericTraits<VT1>::isIntegral isIntegral;
229  return applyVector(v, isIntegral());
230  }
231 
232  template <class T>
233  typename vigra::NumericTraits<T>::RealPromote operator()(T v) const
234  {
235  typedef typename vigra::NumericTraits<T>::isScalar is_scalar;
236  return apply(v, is_scalar());
237  }
238 
239  LUT m_lut;
240 };
241 
251 template <class VT1, class LUT>
253 {
256  //typedef VT1 first_argument_type;
257 
258  typedef typename LUT::value_type lut_type;
259 
262  //typedef typename vigra::NumericTraits<VT1>::RealPromote result_type;
263 
265  {
266  }
267 
269  InvLUTFunctor(LUT & lut)
270  : m_lut(lut)
271  {
272  }
273 
274  // assume float is scaled 0..1
276  {
277  assert(!m_lut.empty());
278  if (v >= m_lut.back()) return m_lut.back();
279  if (v < m_lut[0]) return 0;
280 
281  // find the lower bound, p will point to the first *p >= v
282  typename LUT::const_iterator p = lower_bound(m_lut.begin(), m_lut.end(), v);
283 
284 
285  int x = p-m_lut.begin();
286 #ifdef DEBUG
287 // just for usage in the debugger
288  //const lut_type *plut = &(*(m_lut.begin()));
289 #endif
290  if (v == 1) {
291  return 1;
292  } else if (x == 0) {
293  return 0;
294  } else if (v == *p) {
295  return x/(m_lut.size()-1.0);
296  } else {
297  // interpolate position.
298  // p points to the first element > v
299  double lower = *(p-1);
300  double upper = *(p);
301  lut_type delta = (v - lower) / (upper - lower);
302  return (x-1 + delta) / (m_lut.size()-1.0);
303  }
304 
305  }
306 
307  template <class T>
309  {
311  }
312 
313  // lookup on floating point values. convert to 16 bit
314  // and use lookup table there.
315  template <class T>
316  vigra::RGBValue<lut_type> applyVector( vigra::RGBValue<T> v, vigra::VigraFalseType) const
317  {
318  vigra::RGBValue<VT1> ret;
319  for (size_t i=0; i < v.size(); i++) {
320  ret[i] = applyLutFloat((v[i]));
321  }
322  return ret;
323  }
324 
325  template <class T>
326  vigra::RGBValue<lut_type> applyVector(vigra::RGBValue<T> v, vigra::VigraTrueType) const
327  {
328  vigra::RGBValue<lut_type> ret;
329  for (size_t i=0; i < v.size(); i++) {
330  ret[i] = applyLutInteger(v[i]);
331  }
332  return ret;
333  }
334 
335  // lookup integers,
336  template <class T>
337  lut_type applyScalar(T v, vigra::VigraFalseType) const
338  {
339  return applyLutFloat(v);
340  }
341 
342  // lookup scalar types (the lut needs to be long enought!)
343  template <class T>
344  lut_type applyScalar(T v, vigra::VigraTrueType) const
345  {
346  return applyLutInteger(v);
347  }
348 
349  template <class T>
350  lut_type apply(T v, vigra::VigraTrueType) const
351  {
352  typedef typename vigra::NumericTraits<T>::isIntegral isIntegral;
353  return applyScalar(v, isIntegral());
354  }
355 
356  template <class T>
357  vigra::RGBValue<lut_type> apply(vigra::RGBValue<T> v, vigra::VigraFalseType) const
358  {
359  typedef typename vigra::NumericTraits<T>::isIntegral isIntegral;
360  return applyVector(v, isIntegral());
361  }
362 
363  template <class T>
364  typename vigra::NumericTraits<T>::RealPromote operator()(T v) const
365  {
366  typedef typename vigra::NumericTraits<T>::isScalar is_scalar;
367  return apply(v, is_scalar());
368  }
369 
370  LUT m_lut;
371 };
372 
375 template <class OP>
377 {
378  ExposureResponseFunctor(double exposure, OP & operation)
379  : op(operation), e(exposure)
380  {
381  e=exposure;
382  op = operation;
383  }
384  OP op;
385  double e;
386 
387  template <class VT>
388  typename vigra::NumericTraits<VT>::RealPromote
390  {
391  return op(v*e);
392  }
393 };
394 
395 } // namespace
396 
397 #endif // _H
LUT::value_type lut_type
the functor&#39;s first argument type
Definition: lut.h:126
vigra::RGBValue< lut_type > applyVector(vigra::RGBValue< VT1 > v, vigra::VigraTrueType) const
Definition: lut.h:198
lut_type applyScalar(T v, vigra::VigraFalseType) const
Definition: lut.h:337
lut_type apply(VT1 v, vigra::VigraTrueType) const
Definition: lut.h:220
lut_type applyScalar(VT1 v, vigra::VigraTrueType) const
Definition: lut.h:215
void resizeLUT(const VEC &iLUT, VEC2 &oLUT)
Definition: lut.h:64
misc math function &amp; classes used by other parts of the program
vigra::RGBValue< lut_type > applyVector(vigra::RGBValue< VT1 > v, vigra::VigraFalseType) const
Definition: lut.h:188
ExposureResponseFunctor(double exposure, OP &operation)
Definition: lut.h:378
lut_type applyScalar(VT1 v, vigra::VigraFalseType) const
Definition: lut.h:209
void enforceMonotonicity(LUT &lut)
enforce monotonicity of an array (mostly used for lookup tables)
Definition: lut.h:87
LUTFunctor()
the functor&#39;s result type
Definition: lut.h:132
functor to apply a LUT to gray and color images.
Definition: lut.h:118
functions to manage ROI&#39;s
functor to apply a LUT to gray and color images.
Definition: lut.h:252
vigra::RGBValue< lut_type > applyVector(vigra::RGBValue< T > v, vigra::VigraTrueType) const
Definition: lut.h:326
lut_type applyScalar(T v, vigra::VigraTrueType) const
Definition: lut.h:344
LUT::value_type lut_type
the functor&#39;s first argument type
Definition: lut.h:258
just apply exposure and response to linear data
Definition: lut.h:376
float pow(float a, double b)
Definition: utils.h:181
vigra_ext::ValueTypeTraits< VTIn >::value_type VT1
Definition: lut.h:120
vigra::NumericTraits< VT >::RealPromote operator()(VT v)
Definition: lut.h:389
vigra::NumericTraits< T >::RealPromote operator()(T v) const
Definition: lut.h:364
vigra::NumericTraits< T >::RealPromote operator()(T v) const
Definition: lut.h:233
LUTFunctor(LUT &lut)
create a LUT functor.
Definition: lut.h:138
lut_type applyLutFloat(lut_type v) const
Definition: lut.h:275
lut_type applyLutFloat(double v) const
Definition: lut.h:170
vigra::RGBValue< lut_type > apply(vigra::RGBValue< T > v, vigra::VigraFalseType) const
Definition: lut.h:357
void createGammaLUT(double gamma, VECTOR &lut)
Definition: lut.h:50
InvLUTFunctor()
the functor&#39;s result type
Definition: lut.h:264
static T max(T x, T y)
Definition: svm.cpp:65
InvLUTFunctor(LUT &lut)
create a LUT functor.
Definition: lut.h:269
T1::value_type value_type
Definition: utils.h:153
lut_type applyLutInteger(VT1 v) const
Definition: lut.h:149
lut_type apply(T v, vigra::VigraTrueType) const
Definition: lut.h:350
vigra::RGBValue< lut_type > applyVector(vigra::RGBValue< T > v, vigra::VigraFalseType) const
Definition: lut.h:316
lut_type applyLutInteger(T i) const
Definition: lut.h:308
vigra::RGBValue< lut_type > apply(vigra::RGBValue< VT1 > v, vigra::VigraFalseType) const
Definition: lut.h:226