PICCANTE  0.4
The hottest HDR imaging library!
filter_bilateral_2dg.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_FILTERING_FILTER_BILATERAL_2DG_HPP
19 #define PIC_FILTERING_FILTER_BILATERAL_2DG_HPP
20 
21 //#define BILATERAL_GRID_MULTI_PASS
22 
23 #include "../util/std_util.hpp"
24 
25 #include "../filtering/filter.hpp"
26 #include "../filtering/filter_gaussian_3d.hpp"
27 #include "../image_samplers/image_sampler_bilinear.hpp"
28 
29 namespace pic {
30 
35 {
36 protected:
40  float sigma_s, sigma_r;
41 
43  bool parallel;
44 
52  Image *Splat(Image *base, Image *edge, int channel);
53 
61  void Slice(Image *out, Image *base, Image *edge, int channels);
62 
63 public:
64 
70  FilterBilateral2DG(float sigma_s, float sigma_r);
71 
73 
74  float s_S, s_R, mul_E;
75 
80  std::string signature()
81  {
82  return genBilString("G", sigma_s, sigma_r);
83  }
84 
91  Image *Process(ImageVec imgIn, Image *imgOut);
92 
101  static Image *execute(Image *imgIn, Image *imgOut, float sigma_s,
102  float sigma_r)
103  {
105 
106  //long t0 = timeGetTime();
107 
108  imgOut = filter.Process(Single(imgIn), NULL); //Filtering
109 
110  //long t1 = timeGetTime();
111  //printf("Bilateral Grid Filter time: %f\n", float(t1 - t0) / 1000.0f);
112 
113  return imgOut;
114  }
115 };
116 
118 {
119  //protected values are assigned/computed
120  this->sigma_s = sigma_s;
121  this->sigma_r = sigma_r;
122 
123  parallel = false;
124 
125  grid = NULL;
126  gridBlur = NULL;
127 
128  fltG = new FilterGaussian3D(1.0f);
129 }
130 
132 {
133  delete_s(grid);
135  delete_s(fltG);
136 }
137 
139 {
140  if(grid == NULL) {
141  #ifdef PIC_DEBUG
142  printf("S Rate: %f R Rate: %f Mul E: %f\n", s_S, s_R, mul_E);
143  #endif
144 
145  width = int(ceilf(float(base->width) * s_S));
146  height = int(ceilf(float(base->height) * s_S));
147  range = int(ceilf(s_R));
148 
149  #ifdef PIC_DEBUG
150  printf("Grid Size: %d %d %d\n", width, height, range);
151  #endif
152 
153 #ifdef PIC_BILATERAL_GRID_MULTI_PASS
154  #ifdef PIC_DEBUG
155  printf("Grid - Memory Mb: %3.2f\n",
156  float(width + 1)*float(height + 1)*float(range + 1) * 8.0f /
157  (1024.0f * 1024.0f));
158  #endif
159 
160  grid = new Image(range + 1, width + 1, height + 1, 2);
161  gridBlur = new Image(range + 1, width + 1, height + 1, 2);
162 #else
163  #ifdef PIC_DEBUG
164  printf("Grid - Memory Mb: %3.2f\n",
165  float(width + 1)*float(height + 1)*float(range + 1) * 16.0f /
166  (1024.0f * 1024.0f));
167  #endif
168 
169  grid = new Image(range + 1, width + 1, height + 1, base->channels + 1);
170  gridBlur = new Image(range + 1, width + 1, height + 1, base->channels + 1);
171 #endif
172  }
173 
174  grid->setZero();
175 
176  for(int j = 0; j < base->height; j++) {
177  int y = int(lround(float(j) * s_S));
178 
179  for(int i = 0; i < base->width; i++) {
180 
181  int ind = i * base->xstride + j * base->ystride;
182 
183 #ifdef PIC_BILATERAL_GRID_MULTI_PASS
184  float E = edge->data[ind + channel];
185 #else
186  float E = 0.0f;
187 
188  for(int k = 0; k < edge->channels; k++) {
189  E += edge->data[ind + k];
190  }
191 
192 #endif
193  E *= mul_E;
194 
195  int x = int(lround(float(i) * s_S));
196  int r = int(lround(E));
197 
198  int grdInd = x * grid->xstride + y * grid->ystride + r * grid->tstride;
199 
200 #ifdef PIC_BILATERAL_GRID_MULTI_PASS
201  grid->data[grdInd + 0] += base->data[ind + channels];
202  grid->data[grdInd + 1] += 1.0f;
203 #else
204 
205  for(int k = 0; k < base->channels; k++) {
206  grid->data[grdInd + k] += base->data[ind + k];
207  }
208 
209  grid->data[grdInd + base->channels] += 1.0f; //Counter
210 #endif
211  }
212  }
213  return grid;
214 }
215 
217  int channels)
218 {
219  float widthf = float(grid->width);
220  float heightf = float(grid->height);
221  float rangef = float(grid->frames);
222 
223 #ifdef PIC_BILATERAL_GRID_MULTI_PASS
224  float vOut[2];
225 #else
226  float *vOut = new float [out->channels + 1];
227 #endif
228 
229  for(int j = 0; j < out->height; j++) {
230  for(int i = 0; i < out->width; i++) {
231  int ind = i * out->xstride + j * out->ystride;
232 
233  float x = float(i) * s_S;
234  float y = float(j) * s_S;
235 
236 #ifdef PIC_BILATERAL_GRID_MULTI_PASS
237  float E = edge->data[ind + channels];
238 #else
239  float E = Arrayf::sum(&edge->data[ind], out->channels);
240 
241 #endif
242  E *= mul_E;
243 
244  //Trilinear filtering
245  isb.SampleImage(gridBlur, x / widthf, y / heightf, E / rangef, vOut);
246 
247 #ifdef PIC_BILATERAL_GRID_MULTI_PASS
248 
249  if(vOut[1] > 0.0f) {
250  out->data[ind + channels] = vOut[0] / vOut[1];
251  } else {
252  out->data[ind + channels] = 0.0f;
253  }
254 
255 #else
256  if(vOut[out->channels] > 0.0f) {
257  for(int k = 0; k < out->channels; k++) {
258  out->data[ind + k] = vOut[k] / vOut[out->channels];
259  }
260  } else {
261  Arrayf::assign(0.0f, &out->data[ind], out->channels);
262  }
263 
264 #endif
265  }
266  }
267 }
268 
270 {
271  if(!checkInput(imgIn)) {
272  return imgOut;
273  }
274 
275  imgOut = setupAux(imgIn, imgOut);
276 
277  if(imgOut == NULL) {
278  return imgOut;
279  }
280 
281  Image *base, *edge;
282 
283  base = imgIn[0];
284 
285  int ind;
286  float *baseMaxmaxVal = base->getMaxVal(NULL, NULL);
287  float maxVal = Arrayf::getMax(baseMaxmaxVal, base->channels, ind);
288  delete[] baseMaxmaxVal;
289 
290  if(imgIn.size() == 2) {
291  edge = imgIn[1];
292 
293  float *edgeMaxVal = edge->getMaxVal(NULL, NULL);
294 
295  maxVal = MAX(maxVal, Arrayf::getMax(edgeMaxVal, edge->channels, ind));
296 
297  delete[] edgeMaxVal;
298 
299  *edge /= maxVal;
300  } else {
301  edge = imgIn[0];
302  }
303 
304  //Range in [0,1]
305  *base /= maxVal;
306  float tmpSigma_r = sigma_r;
307  sigma_r /= maxVal;
308 
309  //Grid's Initialization
310  s_S = 1.0f / sigma_s; //Spatial Sampling rate
311  s_R = 1.0f / sigma_r; //Range Sampling rate
312 
313 #ifdef PIC_BILATERAL_GRID_MULTI_PASS
314  int n = imgIn[0]->channels;
315  mul_E = s_R;
316 #else
317  int n = 1;
318  mul_E = s_R / float(imgIn[0]->channels);
319 #endif
320 
321  for(int i = 0; i < n; i++) {
322  //splat
323  Splat(base, edge, i);
324 
325  //blur
327 
328  //slice
329  Slice(imgOut, base, edge, i);
330  }
331 
332  *imgOut *= maxVal;
333  sigma_r = tmpSigma_r;
334 
335  return imgOut;
336 }
337 
338 } // end namespace pic
339 
340 #endif /* PIC_FILTERING_FILTER_BILATERAL_2DG_HPP */
341 
float s_S
Definition: filter_bilateral_2dg.hpp:74
std::string signature()
Signature.
Definition: filter_bilateral_2dg.hpp:80
float mul_E
Definition: filter_bilateral_2dg.hpp:74
Image * Splat(Image *base, Image *edge, int channel)
Splat splats values into the grid.
Definition: filter_bilateral_2dg.hpp:138
static T getMax(T *data, int size, int &ind)
getMax
Definition: array.hpp:516
float * data
data is the main buffer where pixel values are stored.
Definition: image.hpp:91
void setZero()
setZero sets data to 0.0f.
int channels
Definition: image.hpp:80
T * delete_s(T *data)
delete_s
Definition: std_util.hpp:123
std::vector< Image * > ImageVec
ImageVec an std::vector of pic::Image.
Definition: image_vec.hpp:29
PIC_INLINE long lround(double x)
lround rounds double numbers properly.
Definition: math.hpp:229
The Filter class.
Definition: filter.hpp:50
ImageSamplerBilinear isb
Definition: filter_bilateral_2dg.hpp:37
bool parallel
Definition: filter_bilateral_2dg.hpp:43
Image * grid
Definition: filter_bilateral_2dg.hpp:42
int frames
Definition: image.hpp:80
~FilterBilateral2DG()
Definition: filter_bilateral_2dg.hpp:131
float sigma_r
Definition: filter_bilateral_2dg.hpp:40
int width
Definition: filter_bilateral_2dg.hpp:39
void Slice(Image *out, Image *base, Image *edge, int channels)
Slice slices the grid into the output image.
Definition: filter_bilateral_2dg.hpp:216
float sigma_s
Definition: filter_bilateral_2dg.hpp:40
The FilterBilateral2DG class.
Definition: filter_bilateral_2dg.hpp:34
int range
Definition: filter_bilateral_2dg.hpp:39
Image * Process(ImageVec imgIn, Image *imgOut)
Process.
Definition: filter_npasses.hpp:310
float s_R
Definition: filter_bilateral_2dg.hpp:74
Image * gridBlur
Definition: filter_bilateral_2dg.hpp:42
static Image * execute(Image *imgIn, Image *imgOut, float sigma_s, float sigma_r)
execute
Definition: filter_bilateral_2dg.hpp:101
int xstride
Definition: image.hpp:82
static T sum(T *data, int size)
sum
Definition: array.hpp:416
std::string genBilString(std::string type, float sigma_s, float sigma_r)
genBilString
Definition: string.hpp:366
#define PIC_INLINE
Definition: base.hpp:33
void SampleImage(Image *img, float x, float y, float *vOut)
SampleImage samples an image in normalized coordiantes (0,1).
Definition: image_sampler_bilinear.hpp:42
The Image class stores an image as buffer of float.
Definition: image.hpp:60
virtual void f(FilterFData *data)
f
Definition: filter_radial_basis_function.hpp:69
int ystride
Definition: image.hpp:82
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
int tstride
Definition: image.hpp:82
static T * assign(T *data, int size, T *ret)
assign
Definition: array.hpp:464
FilterBilateral2DG(float sigma_s, float sigma_r)
FilterBilateral2DG.
Definition: filter_bilateral_2dg.hpp:117
#define MAX(a, b)
Definition: math.hpp:73
The FilterGaussian3D class.
Definition: filter_gaussian_3d.hpp:29
Image * Process(ImageVec imgIn, Image *imgOut)
Process.
Definition: filter_bilateral_2dg.hpp:269
FilterGaussian3D * fltG
Definition: filter_bilateral_2dg.hpp:38
virtual Image * setupAux(ImageVec imgIn, Image *imgOut)
setupAux
Definition: filter.hpp:288
float * getMaxVal(BBox *box, float *ret)
getMaxVal computes the maximum value for the current Image.
int width
Definition: image.hpp:80
bool checkInput(ImageVec &imgIn)
checkInput
Definition: filter.hpp:385
The ImageSamplerBilinear class.
Definition: image_sampler_bilinear.hpp:28
int height
Definition: image.hpp:80
int height
Definition: filter_bilateral_2dg.hpp:39