PICCANTE  0.4
The hottest HDR imaging library!
pyramid.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_ALGORITHMS_PYRAMID_HPP
19 #define PIC_GL_ALGORITHMS_PYRAMID_HPP
20 
21 #include "../../base.hpp"
22 
23 #include "../../gl/image.hpp"
24 
25 #include "../../gl/filtering/filter_gaussian_2d.hpp"
26 #include "../../gl/filtering/filter_sampler_2d.hpp"
27 #include "../../gl/filtering/filter_blend.hpp"
28 #include "../../gl/filtering/filter_op.hpp"
29 
30 namespace pic {
31 
35 class PyramidGL
36 {
37 protected:
40 
45  std::vector<FilterGL *> filters;
46 
48 
52  void initFilters();
53 
63  void create(ImageGL *img, bool lapGauss, int limitLevel);
64 
68  void release()
69  {
70  stdVectorClear<ImageGL>(stack);
71  stdVectorClear<ImageGL>(trackerUp);
72  stdVectorClear<ImageGL>(trackerRec);
73  stdVectorClear<FilterGL>(filters);
74  }
75 
76 public:
77 
79 
86  PyramidGL(ImageGL *img, bool lapGauss, int limitLevel);
87 
96  PyramidGL(int width, int height, int channels, bool lapGauss, int limitLevel);
97 
98  ~PyramidGL();
99 
104  void update(ImageGL *img);
105 
110  void setValue(float value);
111 
116  void mul(const PyramidGL *pyr);
117 
122  void mulNeg(const PyramidGL *pyr);
123 
128  void add(const PyramidGL *pyr);
129 
135  ImageGL *reconstruct(ImageGL *imgOut);
136 
142  void blend(PyramidGL *pyr, PyramidGL *weight);
143 
148  int size()
149  {
150  return int(stack.size());
151  }
152 
158  Image *get(int index)
159  {
160  return stack[index % stack.size()];
161  }
162 
166  void setNULL()
167  {
168  release();
169 
170  flt_gauss = NULL;
171  flt_sampler = NULL;
172  flt_sub = NULL;
173  flt_add = NULL;
174  flt_blend = NULL;
175 
176  bCreated = false;
177  }
178 };
179 
180 PIC_INLINE PyramidGL::PyramidGL(ImageGL *img, bool lapGauss, int limitLevel = 1)
181 {
182  setNULL();
183 
184  create(img, lapGauss, limitLevel);
185 }
186 
187 PIC_INLINE PyramidGL::PyramidGL(int width, int height, int channels, bool lapGauss, int limitLevel = 1)
188 {
189  setNULL();
190 
191  ImageGL *img = new ImageGL(1, width, height, channels, IMG_GPU, GL_TEXTURE_2D);
192  *img = 0.0f;
193 
194  create(img, lapGauss, limitLevel);
195 
196  delete img;
197 }
198 
200 {
201  release();
202 }
203 
205 {
206  if(!bCreated) {
207  flt_gauss = new FilterGLGaussian2D(1.0f);
208  filters.push_back(flt_gauss);
209 
210  flt_sampler = new FilterGLSampler2D(0.5f);
211  filters.push_back(flt_sampler);
212 
214  filters.push_back(flt_add);
215 
217  filters.push_back(flt_sub);
218 
219  flt_blend = new FilterGLBlend();
220  filters.push_back(flt_blend);
221 
222  bCreated = true;
223  }
224 }
225 
226 PIC_INLINE void PyramidGL::create(ImageGL *img, bool lapGauss, int limitLevel = 1)
227 {
228  if(img == NULL) {
229  return;
230  }
231 
232  limitLevel = MAX(limitLevel, 0);
233 
234  this->limitLevel = limitLevel;
235  this->lapGauss = lapGauss;
236 
237  initFilters();
238 
239  int levels = MAX(log2(MIN(img->width, img->height)) - limitLevel, 0);
240 
241  ImageGL *tmpImg = img;
242  ImageGL *tmpG = NULL;
243  ImageGL *tmpD = NULL;
244 
245  for(int i = 0; i < levels; i++) {
246  tmpG = flt_gauss->Process(SingleGL(tmpImg), NULL);
247  tmpD = flt_sampler->Process(SingleGL(tmpG), NULL);
248 
249  if(lapGauss) { //Laplacian Pyramid
250  flt_sub->Process(DoubleGL(tmpImg, tmpD), tmpG);
251  stack.push_back(tmpG);
252  } else { //Gaussian Pyramid
253  *tmpG = *tmpImg;
254  stack.push_back(tmpG);
255  }
256 
257  if(i < (levels - 1)) {
258  trackerUp.push_back(tmpD);
259  }
260 
261  tmpImg = tmpD;
262  }
263 
264  if(tmpD != NULL) {
265  stack.push_back(tmpD);
266  }
267 
268 #ifdef PIC_DEBUG
269  printf("PyramidGL size: %d\n", int(stack.size()));
270 #endif
271 }
272 
274 {
275  if(img == NULL) {
276  return;
277  }
278 
279  if(stack.empty()) {
280  return;
281  }
282 
283  if(!stack[0]->isSimilarType(img)) {
284  return;
285  }
286 
287  ImageGL *tmpG = NULL;
288  ImageGL *tmpD = NULL;
289  ImageGL *tmpImg = img;
290 
291  int levels = MAX(log2(MIN(tmpImg->width, tmpImg->height)) - limitLevel, 1);
292 
293  for(int i = 0; i < levels; i++) {
294  tmpG = flt_gauss->Process(SingleGL(tmpImg), stack[i]);
295 
296  if(i == (levels - 1) ) {
297  tmpD = flt_sampler->Process(DoubleGL(tmpG, stack[i + 1]), stack[i + 1]);
298  } else {
299  tmpD = flt_sampler->Process(DoubleGL(tmpG, trackerUp[i]), trackerUp[i]);
300  }
301 
302  if(lapGauss) { //Laplacian Pyramid
303  flt_sub->Process(DoubleGL(tmpImg, tmpD), tmpG);
304  } else { //Gaussian Pyramid
305  *tmpG = *tmpImg;
306  }
307 
308  tmpImg = tmpD;
309  }
310 }
311 
313 {
314  if(stack.size() < 2) {
315  return imgOut;
316  }
317 
318  int n = int(stack.size()) - 1;
319  ImageGL *tmp = stack[n];
320 
321  if(trackerRec.empty()) {
322  for(int i = n; i >= 2; i--) {
323  ImageGL *tmp2 = flt_add->Process(DoubleGL(stack[i - 1], tmp), NULL);
324  trackerRec.push_back(tmp2);
325  tmp = tmp2;
326  }
327  } else {
328  int c = 0;
329 
330  for(int i = n; i >= 2; i--) {
331  flt_add->Process(DoubleGL(stack[i - 1], tmp), trackerRec[c]);
332  tmp = trackerRec[c];
333  c++;
334  }
335  }
336 
337  imgOut = flt_add->Process(DoubleGL(stack[0], tmp), imgOut);
338 
339  return imgOut;
340 }
341 
343 {
344  for(unsigned int i = 0; i < stack.size(); i++) {
345  *stack[i] = value;
346  }
347 }
348 
350 {
351  if(stack.size() != pyr->stack.size()) {
352  return;
353  }
354 
355  for(unsigned int i = 0; i < stack.size(); i++) {
356  *stack[i] *= *pyr->stack[i];
357  }
358 }
359 
361 {
362  if(stack.size() != pyr->stack.size()) {
363  return;
364  }
365 
366  for(unsigned int i = 0; i < stack.size(); i++) {
367  *stack[i] += *pyr->stack[i];
368  }
369 }
370 
372 {
373  if(stack.size() != pyr->stack.size() ||
374  stack.size() != weight->stack.size()) {
375  return;
376  }
377 
378  for(unsigned int i = 0; i < stack.size(); i++) {
379  flt_blend->Process(TripleGL(stack[i], pyr->stack[i], weight->stack[i]), stack[i]);
380  }
381 }
382 
383 } // end namespace pic
384 
385 #endif /* PIC_GL_ALGORITHMS_PYRAMID_HPP */
386 
The FilterGLSampler2D class.
Definition: display.hpp:29
PIC_INLINE int log2(int n)
log2 computes logarithm in base 2 for integers.
Definition: math.hpp:302
void setNULL()
setNULL
Definition: pyramid.hpp:166
static FilterGLOp * CreateOpSub(bool bType)
CreateOpSub.
Definition: filter_op.hpp:141
void update(ImageGL *img)
update
The PyramidGL class.
Definition: pyramid.hpp:35
void initFilters()
initFilters
void mul(const PyramidGL *pyr)
mul
PIC_INLINE ImageGLVec SingleGL(ImageGL *img)
SingleGL creates a single for filters input.
Definition: image_vec.hpp:39
Definition: filter_op.hpp:28
The FilterGLBlend class.
Definition: display.hpp:29
FilterGLGaussian2D * flt_gauss
Definition: pyramid.hpp:41
ImageGL * Process(ImageGLVec imgIn, ImageGL *imgOut)
Process.
Definition: filter_npasses.hpp:323
void mulNeg(const PyramidGL *pyr)
mulNeg
The ImageGL class.
Definition: image.hpp:42
static FilterGLOp * CreateOpAdd(bool bType)
CreateOpAdd.
Definition: filter_op.hpp:108
void setValue(float value)
setValue
The FilterGLBlend class.
Definition: filter_blend.hpp:28
void release()
release
Definition: pyramid.hpp:68
void add(const PyramidGL *pyr)
add
virtual ImageGL * Process(ImageGLVec imgIn, ImageGL *imgOut)
Process.
Definition: display.hpp:258
FilterGLBlend * flt_blend
Definition: pyramid.hpp:44
FilterGLOp * flt_sub
Definition: pyramid.hpp:43
The FilterGLGaussian2D class.
Definition: display.hpp:33
FilterGLOp * flt_add
Definition: pyramid.hpp:43
ImageGLVec stack
Definition: display.hpp:78
int limitLevel
Definition: pyramid.hpp:39
void blend(PyramidGL *pyr, PyramidGL *weight)
blend
The FilterGLSampler2D class.
Definition: filter_sampler_2d.hpp:28
#define PIC_INLINE
Definition: base.hpp:33
The ImageGL class.
Definition: display.hpp:42
ImageGLVec stack
Definition: pyramid.hpp:78
ImageGLVec trackerRec
Definition: pyramid.hpp:47
FilterGLSampler2D * flt_sampler
Definition: pyramid.hpp:42
int width
Definition: filter_radial_basis_function.hpp:80
#define MIN(a, b)
Definition: math.hpp:69
The Image class stores an image as buffer of float.
Definition: image.hpp:60
PIC_INLINE ImageGLVec TripleGL(ImageGL *img1, ImageGL *img2, ImageGL *img3)
TripleGL creates a triple for filters input.
Definition: image_vec.hpp:67
std::vector< FilterGL * > filters
Definition: pyramid.hpp:45
The FilterGLGaussian2D class.
Definition: filter_gaussian_2d.hpp:33
int size()
size
Definition: pyramid.hpp:148
The PyramidGL class.
Definition: display.hpp:35
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
ImageGLVec trackerUp
Definition: pyramid.hpp:47
#define MAX(a, b)
Definition: math.hpp:73
bool lapGauss
Definition: pyramid.hpp:38
Definition: image.hpp:37
PyramidGL(ImageGL *img, bool lapGauss, int limitLevel)
PyramidGL.
void create(ImageGL *img, bool lapGauss, int limitLevel)
create
ImageGL * reconstruct(ImageGL *imgOut)
reconstruct
std::vector< ImageGL * > ImageGLVec
ImageGLVec an std::vector of pic::ImageGL.
Definition: image_vec.hpp:32
int height
Definition: filter_radial_basis_function.hpp:80
bool bCreated
Definition: pyramid.hpp:38