PICCANTE  0.4
The hottest HDR imaging library!
filter_bilateral_1d.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_1D_HPP
19 #define PIC_FILTERING_FILTER_BILATERAL_1D_HPP
20 
21 #include "../util/precomputed_gaussian.hpp"
22 #include "../util/std_util.hpp"
23 #include "../util/array.hpp"
24 
25 #include "../filtering/filter.hpp"
26 
27 namespace pic {
28 
33 {
34 protected:
36  int dirs[3];
37  float sigma_r_sq_2;
38 
45  void ProcessBBox(Image *dst, ImageVec src, BBox *box);
46 
47 public:
48 
49  float sigma_s, sigma_r;
50 
56  FilterBilateral1D(float sigma_s, float sigma_r);
57 
63  void update(float sigma_s, float sigma_r);
64 
69  std::string signature()
70  {
71  return genBilString("1D", sigma_s, sigma_r);
72  }
73 
79  void changePass(int pass, int tPass);
80 };
81 
82 PIC_INLINE FilterBilateral1D::FilterBilateral1D(float sigma_s, float sigma_r) : Filter()
83 {
84  pg = NULL;
86 }
87 
88 PIC_INLINE void FilterBilateral1D::update(float sigma_s, float sigma_r)
89 {
90  //protected values are assigned/computed
91  this->sigma_s = sigma_s > 0.0f ? sigma_s : 1.0f;
92  this->sigma_r = sigma_r > 0.0f ? sigma_r : 0.01f;
93  this->sigma_r_sq_2 = this->sigma_r * this->sigma_r * 2.0f;
94 
95  //Precomputation of the Gaussian filter
96  dirs[0] = dirs[1] = dirs[2] = 0;
97 
98  pg = delete_s(pg);
99 
101 }
102 
103 PIC_INLINE void FilterBilateral1D::changePass(int pass, int tPass)
104 {
105  /* tPass++;
106  dirs[ pass%tPass] = 1;
107  for(int i=1;i<tPass;i++)
108  dirs[(pass+i)%tPass] = 0;
109  */
110  int tMod;
111 
112  if(tPass > 1) {
113  tMod = 3;
114  } else {
115  if(tPass == 1) {
116  tMod = 2;
117  } else {
118  printf("ERROR: FilterGaussian1D::ChangePass\n");
119  return;
120  }
121  }
122 
123  dirs[ pass % tMod] = 1;
124 
125  for(int i = 1; i < tMod; i++) {
126  dirs[(pass + i) % tMod] = 0;
127  }
128 
129 #ifdef PIC_DEBUG
130  printf("%d %d %d\n", dirs[0], dirs[1], dirs[2]);
131 #endif
132 }
133 
135 {
136  Image *edge, *base;
137 
138  if(src.size() == 2) {
139  //Joint/Cross Bilateral Filtering
140  base = src[0];
141  edge = src[1];
142  } else {
143  base = src[0];
144  edge = src[0];
145  }
146 
147  for(int m = box->z0; m < box->z1; m++) {
148  for(int j = box->y0; j < box->y1; j++) {
149  for(int i = box->x0; i < box->x1; i++) {
150 
151  float *tmpDst = (*dst )(i, j, m);
152  float *tmpEdge = (*edge)(i, j, m);
153 
154  Arrayf::assign(0.0f, tmpDst, dst->channels);
155 
156  float sum = 0.0f;
157 
158  for(int k = 0; k < pg->kernelSize; k++) {
159  //Spatial filtering
160  float weight = pg->coeff[k];
161 
162  int tmpCoord = k - pg->halfKernelSize;
163 
164  //Address cj
165  int cj = j + tmpCoord * dirs[0];
166  //Address ci
167  int ci = i + tmpCoord * dirs[1];
168  //Address cm
169  int cm = m + tmpCoord * dirs[2];
170 
171 
172  //Range filtering
173  float *curEdge = (*edge)(ci, cj, cm);
174 
175  float edgeDist = Arrayf::distanceSq(curEdge, tmpEdge, dst->channels);
176  edgeDist = expf(-edgeDist / sigma_r_sq_2);
177 
178  //Weight
179  weight *= edgeDist;
180 
181  //filter
182  float *curBase = (*base)(ci, cj, cm);
183  for(int l = 0; l < dst->channels; l++) {
184  tmpDst[l] += curBase[l] * weight;
185  }
186 
187  sum += weight;
188  }
189 
190  //Normalization
191  if(sum > 0.0f) {
192  Arrayf::div(tmpDst, dst->channels, sum);
193  } else {
194  float *base = (*edge)(i, j, m);
195  Arrayf::assign(base, dst->channels, tmpDst);
196  }
197  }
198  }
199  }
200 }
201 
202 } // end namespace pic
203 
204 #endif /* PIC_FILTERING_FILTER_BILATERAL_1D_HPP */
205 
The FilterBilateral1D class.
Definition: filter_bilateral_1d.hpp:32
The BBox class manages the creation of bounding boxes for images.
Definition: bbox.hpp:29
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
int x0
Definition: bbox.hpp:32
void ProcessBBox(Image *dst, ImageVec src, BBox *box)
ProcessBBox.
Definition: filter_bilateral_1d.hpp:134
The Filter class.
Definition: filter.hpp:50
float * coeff
Definition: precomputed_gaussian.hpp:67
int dirs[3]
Definition: filter_bilateral_1d.hpp:36
static T distanceSq(T *data0, T *data1, int n)
distanceSq
Definition: array.hpp:195
void changePass(int pass, int tPass)
changePass
Definition: filter_bilateral_1d.hpp:103
int y0
Definition: bbox.hpp:32
std::string signature()
signature
Definition: filter_bilateral_1d.hpp:69
float sigma_s
Definition: filter_bilateral_1d.hpp:49
std::string genBilString(std::string type, float sigma_s, float sigma_r)
genBilString
Definition: string.hpp:366
#define PIC_INLINE
Definition: base.hpp:33
PrecomputedGaussian * pg
Definition: filter_bilateral_1d.hpp:35
The Image class stores an image as buffer of float.
Definition: image.hpp:60
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
int kernelSize
Definition: precomputed_gaussian.hpp:66
Definition: bilateral_separation.hpp:25
float sigma_r_sq_2
Definition: filter_bilateral_1d.hpp:37
static T * assign(T *data, int size, T *ret)
assign
Definition: array.hpp:464
FilterBilateral1D(float sigma_s, float sigma_r)
FilterBilateral1D.
Definition: filter_bilateral_1d.hpp:82
void update(float sigma_s, float sigma_r)
update
Definition: filter_bilateral_1d.hpp:88
int z0
Definition: bbox.hpp:32
float sigma_r
Definition: filter_bilateral_1d.hpp:49