PICCANTE  0.4
The hottest HDR imaging library!
exposure_fusion.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_GL_TONE_MAPPING_EXPOSURE_FUSION_TMO_HPP
19 #define PIC_GL_TONE_MAPPING_EXPOSURE_FUSION_TMO_HPP
20 
21 #include "../../util/math.hpp"
22 
23 #include "../../util/std_util.hpp"
24 
25 #include "../../gl/tone_mapping/get_all_exposures.hpp"
26 
27 #include "../../gl/algorithms/pyramid.hpp"
28 #include "../../gl/filtering/filter_luminance.hpp"
29 #include "../../gl/filtering/filter_exposure_fusion_weights.hpp"
30 #include "../../gl/filtering/filter_op.hpp"
31 
32 namespace pic {
33 
38 {
39 protected:
40  std::vector<FilterGL *> filters;
41  std::vector<PyramidGL *> pyramids;
43 
47 
49 
51 
52  float wC, wS, wE;
53 
55  bool bAllocate;
56 
61  {
62  if(!bAllocatedFilters) {
63  flt_lum = new FilterGLLuminance();
65  flt_lum->bDelete = true;
66  filters.push_back(flt_lum);
67 
68  removeNegative = new FilterGLOp("max(I0, vec4(0.0))", true, NULL, NULL);
69  removeNegative->bDelete = true;
70  filters.push_back(removeNegative);
71 
73  flt_weights->bDelete = true;
74  filters.push_back(flt_weights);
75  bAllocatedFilters = true;
76  }
77  }
78 
79 public:
83  ExposureFusionGL(float wC = 1.0f, float wE = 1.0f, float wS = 1.0f)
84  {
85  bAllocate = false;
86  bAllocatedFilters = false;
87 
88  update(wC, wE, wS);
89 
90  lum = NULL;
91  acc = NULL;
92  weights = NULL;
93 
94  pW = NULL;
95  pI = NULL;
96  pOut = NULL;
97  }
98 
100  {
101  stdVectorClear<ImageGL>(images);
102  stdVectorClear<PyramidGL>(pyramids);
103  stdVectorClear<FilterGL>(filters);
104  }
105 
112  void update(float wC = 1.0f, float wE = 1.0f, float wS = 1.0f)
113  {
114  this->wC = CLAMPi(wC, 0.0f, 1.0f);
115  this->wE = CLAMPi(wE, 0.0f, 1.0f);
116  this->wS = CLAMPi(wS, 0.0f, 1.0f);
117  }
118 
123  void allocate(ImageGLVec imgIn)
124  {
125  if(!bAllocate) {
126 
127  int width = imgIn[0]->width;
128  int height = imgIn[0]->height;
129  int channels = imgIn[0]->channels;
130 
131  acc = new ImageGL(1, width, height, 1, IMG_GPU, GL_TEXTURE_2D);
132  lum = new ImageGL(1, width, height, 1, IMG_GPU, GL_TEXTURE_2D);
133  weights = new ImageGL(1, width, height, 1, IMG_GPU, GL_TEXTURE_2D);
134 
135  images.push_back(acc);
136  images.push_back(lum);
137  images.push_back(weights);
138 
139  int limitLevel = 2;
140  pW = new PyramidGL(width, height, 1, false, limitLevel);
141  pI = new PyramidGL(width, height, channels, true, limitLevel);
142  pOut = new PyramidGL(width, height, channels, true, limitLevel);
143 
144  pyramids.push_back(pW);
145  pyramids.push_back(pI);
146  pyramids.push_back(pOut);
147 
148  allocateFilters();
149 
150  bAllocate = true;
151  } else {
152  if(!pOut->stack[0]->isSimilarType(imgIn[0])) {
153  bAllocate = false;
154 
155  stdVectorClear<ImageGL>(images);
156  stdVectorClear<PyramidGL>(pyramids);
157 
158  allocate(imgIn);
159  }
160  }
161  }
162 
169  ImageGL *Process(ImageGL *imgIn, ImageGL *imgOut)
170  {
171  pic::ImageGLVec img_vec = getAllExposuresImagesGL(imgIn, 2.2f);
172 
173  imgOut = ProcessStack(img_vec, imgOut);
174 
175  stdVectorClear<ImageGL>(img_vec);
176 
177  return imgOut;
178  }
179 
186  ImageGL *ProcessStack(ImageGLVec imgIn, ImageGL *imgOut = NULL)
187  {
188  auto n = imgIn.size();
189 
190  if(n < 2) {
191  return imgOut;
192  }
193 
194  allocate(imgIn);
195 
196  //compute weights values
197  *acc = 0.0f;
198  for(auto j = 0; j < n; j++) {
199  lum = flt_lum->Process(SingleGL(imgIn[j]), lum);
200  weights = flt_weights->Process(DoubleGL(lum, imgIn[j]), weights);
201 
202  *acc += *weights;
203  }
204 
205  //accumulate on a pyramid
206  pOut->setValue(0.0f);
207 
208  for(auto j = 0; j < n; j++) {
209  lum = flt_lum->Process(SingleGL(imgIn[j]), lum);
210  weights = flt_weights->Process(DoubleGL(lum, imgIn[j]), weights);
211 
212  //normalization
213  *weights /= *acc;
214 
215  pW->update(weights);
216  pI->update(imgIn[j]);
217 
218  pI->mul(pW);
219  pOut->add(pI);
220  }
221 
222  //final result
223  imgOut = pOut->reconstruct(imgOut);
224 
225  float *minVal = imgOut->getMinVal(NULL);
226  float *maxVal = imgOut->getMaxVal(NULL);
227 
228  int ind;
229  float minV = Arrayf::getMin(minVal, imgOut->channels, ind);
230  float maxV = Arrayf::getMax(maxVal, imgOut->channels, ind);
231  *imgOut -= minV;
232  *imgOut /= (maxV - minV);
233  imgOut = removeNegative->Process(SingleGL(imgOut), imgOut);
234 
235  return imgOut;
236  }
237 };
238 
239 } // end namespace pic
240 
241 #endif /* PIC_GL_TONE_MAPPING_EXPOSURE_FUSION_TMO_HPP */
242 
ImageGL * lum
Definition: exposure_fusion.hpp:48
static T getMax(T *data, int size, int &ind)
getMax
Definition: array.hpp:516
Definition: filter_luminance.hpp:28
PIC_INLINE ImageGLVec getAllExposuresImagesGL(ImageGL *imgIn, float gamma=2.2f)
getAllExposuresImagesGL converts an HDR image into a stack of LDR images
Definition: get_all_exposures.hpp:34
void update(ImageGL *img)
update
The PyramidGL class.
Definition: pyramid.hpp:35
bool bAllocate
Definition: exposure_fusion.hpp:55
PyramidGL * pI
Definition: exposure_fusion.hpp:50
void mul(const PyramidGL *pyr)
mul
bool bDelete
Definition: display.hpp:54
ImageGL * acc
Definition: exposure_fusion.hpp:48
PIC_INLINE ImageGLVec SingleGL(ImageGL *img)
SingleGL creates a single for filters input.
Definition: image_vec.hpp:39
PyramidGL * pW
Definition: exposure_fusion.hpp:50
Definition: filter_op.hpp:28
ImageGL * weights
Definition: exposure_fusion.hpp:48
void update(LUMINANCE_TYPE type)
update
FilterGLOp * removeNegative
Definition: exposure_fusion.hpp:46
The ImageGL class.
Definition: image.hpp:42
float wC
Definition: exposure_fusion.hpp:52
float * getMinVal(float *ret=NULL)
getMinVal
Definition: image.hpp:431
void setValue(float value)
setValue
The FilterGLExposureFusionWeights class.
Definition: filter_exposure_fusion_weights.hpp:30
int size() const
size computes the number of values.
Definition: filter_radial_basis_function.hpp:481
void allocateFilters()
allocateFilters
Definition: exposure_fusion.hpp:60
ImageGLVec images
Definition: exposure_fusion.hpp:42
void add(const PyramidGL *pyr)
add
virtual ImageGL * Process(ImageGLVec imgIn, ImageGL *imgOut)
Process.
Definition: display.hpp:258
ExposureFusionGL(float wC=1.0f, float wE=1.0f, float wS=1.0f)
ExposureFusionGL.
Definition: exposure_fusion.hpp:83
bool bAllocatedFilters
Definition: exposure_fusion.hpp:54
void allocate(ImageGLVec imgIn)
allocate
Definition: exposure_fusion.hpp:123
void update(float wC=1.0f, float wE=1.0f, float wS=1.0f)
update
Definition: exposure_fusion.hpp:112
~ExposureFusionGL()
Definition: exposure_fusion.hpp:99
ImageGL * Process(ImageGL *imgIn, ImageGL *imgOut)
Process.
Definition: exposure_fusion.hpp:169
ImageGLVec stack
Definition: pyramid.hpp:78
FilterGLExposureFusionWeights * flt_weights
Definition: exposure_fusion.hpp:45
static T getMin(T *data, int size, int &ind)
getMin
Definition: array.hpp:542
FilterGLLuminance * flt_lum
Definition: exposure_fusion.hpp:44
#define CLAMPi(x, a, b)
Definition: math.hpp:81
The ExposureFusionGL class.
Definition: exposure_fusion.hpp:37
PIC_INLINE ImageGLVec DoubleGL(ImageGL *img1, ImageGL *img2)
DoubleGL creates a couple for filters input.
Definition: image_vec.hpp:52
Definition: bilateral_separation.hpp:25
PyramidGL * pOut
Definition: exposure_fusion.hpp:50
The FilterGLLuminance class.
Definition: filter_luminance.hpp:30
std::vector< PyramidGL * > pyramids
Definition: exposure_fusion.hpp:41
ImageGL * ProcessStack(ImageGLVec imgIn, ImageGL *imgOut=NULL)
ProcessStack.
Definition: exposure_fusion.hpp:186
std::vector< ImageGL * > ImageGLVec
ImageGLVec an std::vector of pic::ImageGL.
Definition: display.hpp:32
float wS
Definition: exposure_fusion.hpp:52
Definition: image.hpp:37
ImageGL * reconstruct(ImageGL *imgOut)
reconstruct
std::vector< FilterGL * > filters
Definition: exposure_fusion.hpp:40
float wE
Definition: exposure_fusion.hpp:52
std::vector< ImageGL * > ImageGLVec
ImageGLVec an std::vector of pic::ImageGL.
Definition: image_vec.hpp:32