PICCANTE  0.4
The hottest HDR imaging library!
ferwerda_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_FERWERDA_TMO_HPP
19 #define PIC_TONE_MAPPING_FERWERDA_TMO_HPP
20 
21 #include "../base.hpp"
22 
23 #include "../util/array.hpp"
24 
25 #include "../filtering/filter.hpp"
26 #include "../filtering/filter_luminance.hpp"
27 #include "../tone_mapping/tone_mapping_operator.hpp"
28 
29 namespace pic {
30 
35 {
36 protected:
37  float Ld_Max, Ld_a, Lw_a;
39 
46  Image *ProcessAux(ImageVec imgIn, Image *imgOut)
47  {
48  updateImage(imgIn[0]);
49 
50  //compute luminance and its statistics
51  images[0] = flt_lum.Process(imgIn, images[0]);
52 
53  if(Lw_a < 0.0f) {
54  float maxVal;
55  images[0]->getMaxVal(NULL, &maxVal);
56  Lw_a = maxVal / 2.0f;
57  }
58 
59  float mC = Tp(Ld_a) / Tp(Lw_a);
60  float mR = Ts(Ld_a) / Ts(Lw_a);
61  float k = WalravenValetonK(Lw_a);
62 
63  int channels = imgIn[0]->channels;
64  float *scale = new float[channels];
65 
66  if(channels == 3) {
67  scale[0] = 1.05f;
68  scale[1] = 0.97f;
69  scale[2] = 1.27f;
70  } else {
71  Arrayf::assign(1.0f, scale, channels);
72  }
73 
74  for(int i = 0; i < channels; i++) {
75  scale[i] *= (mR * k);
76  }
77 
78  #pragma omp parallel for
79  for(int i = 0; i < imgIn[0]->size(); i += channels) {
80 
81  int indexL = i / channels;
82 
83  for(int j = 0; j < channels; j++) {
84  int index = i + j;
85  imgOut->data[index] = imgIn[0]->data[index] * mC +
86  images[0]->data[indexL] * scale[j];
87  }
88  }
89 
90  //NOTE: this is done to have values in [0,1] and not in cd/m^2!
91  *imgOut /= Ld_Max;
92 
93  return imgOut;
94  }
95 
96 public:
97 
104  FerwerdaTMO(float Ld_Max = 100.0f, float Ld_a = 50.0f, float Lw_a = 50.0f) : ToneMappingOperator()
105  {
106  images.push_back(NULL);
107  update(Ld_Max, Ld_a, Lw_a);
108  }
109 
111  {
112  release();
113  }
114 
121  void update(float Ld_Max = 100.0f, float Ld_a = 50.0f, float Lw_a = 50.0f)
122  {
123  this->Ld_Max = Ld_Max > 0.0f ? Ld_Max : 100.0f;
124  this->Ld_a = Ld_a > 0.0f ? Ld_a : (this->Ld_Max / 2.0f);
125  this->Lw_a = Lw_a;
126  }
127 
133  static float Ts(float x)
134  {
135  float t = log10f(x);
136  float y;
137 
138  if(t <= -3.94f) {
139  y = -2.86f;
140  } else {
141  if(t >= -1.44) {
142  y = t - 0.395f;
143  } else {
144  y = powf(0.405f * t + 1.6f, 2.18f) - 2.86f;
145  }
146  }
147 
148  y = powf(10.0f, y);
149 
150  return y;
151  }
152 
158  static float Tp(float x)
159  {
160  float t = log10f(x);
161  float y;
162 
163  if(t <= -2.6f) {
164  y = -0.72f;
165  } else {
166  if(t >= 1.9f) {
167  y = t - 1.255f;
168  } else {
169  y = powf(0.249f * t + 0.65f, 2.7f) - 0.72f;
170  }
171  }
172 
173  y = powf(10.0f, y);
174 
175  return y;
176  }
177 
184  static float WalravenValetonK(float Lw_a, float sigma = 100.0f)
185  {
186  float k = (sigma - Lw_a / 4.0f) / (sigma + Lw_a);
187  return (k > 0.0f) ? k : 0.0f;
188  }
189 
196  static Image *execute(Image *imgIn, Image *imgOut)
197  {
198  FerwerdaTMO ftmo(200.0f, -1.0f, -1.0f);
199  return ftmo.Process(Single(imgIn), imgOut);
200  }
201 };
202 } // end namespace pic
203 
204 #endif /* PIC_TONE_MAPPING_FERWERDA_TMO_HPP */
205 
float Ld_a
Definition: ferwerda_tmo.hpp:37
Image * Process(ImageVec imgIn, Image *imgOut=NULL)
Process.
Definition: tone_mapping_operator.hpp:120
float * data
data is the main buffer where pixel values are stored.
Definition: image.hpp:91
std::vector< Image * > ImageVec
ImageVec an std::vector of pic::Image.
Definition: image_vec.hpp:29
ImageVec images
Definition: tone_mapping_operator.hpp:35
float Lw_a
Definition: ferwerda_tmo.hpp:37
static float Tp(float x)
Tp computes the gamma function used in Ferwerda TMO for Photopic levels (cones&#39; cells).
Definition: ferwerda_tmo.hpp:158
FerwerdaTMO(float Ld_Max=100.0f, float Ld_a=50.0f, float Lw_a=50.0f)
FerwerdaTMO.
Definition: ferwerda_tmo.hpp:104
void update(float Ld_Max=100.0f, float Ld_a=50.0f, float Lw_a=50.0f)
update
Definition: ferwerda_tmo.hpp:121
The ToneMappingOperator class.
Definition: tone_mapping_operator.hpp:31
static float WalravenValetonK(float Lw_a, float sigma=100.0f)
WalravenValetonK.
Definition: ferwerda_tmo.hpp:184
Image * ProcessAux(ImageVec imgIn, Image *imgOut)
ProcessAux.
Definition: ferwerda_tmo.hpp:46
virtual Image * Process(ImageVec imgIn, Image *imgOut)
Process.
Definition: filter.hpp:390
The FilterLuminance class.
Definition: filter_luminance.hpp:33
FilterLuminance flt_lum
Definition: ferwerda_tmo.hpp:38
void updateImage(Image *imgIn)
updateImage
Definition: tone_mapping_operator.hpp:78
~FerwerdaTMO()
Definition: ferwerda_tmo.hpp:110
void release()
release
Definition: tone_mapping_operator.hpp:68
The FerwerdaTMO class.
Definition: ferwerda_tmo.hpp:34
static float Ts(float x)
Ts computes the gamma function used in Ferwerda TMO for Scotopic levels (rods&#39; cells).
Definition: ferwerda_tmo.hpp:133
static Image * execute(Image *imgIn, Image *imgOut)
execute
Definition: ferwerda_tmo.hpp:196
The Image class stores an image as buffer of float.
Definition: image.hpp:60
float Ld_Max
Definition: ferwerda_tmo.hpp:37
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
static T * assign(T *data, int size, T *ret)
assign
Definition: array.hpp:464