Hugin trunk 0.1
Loading...
Searching...
No Matches
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
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
47namespace vigra_ext{
48
49template <class VECTOR>
50inline 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
63template <class VEC, class VEC2>
64void 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
86template <class LUT>
87void 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
117template <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
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
251template <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 {
310 return applyLutFloat(i / lut_type(vigra::NumericTraits<T>::max()));
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
375template <class OP>
377{
379 : op(operation), e(exposure)
380 {
381 e=exposure;
382 op = operation;
383 }
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
misc math function & classes used by other parts of the program
void resizeLUT(const VEC &iLUT, VEC2 &oLUT)
Definition lut.h:64
float pow(float a, double b)
Definition utils.h:181
void createGammaLUT(double gamma, VECTOR &lut)
Definition lut.h:50
void enforceMonotonicity(LUT &lut)
enforce monotonicity of an array (mostly used for lookup tables)
Definition lut.h:87
just apply exposure and response to linear data
Definition lut.h:377
ExposureResponseFunctor(double exposure, OP &operation)
Definition lut.h:378
vigra::NumericTraits< VT >::RealPromote operator()(VT v)
Definition lut.h:389
functor to apply a LUT to gray and color images.
Definition lut.h:253
vigra::NumericTraits< T >::RealPromote operator()(T v) const
Definition lut.h:364
LUT::value_type lut_type
the functor's first argument type
Definition lut.h:258
vigra::RGBValue< lut_type > apply(vigra::RGBValue< T > v, vigra::VigraFalseType) const
Definition lut.h:357
InvLUTFunctor()
the functor's result type
Definition lut.h:264
lut_type applyLutFloat(lut_type v) const
Definition lut.h:275
InvLUTFunctor(LUT &lut)
create a LUT functor.
Definition lut.h:269
lut_type applyScalar(T v, vigra::VigraFalseType) const
Definition lut.h:337
lut_type applyLutInteger(T i) const
Definition lut.h:308
lut_type apply(T v, vigra::VigraTrueType) const
Definition lut.h:350
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
vigra::RGBValue< lut_type > applyVector(vigra::RGBValue< T > v, vigra::VigraFalseType) const
Definition lut.h:316
functor to apply a LUT to gray and color images.
Definition lut.h:119
vigra::RGBValue< lut_type > applyVector(vigra::RGBValue< VT1 > v, vigra::VigraFalseType) const
Definition lut.h:188
LUTFunctor()
the functor's result type
Definition lut.h:132
lut_type applyScalar(VT1 v, vigra::VigraFalseType) const
Definition lut.h:209
vigra::RGBValue< lut_type > apply(vigra::RGBValue< VT1 > v, vigra::VigraFalseType) const
Definition lut.h:226
LUTFunctor(LUT &lut)
create a LUT functor.
Definition lut.h:138
LUT::value_type lut_type
the functor's first argument type
Definition lut.h:126
lut_type applyLutInteger(VT1 v) const
Definition lut.h:149
lut_type applyScalar(VT1 v, vigra::VigraTrueType) const
Definition lut.h:215
vigra::RGBValue< lut_type > applyVector(vigra::RGBValue< VT1 > v, vigra::VigraTrueType) const
Definition lut.h:198
lut_type apply(VT1 v, vigra::VigraTrueType) const
Definition lut.h:220
vigra::NumericTraits< T >::RealPromote operator()(T v) const
Definition lut.h:233
vigra_ext::ValueTypeTraits< VTIn >::value_type VT1
Definition lut.h:120
lut_type applyLutFloat(double v) const
Definition lut.h:170
T1::value_type value_type
Definition utils.h:153
std::vector< deghosting::BImagePtr > threshold(const std::vector< deghosting::FImagePtr > &inputImages, const double threshold, const uint16_t flags)
Threshold function used for creating alpha masks for images.
Definition threshold.h:41
functions to manage ROI's