Hugintrunk  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ResponseTransform.h
Go to the documentation of this file.
1 // -*- c-basic-offset: 4 -*-
24 #ifndef _PHOTOMETRIC_VIGNETTING_CORRECTION_H
25 #define _PHOTOMETRIC_VIGNETTING_CORRECTION_H
26 
27 #include <vector>
28 #include <functional>
29 #include "hugin_config.h"
30 #include <random>
31 
32 #include <vigra/stdimage.hxx>
33 #include <vigra/numerictraits.hxx>
34 #include <vigra/array_vector.hxx>
35 
36 #include <hugin_math/hugin_math.h>
37 #include <vigra_ext/lut.h>
38 #include <vigra_ext/utils.h>
39 #include <panodata/SrcPanoImage.h>
40 
41 
42 namespace HuginBase { namespace Photometric {
43 
44 
50 template <class VTIn>
52 {
53 
54  public:
57 
59  typedef std::vector<double> LUT;
60 
61 
62  public:
65 
68 
70  virtual ~ResponseTransform() {};
71 
72  private:
74  void initWithSrcImg(const HuginBase::SrcPanoImage & src);
75 
76 
77  public:
79  void setFlatfield(const vigra::FImage * flat)
80  { m_flatfield = flat; }
81 
83  double calcVigFactor(hugin_utils::FDiff2D d) const;
84 
86  {
88  }
89 
91  typename vigra::NumericTraits<VT1>::RealPromote
92  apply(VT1 v, const hugin_utils::FDiff2D & pos, vigra::VigraTrueType) const;
93 
95  typename vigra::NumericTraits<VT1>::RealPromote
96  apply(VT1 v, const hugin_utils::FDiff2D & pos) const;
97 
99  typename vigra::NumericTraits<vigra::RGBValue<VT1> >::RealPromote
100  apply(vigra::RGBValue<VT1> v, const hugin_utils::FDiff2D & pos, vigra::VigraFalseType) const;
101 
103  typename vigra::NumericTraits<vigra::RGBValue<VT1> >::RealPromote
104  apply(vigra::RGBValue<VT1> v, const hugin_utils::FDiff2D & pos) const;
105 
106 
108  template <class T>
109  typename vigra::NumericTraits<T>::RealPromote
110  operator()(T v, const hugin_utils::FDiff2D & pos) const { return apply(v, pos); }
111 
112 
113 
114  public:
115 
119  const vigra::FImage * m_flatfield;
121  std::vector<double> m_RadialVigCorrCoeff;
126 
128 };
129 
130 
136 template <class VTIn, class VTOut>
138 {
139 
141 
142  public:
144  typedef typename vigra::NumericTraits<VT1>::RealPromote VTInCompReal;
146 
147  typedef std::vector<double> LUT;
148  typedef std::vector<dest_type> LUTD;
149 
150 
151  public:
154 
157 
159  virtual ~InvResponseTransform() {};
160 
161  private:
163  void init(const HuginBase::SrcPanoImage & src);
164 
165 
166  public:
168  void setHDROutput(bool hdrMode, double destExposure);
169 
171  void setOutput(double destExposure, const LUTD & destLut, double scale, double rangeCompression = 0.0);
172 
174  {
175  if (!Base::m_lutR.empty()) {
177  invertLUT();
179  }
180  }
181 
188  double dither(const double &v) const;
189 
191  typename vigra::NumericTraits<dest_type>::RealPromote
192  apply(VT1 v, const hugin_utils::FDiff2D & pos, vigra::VigraTrueType) const;
193 
195  typename vigra::NumericTraits<dest_type>::RealPromote
196  apply(VT1 v, const hugin_utils::FDiff2D & pos) const;
197 
199  typename vigra::NumericTraits<vigra::RGBValue<VT1> >::RealPromote
200  apply(vigra::RGBValue<VT1> v, const hugin_utils::FDiff2D & pos, vigra::VigraFalseType) const;
201 
203  typename vigra::NumericTraits<vigra::RGBValue<VT1> >::RealPromote
204  apply(vigra::RGBValue<VT1> v, const hugin_utils::FDiff2D & pos) const;
205 
206 
208  template <class T>
209  typename vigra::NumericTraits<T>::RealPromote
210  operator()(T v, const hugin_utils::FDiff2D & pos) const
211  {
212  return apply(v, pos);
213  }
214 
216  template <class T, class A>
217  A hdrWeight(T v, A a) const
218  {
219  if (m_hdrMode && a > 0) {
220  return vigra::NumericTraits<A>::fromRealPromote(vigra_ext::getMaxComponent(v)/(double)vigra_ext::LUTTraits<T>::max()*vigra_ext::LUTTraits<A>::max());
221  } else {
222  return a;
223  }
224  }
225 
226  void emitGLSL(std::ostringstream& oss, std::vector<double>& invLut, std::vector<double>& destLut) const;
227 
228  private:
229  void invertLUT()
230  {
231  m_lutRInv.clear();
232  if (!Base::m_lutR.empty())
233  {
234  m_lutRInv.reserve(Base::m_lutR.size());
236  for (int i = 0; i < Base::m_lutR.size(); i++)
237  {
238  const double f = static_cast<double>(i) / (Base::m_lutR.size() - 1);
239  m_lutRInv.push_back(slowRInvFunc(f));
240  };
241  };
242  };
243  protected: // needs be public?
244  LUT m_lutRInv;
249  bool m_hdrMode;
250  double m_intScale;
252 
253  private:
254  std::mt19937 Twister;
255 };
256 
257 
258 }} // namespace
259 
260 
261 
262 
263 // templated implementation ----------------------------------------------------
264 
265 
266 namespace HuginBase { namespace Photometric {
267 
268 
269 template <class VTIn>
271 {
272  m_radiusScale=0;
273  m_flatfield = 0;
274 }
275 
276 template <class VTIn>
278 {
279  initWithSrcImg(src);
280 }
281 
282 
283 template <class VTIn>
285 {
286 // DEBUG_DEBUG(" " << src.getFilename() << ": resp type:" << src.getResponseType() << " expo: " << src.getExposure());
287  m_flatfield = 0;
288  m_src = src;
289  m_radiusScale = 1.0/sqrt(m_src.getSize().x/2.0*m_src.getSize().x/2.0 + m_src.getSize().y/2.0*m_src.getSize().y/2.0);
290  m_srcExposure = m_src.getExposure();
291  //save some variables, direct access is slower since merging of layout mode
292  m_RadialVigCorrCoeff = m_src.getRadialVigCorrCoeff();
293  m_RadialVigCorrCenter = m_src.getRadialVigCorrCenter();
294  m_VigCorrMode = m_src.getVigCorrMode();
295  m_WhiteBalanceRed = m_src.getWhiteBalanceRed();
296  m_WhiteBalanceBlue = m_src.getWhiteBalanceBlue();
297 
298  // build response function lookup table, if required
299  if (m_src.getResponseType() != HuginBase::SrcPanoImage::RESPONSE_LINEAR) {
300  // scale lut to right byte size..
301  double lutLenD = vigra_ext::LUTTraits<VT1>::max();
302  // maximum lut size: 10 bits. Should be enought for most purposes.
303  // and fit into the L1 cache.
304  size_t lutLen=0;
305  if (lutLenD == 1.0 || (lutLenD > ((1<<10)-1))) {
306  lutLen = (1<<10);
307  } else {
308  lutLen = size_t(lutLenD) + 1;
309  }
310  switch (m_src.getResponseType())
311  {
313  {
314  if (lutLen == 1<<10) {
315  vigra_ext::EMoR::createEMoRLUT(m_src.getEMoRParams(), m_lutR);
316  } else {
317  // resize lut, if size doesn't fit
318  LUT tmp;
319  vigra_ext::EMoR::createEMoRLUT(m_src.getEMoRParams(), tmp);
320  m_lutR.resize(lutLen);
321  vigra_ext::resizeLUT(tmp, m_lutR);
322  }
323  }
324  break;
326  m_lutR.resize(lutLen);
327  vigra_ext::createGammaLUT(m_src.getGamma(), m_lutR);
328  break;
329  default:
330  // response curve is stored in src image
331  vigra_fail("ResponseTransform: unknown response function type");
332  break;
333  }
334  m_lutRFunc = vigra_ext::LUTFunctor<VT1, LUT>(m_lutR);
335  }
336 }
337 
338 
339 template <class VTIn>
341 {
342  if (m_VigCorrMode & HuginBase::SrcPanoImage::VIGCORR_RADIAL) {
343  d = d - m_RadialVigCorrCenter;
344  // scale according to
345  d *= m_radiusScale;
346  double vig = m_RadialVigCorrCoeff[0];
347  double r2 = d.x*d.x + d.y*d.y;
348  double r = r2;
349  for (unsigned int i = 1; i < 4; i++) {
350  vig += m_RadialVigCorrCoeff[i] * r;
351  r *= r2;
352  }
353  return vig;
354  } else if (m_VigCorrMode & HuginBase::SrcPanoImage::VIGCORR_FLATFIELD) {
355  // TODO: implement flatfield
356  if (m_flatfield) {
357  int x = std::min(std::max(hugin_utils::roundi(d.x),0), static_cast<int>(m_flatfield->width()-1));
358  int y = std::min(std::max(hugin_utils::roundi(d.y),0), static_cast<int>(m_flatfield->height()-1));
359  return (*m_flatfield)(x,y);
360  } else {
361  return 1;
362  }
363  } else {
364  return 1;
365  }
366 }
367 
368 
369 template <class VTIn>
370 typename vigra::NumericTraits<typename ResponseTransform<VTIn>::VT1>::RealPromote
371 ResponseTransform<VTIn>::apply(typename ResponseTransform<VTIn>::VT1 v, const hugin_utils::FDiff2D & pos, vigra::VigraTrueType) const
372 {
373  typename vigra::NumericTraits<VT1>::RealPromote ret = v;
374  // first, apply vignetting
375 
376  ret = ret*calcVigFactor(pos)*m_srcExposure;
377  if (!m_lutR.empty()) {
378  return m_lutRFunc(ret);
379  } else {
380  return ret;
381  }
382 }
383 
384 template <class VTIn>
385 typename vigra::NumericTraits<vigra::RGBValue<typename ResponseTransform<VTIn>::VT1> >::RealPromote
386 ResponseTransform<VTIn>::apply(vigra::RGBValue<typename ResponseTransform<VTIn>::VT1> v, const hugin_utils::FDiff2D & pos, vigra::VigraFalseType) const
387 {
388  typename vigra::NumericTraits<vigra::RGBValue<VT1> >::RealPromote ret = v;
389  // first, apply vignetting
390  double common = calcVigFactor(pos)*m_srcExposure;
391  ret = ret*common;
392  // apply white balance factors
393  ret.red() = ret.red() * m_WhiteBalanceRed;
394  ret.blue() = ret.blue() * m_WhiteBalanceBlue;
395  // apply response curve
396  if (!m_lutR.empty()) {
397  return m_lutRFunc(ret);
398  } else {
399  return ret;
400  }
401 }
402 
403 template <class VTIn>
404 typename vigra::NumericTraits<typename ResponseTransform<VTIn>::VT1>::RealPromote
405 ResponseTransform<VTIn>::apply(typename ResponseTransform<VTIn>::VT1 v, const hugin_utils::FDiff2D & pos) const
406 {
407  typedef typename vigra::NumericTraits<VT1>::isScalar is_scalar;
408  return apply(v, pos, is_scalar());
409 }
410 
411 template <class VTIn>
412 typename vigra::NumericTraits<vigra::RGBValue<typename ResponseTransform<VTIn>::VT1> >::RealPromote
413 ResponseTransform<VTIn>::apply(vigra::RGBValue<typename ResponseTransform<VTIn>::VT1> v, const hugin_utils::FDiff2D & pos) const
414 {
415  typedef typename vigra::NumericTraits<vigra::RGBValue<VT1> >::isScalar is_scalar;
416  return apply(v, pos, is_scalar());
417 }
418 
419 template <class VTIn, class VTOut>
421 {
422  m_destExposure = 1.0;
423  m_hdrMode = false;
424  m_rangeCompression = 0.0;
425  m_intScale = 1;
426 }
427 
428 template <class VTIn, class VTOut>
430 : Base(src), m_hdrMode(false), m_rangeCompression(0.0)
431 {
432  m_destExposure = 1.0;
433  m_intScale = 1;
434  if (!Base::m_lutR.empty()) {
435  invertLUT();
437  }
438 }
439 
440 template <class VTIn, class VTOut>
442 {
443  m_destExposure = 1.0;
444  m_intScale = 1;
445  m_rangeCompression = 0.0;
446  Base::init(src);
447  if (!Base::m_lutR.empty()) {
448  invertLUT();
449  m_lutRInvFunc = vigra_ext::LUTFunctor<VT1, LUT>(m_lutRInv);
450  }
451 }
452 
453 template <class VTIn, class VTOut>
454 void InvResponseTransform<VTIn,VTOut>::setHDROutput(bool hdrMode, double destExposure)
455 {
456  m_hdrMode = hdrMode;
457  m_intScale = 1;
458  m_destExposure = destExposure;
459  m_destLut.clear();
460  m_rangeCompression = 0.0;
461 }
462 
463 template <class VTIn, class VTOut>
464 void InvResponseTransform<VTIn,VTOut>::setOutput(double destExposure, const LUTD & destLut, double scale, double rangeCompression)
465 {
466  m_hdrMode = false;
467  m_destLut = destLut;
468  if (!m_destLut.empty()) {
469  m_destLutFunc = vigra_ext::LUTFunctor<VTInCompReal, LUTD>(m_destLut);
470  m_rangeCompression = rangeCompression;
471  }
472  else
473  {
474  m_rangeCompression = 0.0;
475  };
476  m_destExposure = destExposure;
477  m_intScale = scale;
478 }
479 
480 
481 template <class VTIn, class VTOut>
482 double InvResponseTransform<VTIn,VTOut>::dither(const double &v) const
483 {
484  std::mt19937 &mt = const_cast<std::mt19937 &>(Twister);
485  double vFraction = v - floor(v);
486  // Only dither values within a certain range of the rounding cutoff point.
487  if (vFraction > 0.25 && vFraction <= 0.75) {
488  // Generate a random number between 0 and 0.5.
489  double random = 0.5 * (double)mt() / UINT_MAX;
490  if ((vFraction - 0.25) >= random) {
491  return ceil(v);
492  } else {
493  return floor(v);
494  }
495  } else {
496  return v;
497  }
498 }
499 
500 
501 template <class VTIn, class VTOut>
502 typename vigra::NumericTraits<typename InvResponseTransform<VTIn,VTOut>::dest_type>::RealPromote
503 InvResponseTransform<VTIn,VTOut>::apply(VT1 v, const hugin_utils::FDiff2D & pos, vigra::VigraTrueType) const
504 {
505  // inverse response
506  typename vigra::NumericTraits<VT1>::RealPromote ret(v);
507  if (!Base::m_lutR.empty()) {
508  ret = m_lutRInvFunc(v);
509  } else {
511  }
512  // inverse vignetting and exposure
513  ret *= m_destExposure / (Base::calcVigFactor(pos) * Base::m_srcExposure);
514  // apply output transform if required
515  if (!m_destLut.empty()) {
516  if (m_rangeCompression > 0.0)
517  {
518  ret = log2(m_rangeCompression*ret + 1) / log2(m_rangeCompression + 1);
519  };
520  ret = m_destLutFunc(ret);
521  }
522  // dither all integer images
523  if ( m_intScale > 1) {
524  return dither(ret * m_intScale);
525  }
526  return ret;
527 }
528 
529 
530 template <class VTIn, class VTOut>
531 typename vigra::NumericTraits<vigra::RGBValue<typename InvResponseTransform<VTIn,VTOut>::VT1> >::RealPromote
532 InvResponseTransform<VTIn,VTOut>::apply(vigra::RGBValue<VT1> v, const hugin_utils::FDiff2D & pos, vigra::VigraFalseType) const
533 {
534  typename vigra::NumericTraits<vigra::RGBValue<VT1> >::RealPromote ret(v);
535  if (!Base::m_lutR.empty()) {
536  ret = m_lutRInvFunc(v);
537  } else {
539  }
540 
541  // inverse vignetting and exposure
542  ret *= m_destExposure/(Base::calcVigFactor(pos)*Base::m_srcExposure);
543  ret.red() /= Base::m_WhiteBalanceRed;
544  ret.blue() /= Base::m_WhiteBalanceBlue;
545  // apply output transform if required
546  if (!m_destLut.empty()) {
547  if (m_rangeCompression > 0)
548  {
549  ret.red() = log2(m_rangeCompression*ret.red() + 1) / log2(m_rangeCompression + 1);
550  ret.blue() = log2(m_rangeCompression*ret.blue() + 1) / log2(m_rangeCompression + 1);
551  ret.green() = log2(m_rangeCompression*ret.green() + 1) / log2(m_rangeCompression + 1);
552  };
553  ret = m_destLutFunc(ret);
554  }
555  // dither 8 bit images.
556  if (m_intScale > 1) {
557  for (size_t i=0; i < 3; i++) {
558  ret[i] = dither(ret[i] * m_intScale);
559  }
560  }
561  return ret;
562 }
563 
564 
565 template <class VTIn, class VTOut>
566 typename vigra::NumericTraits<typename InvResponseTransform<VTIn,VTOut>::dest_type>::RealPromote
568 {
569  typedef typename vigra::NumericTraits<VT1>::isScalar is_scalar;
570  return apply(v, pos, is_scalar());
571 }
572 
573 template <class VTIn, class VTOut>
574 typename vigra::NumericTraits<vigra::RGBValue<typename InvResponseTransform<VTIn,VTOut>::VT1> >::RealPromote
575 InvResponseTransform<VTIn,VTOut>::apply(vigra::RGBValue<VT1> v, const hugin_utils::FDiff2D & pos) const
576 {
577  typedef typename vigra::NumericTraits<vigra::RGBValue<VT1> >::isScalar is_scalar;
578  return apply(v, pos, is_scalar());
579 }
580 
581 template <class VTIn, class VTOut>
582 void
583 InvResponseTransform<VTIn,VTOut>::emitGLSL(std::ostringstream& oss, std::vector<double>& invLut, std::vector<double>& destLut) const
584 {
585  invLut = m_lutRInv;
586  destLut = m_destLut;
587 
588  const double invLutSize = Base::m_lutR.size();
589  const double pixelMax = vigra_ext::LUTTraits<VT1>::max();
590  const double destLutSize = m_destLut.size();
591 
592  oss << " // invLutSize = " << invLutSize << endl
593  << " // pixelMax = " << pixelMax << endl
594  << " // destLutSize = " << destLutSize << endl
595  << " // destExposure = " << m_destExposure << endl
596  << " // srcExposure = " << Base::m_srcExposure << endl
597  << " // whiteBalanceRed = " << Base::m_src.getWhiteBalanceRed() << endl
598  << " // whiteBalanceBlue = " << Base::m_src.getWhiteBalanceBlue() << endl;
599 
600  // alpha hdrWeight
601  if (m_hdrMode)
602  {
603  // hdr weight needs to be calculated from input pixel value
604  // so do it before the whole InvResponseTransformation is done
605  oss << " p.a = max(p.r, max(p.g, p.b));" << endl;
606  }
607 
608  if (!Base::m_lutR.empty()) {
609  oss << " p.rgb = p.rgb * " << (invLutSize - 1.0) << ";" << endl
610  << " vec2 invR = texture2DRect(InvLutTexture, vec2(p.r, 0.0)).sq;" << endl
611  << " vec2 invG = texture2DRect(InvLutTexture, vec2(p.g, 0.0)).sq;" << endl
612  << " vec2 invB = texture2DRect(InvLutTexture, vec2(p.b, 0.0)).sq;" << endl
613  << " vec3 invX = vec3(invR.x, invG.x, invB.x);" << endl
614  << " vec3 invY = vec3(invR.y, invG.y, invB.y);" << endl
615  << " vec3 invA = fract(p.rgb);" << endl
616  << " p.rgb = mix(invX, invY, invA);" << endl;
617  }
618 
619  if (Base::m_src.getVigCorrMode() & HuginBase::SrcPanoImage::VIGCORR_RADIAL) {
620  oss << " // VigCorrMode=VIGCORR_RADIAL" << endl
621  << " float vig = 1.0;" << endl
622  << " {" << endl
623  << " vec2 vigCorrCenter = vec2(" << Base::m_src.getRadialVigCorrCenter().x << ", "
624  << Base::m_src.getRadialVigCorrCenter().y << ");" << endl
625  << " float radiusScale=" << Base::m_radiusScale << ";" << endl
626  << " float radialVigCorrCoeff0 = " << Base::m_src.getRadialVigCorrCoeff()[0] << ";" << endl
627  << " float radialVigCorrCoeff1 = " << Base::m_src.getRadialVigCorrCoeff()[1] << ";" << endl
628  << " float radialVigCorrCoeff2 = " << Base::m_src.getRadialVigCorrCoeff()[2] << ";" << endl
629  << " float radialVigCorrCoeff3 = " << Base::m_src.getRadialVigCorrCoeff()[3] << ";" << endl
630  << " vec2 src = texture2DRect(CoordTexture, gl_TexCoord[0].st).sq;" << endl
631  << " vec2 d = src - vigCorrCenter;" << endl
632  << " d *= radiusScale;" << endl
633  << " vig = radialVigCorrCoeff0;" << endl
634  << " float r2 = dot(d, d);" << endl
635  << " float r = r2;" << endl
636  << " vig += radialVigCorrCoeff1 * r;" << endl
637  << " r *= r2;" << endl
638  << " vig += radialVigCorrCoeff2 * r;" << endl
639  << " r *= r2;" << endl
640  << " vig += radialVigCorrCoeff3 * r;" << endl
641  << " }" << endl;
642  } else if (Base::m_src.getVigCorrMode() & HuginBase::SrcPanoImage::VIGCORR_FLATFIELD) {
643  oss << " // VigCorrMode=VIGCORR_FLATFIELD" << endl
644  << " float vig = 1.0;" << endl;
645  } else {
646  oss << " // VigCorrMode=none" << endl
647  << " float vig = 1.0;" << endl;
648  }
649 
650  oss << " vec3 exposure_whitebalance = vec3("
651  << (m_destExposure / (Base::m_srcExposure * Base::m_src.getWhiteBalanceRed())) << ", "
652  << (m_destExposure / (Base::m_srcExposure)) << ", "
653  << (m_destExposure / (Base::m_srcExposure * Base::m_src.getWhiteBalanceBlue())) << ");" << endl
654  << " p.rgb = (p.rgb * exposure_whitebalance) / vig;" << endl;
655 
656  if (!m_destLut.empty()) {
657  if (m_rangeCompression > 0)
658  {
659  oss << " p.rgb = log2(" << m_rangeCompression << " * p.rgb + 1.0) / " << log2(m_rangeCompression + 1) << ";" << endl;
660  };
661  oss << " p.rgb = p.rgb * " << (destLutSize - 1.0) << ";" << endl
662  << " vec2 destR = texture2DRect(DestLutTexture, vec2(p.r, 0.0)).sq;" << endl
663  << " vec2 destG = texture2DRect(DestLutTexture, vec2(p.g, 0.0)).sq;" << endl
664  << " vec2 destB = texture2DRect(DestLutTexture, vec2(p.b, 0.0)).sq;" << endl
665  << " vec3 destX = vec3(destR.x, destG.x, destB.x);" << endl
666  << " vec3 destY = vec3(destR.y, destG.y, destB.y);" << endl
667  << " vec3 destA = fract(p.rgb);" << endl
668  << " p.rgb = mix(destX, destY, destA);" << endl;
669  }
670 }
671 
672 }} // namespace
673 
674 #endif // _H
double dither(const double &v) const
Dithering is used to fool the eye into seeing gradients that are finer than the precision of the pixe...
void initWithSrcImg(const HuginBase::SrcPanoImage &src)
V getMaxComponent(vigra::RGBValue< V > const &v)
get the maximum component of a vector (also works for single pixel types...)
Definition: utils.h:268
int roundi(T x)
Definition: hugin_math.h:73
void resizeLUT(const VEC &iLUT, VEC2 &oLUT)
Definition: lut.h:64
misc math function &amp; classes used by other parts of the program
static const double A(-0.75)
radiometric transformation, includes exposure, vignetting and white balance
vigra_ext::LUTFunctor< VT1, LUT > m_lutRFunc
vigra::NumericTraits< VT1 >::RealPromote apply(VT1 v, const hugin_utils::FDiff2D &pos, vigra::VigraTrueType) const
function for gray values (ignores white balance :-)
radiometric transformation, includes exposure, vignetting and white balance.
void enforceMonotonicity(LUT &lut)
enforce monotonicity of an array (mostly used for lookup tables)
Definition: lut.h:87
vigra::NumericTraits< VT1 >::RealPromote VTInCompReal
functions to manage ROI&#39;s
functor to apply a LUT to gray and color images.
Definition: lut.h:252
empirical model of response
Definition: SrcPanoImage.h:100
void setHDROutput(bool hdrMode, double destExposure)
vigra::NumericTraits< T >::RealPromote operator()(T v, const hugin_utils::FDiff2D &pos) const
deprecated
radial vignetting correction
Definition: SrcPanoImage.h:93
vigra::NumericTraits< T >::RealPromote operator()(T v, const hugin_utils::FDiff2D &pos) const
deprecated
vigra::NumericTraits< dest_type >::RealPromote apply(VT1 v, const hugin_utils::FDiff2D &pos, vigra::VigraTrueType) const
function for gray values (ignores white balance :-)
vigra_ext::ValueTypeTraits< VTIn >::value_type VT1
vigra_ext::LUTFunctor< VT1, LUT > m_lutRInvFunc
vigra_ext::ValueTypeTraits< VTIn >::value_type VT1
void createGammaLUT(double gamma, VECTOR &lut)
Definition: lut.h:50
void createEMoRLUT(const std::vector< float > &params, VECTOR &lut)
Definition: emor.h:44
double calcVigFactor(hugin_utils::FDiff2D d) const
void init(const HuginBase::SrcPanoImage &src)
vigra_ext::ValueTypeTraits< VTOut >::value_type dest_type
static T max(T x, T y)
Definition: svm.cpp:65
a simple gamma response curve
Definition: SrcPanoImage.h:102
T1::value_type value_type
Definition: utils.h:153
All variables of a source image.
Definition: SrcPanoImage.h:194
void emitGLSL(std::ostringstream &oss, std::vector< double > &invLut, std::vector< double > &destLut) const
void setFlatfield(const vigra::FImage *flat)
static T min(T x, T y)
Definition: svm.cpp:62
void setOutput(double destExposure, const LUTD &destLut, double scale, double rangeCompression=0.0)
output lut
vigra_ext::LUTFunctor< VTInCompReal, LUTD > m_destLutFunc