PICCANTE  0.4
The hottest HDR imaging library!
filter_bilateral_2das.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_2DAS_HPP
19 #define PIC_FILTERING_FILTER_BILATERAL_2DAS_HPP
20 
21 #include <random>
22 
23 #include "../base.hpp"
24 #include "../util/std_util.hpp"
25 #include "../util/precomputed_gaussian.hpp"
26 #include "../filtering/filter_sampling_map.hpp"
27 #include "../point_samplers/sampler_random_m.hpp"
28 
29 namespace pic {
30 
35 {
36 protected:
40  int seed;
42 
44 
51  void ProcessBBox(Image *dst, ImageVec src, BBox *box);
52 
53 public:
58 
66  FilterBilateral2DAS(float sigma_s, float sigma_r, int mult, SAMPLER_TYPE type);
67 
69 
77  void update(float sigma_s, float sigma_r, int mult, SAMPLER_TYPE type);
78 
85  Image *setupAux(ImageVec imgIn, Image *imgOut)
86  {
88 
89  samplingMap = fsm.Process(imgIn, samplingMap);
90  float maxVal;
91  samplingMap->getMaxVal(NULL, &maxVal);
92  *samplingMap /= maxVal;
93 
94  return allocateOutputMemory(imgIn, imgOut, bDelete);
95  }
96 
101  std::string signature()
102  {
103  return genBilString("AS", sigma_s, sigma_r);
104  }
105 
114  static Image *execute(Image *imgIn, Image *imgOut, float sigma_s, float sigma_r)
115  {
117  imgOut = flt.Process(Single(imgIn), imgOut);
118  return imgOut;
119  }
120 };
121 
123 {
124  seed = 1;
125  pg = NULL;
126  ms = NULL;
127  samplingMap = NULL;
128 }
129 
131  float sigma_r, int mult = 1, SAMPLER_TYPE type = ST_BRIDSON) : Filter()
132 {
133  seed = 1;
134  pg = NULL;
135  ms = NULL;
136  samplingMap = NULL;
137 
138  update(sigma_s, sigma_r, mult, type);
139 }
140 
142 {
143  pg = delete_s(pg);
144  ms = delete_s(ms);
146 }
147 
149  float sigma_r, int mult = 1, SAMPLER_TYPE type = ST_BRIDSON)
150 {
151  //protected values are assigned/computed
152  this->sigma_s = sigma_s > 0.0f ? sigma_s : 1.0f;
153  this->sigma_r = sigma_r > 0.0f ? sigma_r : 0.01f;
154  this->sigma_r_sq_2 = this->sigma_r * this->sigma_r * 2.0f;
155 
156  //precompute the Gaussian Kernel
157  pg = delete_s(pg);
159 
160  //Poisson samples
162 
163  ms = delete_s(ms);
164  if(mult > 0) {
165  ms = new MRSamplers<2>(type, window, pg->halfKernelSize * mult, 3, 64);
166  } else if(mult < 0) {
167  mult = -mult;
168  ms = new MRSamplers<2>(type, window, pg->halfKernelSize / mult, 3, 64);
169  }
170 
171  seed = 1;
172 }
173 
175 {
176  int channels = dst->channels;
177 
178  //filter
179  Image *edge, *base;
180 
181  switch(src.size()) {
182  case 1: {
183  base = src[0];
184  edge = src[0];
185  } break;
186 
187  default: {
188  base = src[0];
189  edge = src[1];
190  } break;
191 
192  }
193 
194  RandomSampler<2> *ps;
195  float valOut;
196 
197  //Mersenne Twister
198  std::mt19937 m(seed);
199 
200  for(int i = box->y0; i < box->y1; i++) {
201  float x = float(i) / dst->heightf;
202 
203  for(int j = box->x0; j < box->x1; j++) {
204 
205  //convolve with the kernel
206  float *dst_data = (*dst)(j, i);
207  float *edge_data = (*edge)(j, i);
208 
209  Arrayf::assign(0.0f, dst_data, channels);
210 
211  ps = ms->getSampler(&m);
212 
213  //calculate the number of samples
214  float y = float(j) / dst->widthf;
215  isb.SampleImage(samplingMap, x, y, &valOut);
216 
217  float tmpValOut = 1.0f - valOut; //+valOut[1]+valOut[2])/3.0f;
218  float levelVal = CLAMPi(tmpValOut, 0.0f, 0.9f) * float(ps->levelsR.size());
219 
220  int levelInt = int(floorf(levelVal));
221  int nSamples = ps->levelsR[levelInt];
222 
223  int levelsRsize = int(ps->levelsR.size()) - 1;
224  if(levelInt < levelsRsize) {
225  if((levelVal - float(levelInt)) > 0.0f) {
226  nSamples += int(float(ps->levelsR[levelInt + 1] - ps->levelsR[levelInt]) *
227  (levelVal - float(levelInt)));
228  }
229  }
230 
231  if((nSamples % 2) == 1) {
232  nSamples++;
233  }
234 
235  nSamples = MIN(nSamples, pg->halfKernelSize * pg->halfKernelSize * 2);
236 
237  float sum = 0.0f;
238  for(int k = 0; k < nSamples; k += 2) {
239  //fetch addresses
240  int cj = j + ps->samplesR[k ];
241  int ci = i + ps->samplesR[k + 1];
242 
243  //
244  //Spatial Gaussian kernel
245  //
246  float G1 = pg->coeff[ps->samplesR[k ] + pg->halfKernelSize] *
247  pg->coeff[ps->samplesR[k + 1] + pg->halfKernelSize];
248 
249 
250  float *cur_edge = (*edge)(cj, ci);
251 
252  //
253  //Range Gaussian Kernel
254  //
255  float tmp = Arrayf::distanceSq(cur_edge, edge_data, channels);
256  float G2 = expf(-tmp / sigma_r_sq_2);
257 
258  //Weight
259  float weight = G1 * G2;
260  sum += weight;
261 
262  //filter
263  float *base_data_ci_cj = (*base)(cj, ci);
264 
265  for(int l = 0; l < channels; l++) {
266  dst_data[l] += base_data_ci_cj[l] * weight;
267  }
268  }
269 
270  //normalization
271  if(sum > 0.0f) {
272  Arrayf::div(dst_data, channels, sum);
273  } else {
274  float *base_data = (*base)(j, i);
275  Arrayf::assign(base_data, channels, dst_data);
276  }
277  }
278  }
279 }
280 
281 } // end namespace pic
282 
283 #endif /* PIC_FILTERING_FILTER_BILATERAL_2DAS_HPP */
The BBox class manages the creation of bounding boxes for images.
Definition: bbox.hpp:29
float sigma_r_sq_2
Definition: filter_bilateral_2das.hpp:37
The FilterSamplingMap class.
Definition: filter_sampling_map.hpp:34
int channels
Definition: image.hpp:80
T * delete_s(T *data)
delete_s
Definition: std_util.hpp:123
Image * samplingMap
Definition: filter_bilateral_2das.hpp:41
std::vector< Image * > ImageVec
ImageVec an std::vector of pic::Image.
Definition: image_vec.hpp:29
The FilterBilateral2DAS class.
Definition: filter_bilateral_2das.hpp:34
int x0
Definition: bbox.hpp:32
The MRSamplers class.
Definition: sampler_random_m.hpp:34
MRSamplers< 2 > * ms
Definition: filter_bilateral_2das.hpp:43
void update(float sigma_s, float sigma_r, int mult, SAMPLER_TYPE type)
update
Definition: filter_bilateral_2das.hpp:148
The Filter class.
Definition: filter.hpp:50
Definition: point_samplers.hpp:51
ImageSamplerBilinear isb
Definition: filter_bilateral_2das.hpp:39
virtual Image * Process(ImageVec imgIn, Image *imgOut)
Process.
Definition: filter.hpp:390
float heightf
Definition: image.hpp:84
std::string signature()
Signature.
Definition: filter_bilateral_2das.hpp:101
Image * setupAux(ImageVec imgIn, Image *imgOut)
setupAux
Definition: filter_bilateral_2das.hpp:85
float * coeff
Definition: precomputed_gaussian.hpp:67
Vec< 2, int > Vec2i
Vec2i.
Definition: vec.hpp:829
static T distanceSq(T *data0, T *data1, int n)
distanceSq
Definition: array.hpp:195
float sigma_r
Definition: filter_bilateral_2das.hpp:37
int y0
Definition: bbox.hpp:32
int seed
Definition: filter_bilateral_2das.hpp:40
RandomSampler< N > * getSampler(std::mt19937 *m)
getSampler gets a sampler at a given level
Definition: sampler_random_m.hpp:139
Image * Process(ImageVec imgIn, Image *imgOut)
Process.
Definition: filter_npasses.hpp:310
float sigma_s
Definition: filter_bilateral_2das.hpp:37
Image * allocateOutputMemory(ImageVec imgIn, Image *imgOut, bool bDelete)
allocateOutputMemory
Definition: filter_radial_basis_function.hpp:217
std::string genBilString(std::string type, float sigma_s, float sigma_r)
genBilString
Definition: string.hpp:366
#define PIC_INLINE
Definition: base.hpp:33
SAMPLER_TYPE
Definition: point_samplers.hpp:51
FilterBilateral2DAS()
FilterBilateral2DAS.
Definition: filter_bilateral_2das.hpp:122
std::vector< int > samplesR
Definition: sampler_random.hpp:53
~FilterBilateral2DAS()
Definition: filter_bilateral_2das.hpp:141
float widthf
Definition: image.hpp:84
static Image * execute(Image *imgIn, Image *imgOut, float sigma_s, float sigma_r)
execute
Definition: filter_bilateral_2das.hpp:114
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
#define MIN(a, b)
Definition: math.hpp:69
The Image class stores an image as buffer of float.
Definition: image.hpp:60
PrecomputedGaussian * pg
Definition: filter_bilateral_2das.hpp:38
static void div(T *data, int size, T value)
div
Definition: array.hpp:353
The PrecomputedGaussian class.
Definition: precomputed_gaussian.hpp:30
int halfKernelSize
Definition: precomputed_gaussian.hpp:66
virtual void f(FilterFData *data)
f
Definition: filter_radial_basis_function.hpp:69
Definition: point_samplers.hpp:51
#define CLAMPi(x, a, b)
Definition: math.hpp:81
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
static T * assign(T *data, int size, T *ret)
assign
Definition: array.hpp:464
The RandomSampler class.
Definition: sampler_random.hpp:43
void ProcessBBox(Image *dst, ImageVec src, BBox *box)
ProcessBBox.
Definition: filter_bilateral_2das.hpp:174
bool bDelete
Definition: filter_radial_basis_function.hpp:120
float * getMaxVal(BBox *box, float *ret)
getMaxVal computes the maximum value for the current Image.
The ImageSamplerBilinear class.
Definition: image_sampler_bilinear.hpp:28
The Vec class.
Definition: vec.hpp:35
std::vector< int > levelsR
Definition: sampler_random.hpp:57