PICCANTE  0.4
The hottest HDR imaging library!
lischinski_tmo.hpp
Go to the documentation of this file.
1 /*
2 
3 PICCANTE
4 The hottest HDR imaging library!
5 http://vcg.isti.cnr.it/piccante
6 
7 Copyright (C) 2014
8 Visual Computing Laboratory - ISTI CNR
9 http://vcg.isti.cnr.it
10 First author: Francesco Banterle
11 
12 This Source Code Form is subject to the terms of the Mozilla Public
13 License, v. 2.0. If a copy of the MPL was not distributed with this
14 file, You can obtain one at http://mozilla.org/MPL/2.0/.
15 
16 */
17 
18 #ifndef PIC_TONE_MAPPING_LISCHINSKI_TMO_HPP
19 #define PIC_TONE_MAPPING_LISCHINSKI_TMO_HPP
20 
21 #include "../base.hpp"
22 #include "../util/math.hpp"
23 #include "../algorithms/lischinski_minimization.hpp"
24 #include "../tone_mapping/reinhard_tmo.hpp"
25 #include "../tone_mapping/tone_mapping_operator.hpp"
26 
27 namespace pic {
28 
30 {
31 protected:
33 
34  float alpha, whitePoint;
35 
42  Image *ProcessAux(ImageVec imgIn, Image *imgOut)
43  {
44  updateImage(imgIn[0]);
45 
46  //extract luminance
47  images[0] = flt_lum.Process(imgIn, images[0]);
48 
49  float minL, maxL, Lav;
50 
51  images[0]->getMinVal(NULL, &minL);
52  images[0]->getMaxVal(NULL, &maxL);
53  images[0]->getLogMeanVal(NULL, &Lav);
54 
55  float minL_log = log2fPlusEpsilon(minL);
56  float maxL_log = log2fPlusEpsilon(maxL);
57 
58  int Z = int(ceilf(maxL_log - minL_log));
59 
60  if(Z <= 0) {
61  return imgOut;
62  }
63 
64  if(alpha <= 0.0f) {
65  alpha = ReinhardTMO::estimateAlpha(minL, maxL, Lav);
66  }
67 
68  if(whitePoint <= 0.0f) {
70  }
71 
72  float whitePoint_sq = whitePoint * whitePoint;
73 
74  //choose the representative Rz for each zone
75  std::vector<float> *zones = new std::vector<float>[Z];
76  float *fstop = new float[Z];
77  float *Rz = new float[Z];
78 
79  Array<float>::assign(0.0f, Rz, Z);
80  Array<float>::assign(0.0f, fstop, Z);
81 
82  for(int i = 0; i < images[0]->size(); i++) {
83  float L = images[0]->data[i];
84  float L_log = log2fPlusEpsilon(L);
85 
86  int zone = CLAMP(int(ceilf(L_log - minL_log)), Z);
87  zones[zone].push_back(L);
88  }
89 
90  for(int i = 0; i < Z; i++) {
91  if(!zones[i].empty()) {
92  std::sort(zones[i].begin(), zones[i].end());
93  Rz[i] = zones[i][zones[i].size() >> 1];
94 
95  if(Rz[i] > 0.0f) {
96  float Rz_s = Rz[i] * alpha / Lav; //photographic operator
97  float f = (Rz_s * (1.0f + Rz_s / whitePoint_sq) ) / (1.0f + Rz_s);
98  fstop[i] = log2fPlusEpsilon(f / Rz[i]);
99  }
100  }
101  }
102 
103  //create the fstop map
104  images[0]->applyFunction(log2fPlusEpsilon);
105 
106  if(images[1] == NULL) {
107  images[1] = images[0]->allocateSimilarOne();
108  }
109 
110  for(int i = 0; i < images[0]->size(); i++) {
111  float L_log = images[0]->data[i];
112  int zone = CLAMP(int(ceilf(L_log - minL_log)), Z);
113  images[1]->data[i] = fstop[zone];
114  }
115 
116  //run Lischinski minimization
117  images[2] = LischinskiMinimization(images[0], images[1], NULL, 0.007f, images[2]);
118 
119  images[2]->applyFunction(pow2f);
120 
121  *imgOut = *imgIn[0];
122  *imgOut *= images[2];
123 
124  delete[] zones;
125  delete[] Rz;
126  delete[] fstop;
127 
128  return imgOut;
129  }
130 
131 public:
132 
138  LischinskiTMO(float alpha = 0.15f, float whitePoint = 1e6f)
139  {
140  images.push_back(NULL);
141  images.push_back(NULL);
142  images.push_back(NULL);
144  }
145 
151  void update(float alpha = 0.15f, float whitePoint = 1e6f)
152  {
153  this->alpha = alpha;
154  this->whitePoint = whitePoint;
155  }
156 
163  static Image *execute(Image *imgIn, Image *imgOut)
164  {
165  LischinskiTMO ltmo(0.15f, 1e6f);
166  return ltmo.Process(Single(imgIn), imgOut);
167  }
168 };
169 
170 } // end namespace pic
171 
172 #endif /* PIC_TONE_MAPPING_LISCHINSKI_TMO_HPP */
173 
Image * Process(ImageVec imgIn, Image *imgOut=NULL)
Process.
Definition: tone_mapping_operator.hpp:120
static float estimateAlpha(float LMin, float LMax, float logAverage)
estimateAlpha
Definition: reinhard_tmo.hpp:167
float whitePoint
Definition: lischinski_tmo.hpp:34
std::vector< Image * > ImageVec
ImageVec an std::vector of pic::Image.
Definition: image_vec.hpp:29
ImageVec images
Definition: tone_mapping_operator.hpp:35
The ToneMappingOperator class.
Definition: tone_mapping_operator.hpp:31
virtual Image * Process(ImageVec imgIn, Image *imgOut)
Process.
Definition: filter.hpp:390
The FilterLuminance class.
Definition: filter_luminance.hpp:33
void update(float alpha=0.15f, float whitePoint=1e6f)
update
Definition: lischinski_tmo.hpp:151
void updateImage(Image *imgIn)
updateImage
Definition: tone_mapping_operator.hpp:78
PIC_INLINE Image * LischinskiMinimization(Image *L, Image *g, Image *omega=NULL, float omega_global=1.0f, Image *gOut=NULL, float alpha=1.0f, float lambda=0.4f, float LISCHINSKI_EPSILON=1e-4f)
LischinskiMinimization.
Definition: lischinski_minimization.hpp:82
PIC_INLINE float log2fPlusEpsilon(float x)
log2fPlusEpsilon
Definition: math.hpp:395
static Image * execute(Image *imgIn, Image *imgOut)
execute
Definition: lischinski_tmo.hpp:163
Image * ProcessAux(ImageVec imgIn, Image *imgOut)
ProcessAux.
Definition: lischinski_tmo.hpp:42
float alpha
Definition: lischinski_tmo.hpp:34
LischinskiTMO(float alpha=0.15f, float whitePoint=1e6f)
LischinskiTMO.
Definition: lischinski_tmo.hpp:138
The Image class stores an image as buffer of float.
Definition: image.hpp:60
PIC_INLINE float pow2f(float x)
pow2f
Definition: math.hpp:405
FilterLuminance flt_lum
Definition: lischinski_tmo.hpp:32
PIC_INLINE ImageVec Single(Image *img)
Single creates an std::vector which contains img; this is for filters input.
Definition: image_vec.hpp:36
Definition: bilateral_separation.hpp:25
#define CLAMP(x, a)
Definition: math.hpp:77
static T * assign(T *data, int size, T *ret)
assign
Definition: array.hpp:464
Definition: lischinski_tmo.hpp:29
static float estimateWhitePoint(float LMin, float LMax)
estimateWhitePoint
Definition: reinhard_tmo.hpp:185