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_ALGORITHMS_PYRAMID_HPP
19 #define PIC_ALGORITHMS_PYRAMID_HPP
20 
21 #include "../base.hpp"
22 #include "../image.hpp"
23 #include "../image_vec.hpp"
24 #include "../util/std_util.hpp"
25 #include "../filtering/filter.hpp"
26 #include "../filtering/filter_gaussian_2d.hpp"
27 #include "../filtering/filter_sampler_2d.hpp"
28 #include "../filtering/filter_sampler_2dsub.hpp"
29 #include "../filtering/filter_sampler_2dadd.hpp"
30 
31 namespace pic {
32 
36 class Pyramid
37 {
38 protected:
41 
46  std::vector< Filter* > filters;
47 
49 
53  void initFilters();
54 
64  void create(Image *img, bool lapGauss, int limitLevel);
65 
69  void release()
70  {
71  stdVectorClear<Image>(trackerUp);
72  stdVectorClear<Image>(trackerRec);
73  stdVectorClear<Image>(stack);
74  stdVectorClear<Filter>(filters);
75  }
76 
77 public:
78 
80 
88  Pyramid(Image *img, bool lapGauss, int limitLevel);
89 
99  Pyramid(int width, int height, int channels, bool lapGauss, int limitLevel);
100 
101  ~Pyramid();
102 
109  {
110  this->lapGauss = lapGauss;
111  }
112 
117  void update(Image *img);
118 
123  void setValue(float value);
124 
129  void mul(const Pyramid *pyr);
130 
135  void add(const Pyramid *pyr);
136 
142  Image *reconstruct(Image *imgOut);
143 
149  void blend(Pyramid *pyr, Pyramid *weight);
150 
155  int size()
156  {
157  return int(stack.size());
158  }
159 
165  Image *get(int index)
166  {
167  return stack[index % stack.size()];
168  }
169 
173  void setNULL()
174  {
175  release();
176 
177  flt_gauss = NULL;
178  flt_sampler = NULL;
179  flt_sub = NULL;
180  flt_add = NULL;
181 
182  bCreated = false;
183  }
184 };
185 
186 PIC_INLINE Pyramid::Pyramid(Image *img, bool lapGauss, int limitLevel = 1)
187 {
188  setNULL();
189 
190  create(img, lapGauss, limitLevel);
191 }
192 
193 PIC_INLINE Pyramid::Pyramid(int width, int height, int channels, bool lapGauss, int limitLevel = 1)
194 {
195  setNULL();
196 
197  Image *img = new Image(1, width, height, channels);
198  *img = 0.0f;
199 
200  create(img, lapGauss, limitLevel);
201 
202  delete img;
203 }
204 
206 {
207  release();
208 }
209 
211 {
212  if(!bCreated) {
213  flt_gauss = new FilterGaussian2D(1.0f);
214  filters.push_back(flt_gauss);
215 
216  flt_sampler = new FilterSampler2D(0.5f);
217  filters.push_back(flt_sampler);
218 
219  flt_sub = new FilterSampler2DSub(NULL);
220  filters.push_back(flt_sub);
221 
222  flt_add = new FilterSampler2DAdd(NULL);
223  filters.push_back(flt_add);
224 
225  bCreated = true;
226  }
227 }
228 
229 PIC_INLINE void Pyramid::create(Image *img, bool lapGauss, int limitLevel = 1)
230 {
231  if(img == NULL) {
232  return;
233  }
234 
235  if(!img->isValid()) {
236  return;
237  }
238 
239  limitLevel = MAX(limitLevel, 0);
240 
241  this->limitLevel = limitLevel;
242  this->lapGauss = lapGauss;
243 
244  initFilters();
245 
246  int levels = log2(MIN(img->width, img->height)) - limitLevel;
247 
248  Image *tmpImg = img;
249  Image *tmpG = NULL;
250  Image *tmpD = NULL;
251 
252  for(int i = 0; i < levels; i++) {
253  tmpG = flt_gauss->Process(Single(tmpImg), NULL);
254  tmpD = flt_sampler->Process(Single(tmpG), NULL);
255 
256  if(lapGauss) { //Laplacian Pyramid
257  flt_sub->Process(Double(tmpImg, tmpD), tmpG);
258  stack.push_back(tmpG);
259  } else { //Gaussian Pyramid
260  *tmpG = *tmpImg;
261  stack.push_back(tmpG);
262  }
263 
264  if(i < (levels - 1)) {
265  trackerUp.push_back(tmpD);
266  }
267 
268  tmpImg = tmpD;
269  }
270 
271  if(tmpD != NULL) {
272  stack.push_back(tmpD);
273  }
274 
275 #ifdef PIC_DEBUG
276  printf("Pyramid size: %zu\n", stack.size());
277 #endif
278 }
279 
281 {
282  if(img == NULL) {
283  return;
284  }
285 
286  if(stack.empty() || !img->isValid()) {
287  return;
288  }
289 
290  if(!stack[0]->isSimilarType(img)) {
291  return;
292  }
293 
294  Image *tmpG = NULL;
295  Image *tmpD = NULL;
296  Image *tmpImg = img;
297 
298  int levels = MAX(log2(MIN(img->width, img->height)) - limitLevel, 1);
299 
300  for(int i = 0; i < levels; i++) {
301 
302  tmpG = flt_gauss->Process(Single(tmpImg), stack[i]);
303 
304  if(i == (levels - 1)) {
305  tmpD = flt_sampler->Process(Double(tmpG, stack[i + 1]), stack[i + 1]);
306  } else {
307  tmpD = flt_sampler->Process(Double(tmpG, trackerUp[i]), trackerUp[i]);
308  }
309 
310  if(lapGauss) { //Laplacian Pyramid
311  flt_sub->Process(Double(tmpImg, tmpD), tmpG);
312  } else { //Gaussian Pyramid
313  *tmpG = *tmpImg;
314  }
315 
316  tmpImg = tmpD;
317  }
318 }
319 
321 {
322  if(stack.size() < 2) {
323  return imgOut;
324  }
325 
326  int n = int(stack.size()) - 1;
327  Image *tmp = stack[n];
328 
329  if(trackerRec.empty()) {
330  for(int i = n; i >= 2; i--) {
331  Image *tmp2 = flt_add->Process(Double(stack[i - 1], tmp), NULL);
332  trackerRec.push_back(tmp2);
333  tmp = tmp2;
334  }
335  } else {
336  int c = 0;
337 
338  for(int i = n; i >= 2; i--) {
339  flt_add->Process(Double(stack[i - 1], tmp), trackerRec[c]);
340  tmp = trackerRec[c];
341  c++;
342  }
343  }
344 
345  imgOut = flt_add->Process(Double(stack[0], tmp), imgOut);
346 
347  return imgOut;
348 }
349 
350 PIC_INLINE void Pyramid::setValue(float value)
351 {
352  for(unsigned int i = 0; i < stack.size(); i++) {
353  *stack[i] = value;
354  }
355 }
356 
358 {
359  if(stack.size() != pyr->stack.size()) {
360  return;
361  }
362 
363  for(unsigned int i = 0; i < stack.size(); i++) {
364  *stack[i] *= *pyr->stack[i];
365  }
366 }
367 
369 {
370  if(stack.size() != pyr->stack.size()) {
371  return;
372  }
373 
374  for(unsigned int i = 0; i < stack.size(); i++) {
375  *stack[i] += *pyr->stack[i];
376  }
377 }
378 
380 {
381  if(stack.size() != pyr->stack.size() ||
382  stack.size() != weight->stack.size()) {
383  return;
384  }
385 
386  for(unsigned int i = 0; i < stack.size(); i++) {
387  stack[i]->blend(pyr->stack[i], weight->stack[i]);
388  }
389 }
390 
391 } // end namespace pic
392 
393 #endif /* PIC_ALGORITHMS_PYRAMID_HPP */
394 
The FilterSampler2D class.
Definition: filter_sampler_2d.hpp:32
FilterSampler2DSub * flt_sub
Definition: pyramid.hpp:44
void blend(Pyramid *pyr, Pyramid *weight)
blend
Definition: pyramid.hpp:379
void initFilters()
initFilters
Definition: pyramid.hpp:210
void add(const Pyramid *pyr)
add is the add operator ( += ) between pyramids.
Definition: pyramid.hpp:368
FilterSampler2D * flt_sampler
Definition: pyramid.hpp:43
PIC_INLINE int log2(int n)
log2 computes logarithm in base 2 for integers.
Definition: math.hpp:302
std::vector< Image * > ImageVec
ImageVec an std::vector of pic::Image.
Definition: image_vec.hpp:29
void setValue(float value)
SetValue.
Definition: pyramid.hpp:350
ImageVec trackerUp
Definition: pyramid.hpp:48
FilterSampler2DAdd * flt_add
Definition: pyramid.hpp:45
virtual Image * Process(ImageVec imgIn, Image *imgOut)
Process.
Definition: filter.hpp:390
void release()
release
Definition: pyramid.hpp:69
void create(Image *img, bool lapGauss, int limitLevel)
create
Definition: pyramid.hpp:229
ImageVec trackerRec
Definition: pyramid.hpp:48
FilterGaussian2D * flt_gauss
Definition: pyramid.hpp:42
PIC_INLINE ImageVec Double(Image *img1, Image *img2)
Double creates an std::vector which contains img1 and img2; this is for filters input.
Definition: image_vec.hpp:49
Image * Process(ImageVec imgIn, Image *imgOut)
Process.
Definition: filter_npasses.hpp:310
Pyramid(Image *img, bool lapGauss, int limitLevel)
Pyramid.
Definition: pyramid.hpp:186
bool bCreated
Definition: pyramid.hpp:39
void update(Image *img)
update recomputes the pyramid given a compatible image, img.
Definition: pyramid.hpp:280
Image * reconstruct(Image *imgOut)
reconstruct evaluates a Gaussian/Laplacian pyramid.
Definition: pyramid.hpp:320
The FilterSampler2DAdd class.
Definition: filter_sampler_2dadd.hpp:31
#define PIC_INLINE
Definition: base.hpp:33
void setLapGauss(bool lapGauss)
setLapGauss
Definition: pyramid.hpp:108
~Pyramid()
Definition: pyramid.hpp:205
#define MIN(a, b)
Definition: math.hpp:69
The Image class stores an image as buffer of float.
Definition: image.hpp:60
bool lapGauss
Definition: pyramid.hpp:39
The Pyramid class.
Definition: pyramid.hpp:36
The FilterSampler2DSub class.
Definition: filter_sampler_2dsub.hpp:29
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
void mul(const Pyramid *pyr)
mul is the mul operator ( *= ) between pyramids.
Definition: pyramid.hpp:357
bool isValid()
isValid checks if the current image is valid, which means if they have an allocated buffer or not...
int size()
size
Definition: pyramid.hpp:155
int limitLevel
Definition: pyramid.hpp:40
#define MAX(a, b)
Definition: math.hpp:73
The FilterGaussian2D class.
Definition: filter_gaussian_2d.hpp:31
void setNULL()
setNULL
Definition: pyramid.hpp:173
int width
Definition: image.hpp:80
int height
Definition: image.hpp:80
ImageVec stack
Definition: pyramid.hpp:79
std::vector< Filter *> filters
Definition: pyramid.hpp:46