PICCANTE  0.4
The hottest HDR imaging library!
ward_histogram_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_WARD_HISTOGRAM_TMO_HPP
19 #define PIC_TONE_MAPPING_WARD_HISTOGRAM_TMO_HPP
20 
21 #include "../base.hpp"
22 #include "../image.hpp"
23 #include "../image_vec.hpp"
24 #include "../histogram.hpp"
25 #include "../util/array.hpp"
26 #include "../filtering/filter_luminance.hpp"
27 #include "../filtering/filter_sampler_2d.hpp"
28 #include "../tone_mapping/tone_mapping_operator.hpp"
29 
30 namespace pic {
31 
33 {
34 protected:
35 
42  Image *ProcessAux(ImageVec imgIn, Image *imgOut)
43  {
44  updateImage(imgIn[0]);
45 
46  images[0] = flt_lum.Process(imgIn, images[0]);
47 
48  int fScaleX, fScaleY;
49  getScaleFiltering(imgIn[0], fScaleX, fScaleY);
50  flt_smp.update(fScaleX, fScaleY, &isb);
51  images[1] = flt_smp.Process(Single(images[0]), images[1]);
52 
53  //compute min and max luminance
54  float LMin, LMax;
55  images[1]->getMinVal(NULL, &LMin);
56  images[1]->getMaxVal(NULL, &LMax);
57 
58  float log_LMin = logf(LMin + epsilon);
59  float log_LMax = logf(LMax + epsilon);
60 
61  float log_LdMin = logf(LdMin + epsilon);
62  float log_LdMax = logf(LdMax + epsilon);
63 
64  float delta_Ld = LdMax - LdMin;
65  float delta_log_L = (log_LMax - log_LMin);
66  float delta_log_Ld = log_LdMax - log_LdMin;
67 
68  //compute the histogram with ceiling
70 
71  if(bCeiling) {
72  h.ceiling(delta_log_L / (float(nBin) * delta_log_Ld));
73  }
74 
76  float maxPcumf = float(Pcum[nBin - 1]);
77 
78  for(int i = 0; i < nBin; i++) {
79  PcumNorm[i] = float(Pcum[i]) / maxPcumf;
80  x[i] = delta_log_L * float(i) / float(nBin - 1) + log_LMin;
81  }
82 
83  #pragma omp parallel for
84  for(int i = 0; i < images[0]->size(); i++) {
85  float L_w = images[0]->data[i];
86 
87  float log_L_w = logf(L_w + epsilon);
88  float Ld = expf(delta_log_Ld * Arrayf::interp(x, PcumNorm, nBin, log_L_w) + log_LdMin) - epsilon;
89 
90  float scale = (MAX(Ld, 0.0f) - LdMin) / (delta_Ld * L_w);
91  scale = MAX(scale, 0.0f);
92 
93  int index = i * imgOut->channels;
94  for(int j = 0; j < imgOut->channels; j++) {
95  int k = index + j;
96  imgOut->data[k] = imgIn[0]->data[k] * scale;
97  }
98  }
99 
100  imgOut->removeSpecials();
101 
102  return imgOut;
103  }
104 
109  void allocate(int nBin = 256)
110  {
111  nBin = nBin > 16 ? nBin : 256;
112 
113  if(this->nBin == nBin) {
114  return;
115  }
116 
117  releaseAux();
118 
119  Pcum = new unsigned int[nBin];
120  PcumNorm = new float[nBin];
121  x = new float[nBin];
122 
123  this->nBin = nBin;
124  }
125 
126  int nBin;
127  float LdMin, LdMax;
130  float epsilon;
131 
132  unsigned int *Pcum;
133  float *PcumNorm, *x;
134 
135  bool bCeiling;
138 
139 public:
140 
148  WardHistogramTMO(int nBin = 256, float LdMin = 1.0f, float LdMax = 100.0f, bool bCeiling = true) : ToneMappingOperator()
149  {
150  this->Pcum = NULL;
151  this->PcumNorm = NULL;
152  this->x = NULL;
153  this->nBin = 0;
154  this->bCeiling = bCeiling;
155 
156  images.clear();
157  images.push_back(NULL);
158  images.push_back(NULL);
159 
160  update(nBin, LdMin, LdMax);
161  }
162 
164  {
165  release();
166  }
167 
171  void releaseAux()
172  {
175  x = delete_vec_s(x);
176  }
177 
184  void update(int nBin = 256, float LdMin = 1.0f, float LdMax = 100.0f)
185  {
186  allocate(nBin);
187 
188  epsilon = 1e-6f;
189 
190  this->LdMax = LdMax > 0.0f ? LdMax : 100.0f;
191  this->LdMin = LdMin > 0.0f ? LdMin : 1.0f;
192 
193  if(this->LdMin > this->LdMax) {
194  LdMin = 1.0f;
195  LdMax = 100.0f;
196  }
197 
198  }
199 
206  static Image* execute(Image *imgIn, Image *imgOut)
207  {
208  WardHistogramTMO wtmo(100, 1.0f, 200.0f);
209  return wtmo.Process(Single(imgIn), imgOut);
210  }
211 };
212 
213 } // end namespace pic
214 
215 #endif /* PIC_TONE_MAPPING_WARD_HISTOGRAM_TMO_HPP */
216 
bool bCeiling
Definition: ward_histogram_tmo.hpp:135
The FilterSampler2D class.
Definition: filter_sampler_2d.hpp:32
void calculate(Image *imgIn, VALUE_SPACE type=VS_LIN, int nBin=256, BBox *box=NULL, int channel=0)
calculate computes the histogram of an input image. In the case of LDR images, they are ssumed to be ...
Definition: histogram.hpp:213
~WardHistogramTMO()
Definition: ward_histogram_tmo.hpp:163
Image * Process(ImageVec imgIn, Image *imgOut=NULL)
Process.
Definition: tone_mapping_operator.hpp:120
static Image * execute(Image *imgIn, Image *imgOut)
execute
Definition: ward_histogram_tmo.hpp:206
float * data
data is the main buffer where pixel values are stored.
Definition: image.hpp:91
int channels
Definition: image.hpp:80
Definition: ward_histogram_tmo.hpp:32
int nBin
Definition: ward_histogram_tmo.hpp:126
static T interp(T *x, T *y, int size, T xval)
interp linearly interpolates x and y data
Definition: array.hpp:569
std::vector< Image * > ImageVec
ImageVec an std::vector of pic::Image.
Definition: image_vec.hpp:29
The Histogram class is a class for creating, managing, loading, and saving histogram for an Image...
Definition: histogram.hpp:37
ImageVec images
Definition: tone_mapping_operator.hpp:35
WardHistogramTMO(int nBin=256, float LdMin=1.0f, float LdMax=100.0f, bool bCeiling=true)
WardHistogramTMO.
Definition: ward_histogram_tmo.hpp:148
The ToneMappingOperator class.
Definition: tone_mapping_operator.hpp:31
FilterLuminance flt_lum
Definition: ward_histogram_tmo.hpp:136
void allocate(int nBin=256)
allocate
Definition: ward_histogram_tmo.hpp:109
void update(int nBin=256, float LdMin=1.0f, float LdMax=100.0f)
update
Definition: ward_histogram_tmo.hpp:184
virtual Image * Process(ImageVec imgIn, Image *imgOut)
Process.
Definition: filter.hpp:390
The FilterLuminance class.
Definition: filter_luminance.hpp:33
unsigned int * Pcum
Definition: ward_histogram_tmo.hpp:132
T * delete_vec_s(T *data)
delete_vec_s
Definition: std_util.hpp:138
void update(int width, int height, ImageSampler *isb)
update
Definition: filter_sampler_2d.hpp:127
uint * bin
Definition: histogram.hpp:131
void updateImage(Image *imgIn)
updateImage
Definition: tone_mapping_operator.hpp:78
void ceiling(float k)
ceiling limits the maximum value of the histogram using Ward algorithm.
Definition: histogram.hpp:364
void release()
release
Definition: tone_mapping_operator.hpp:68
Definition: histogram.hpp:31
float LdMin
Definition: ward_histogram_tmo.hpp:127
float * PcumNorm
Definition: ward_histogram_tmo.hpp:133
FilterSampler2D flt_smp
Definition: ward_histogram_tmo.hpp:137
float epsilon
Definition: ward_histogram_tmo.hpp:130
static T * cumsum(T *vec, int size, T *ret)
cumsum
Definition: array.hpp:438
void releaseAux()
releaseAux
Definition: ward_histogram_tmo.hpp:171
The Image class stores an image as buffer of float.
Definition: image.hpp:60
void removeSpecials()
removeSpecials removes NaN and +/-Inf values and sets them to 0.0f.
float * x
Definition: ward_histogram_tmo.hpp:133
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
float LdMax
Definition: ward_histogram_tmo.hpp:127
#define MAX(a, b)
Definition: math.hpp:73
ImageSamplerBilinear isb
Definition: ward_histogram_tmo.hpp:128
static void getScaleFiltering(Image *imgIn, int &fScaleX, int &fScaleY)
getScaleFiltering
Definition: tone_mapping_operator.hpp:102
The ImageSamplerBilinear class.
Definition: image_sampler_bilinear.hpp:28
Image * ProcessAux(ImageVec imgIn, Image *imgOut)
ProcessAux.
Definition: ward_histogram_tmo.hpp:42
Histogram h
Definition: ward_histogram_tmo.hpp:129