PICCANTE  0.4
The hottest HDR imaging library!
filter_guided_a_b.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_GUIDED_A_B_HPP
19 #define PIC_FILTERING_FILTER_GUIDED_A_B_HPP
20 
21 #include "../filtering/filter.hpp"
22 
23 #include "../util/array.hpp"
24 
25 #include "../util/matrix_3_x_3.hpp"
26 
27 #include "../util/math.hpp"
28 
29 namespace pic {
30 
34 class FilterGuidedAB: public Filter
35 {
36 protected:
37 
38  int radius;
40 
48  void Process1Channel(Image *I, Image *p, Image *q, BBox *box);
49 
57  void Process3Channel(Image *I, Image *p, Image *q, BBox *box);
58 
65  void ProcessBBox(Image *dst, ImageVec src, BBox *box);
66 
67 public:
68 
73  {
74  update(8, 0.01f);
75  }
76 
83  {
85  }
86 
95  void OutputSize(ImageVec imgIn, int &width, int &height, int &channels, int &frames)
96  {
97  width = imgIn[0]->width;
98  height = imgIn[0]->height;
99  channels = getp(imgIn)->channels * (getI(imgIn)->channels + 1);
100  frames = imgIn[0]->frames;
101  }
102 
108  Image *getI(ImageVec &imgIn)
109  {
110  auto n = imgIn.size();
111  if(n == 1) {
112  return imgIn[0];
113  } else {
114  if(n > 1) {
115  return imgIn[1];
116  } else {
117  return NULL;
118  }
119  }
120  }
121 
127  Image *getp(ImageVec &imgIn)
128  {
129  auto n = imgIn.size();
130  if(n == 1) {
131  return imgIn[0];
132  } else {
133  if(n > 1) {
134  return imgIn[0];
135  } else {
136  return NULL;
137  }
138  }
139  }
140 
146  void update(int radius, float e_regularization);
147 
157  static Image *execute(Image *imgIn, Image *guide, Image *imgOut,
158  int radius, float e_regularization)
159  {
161  return filter.Process(Double(imgIn, guide), imgOut);
162  }
163 };
164 
165 PIC_INLINE void FilterGuidedAB::update(int radius, float e_regularization)
166 {
167  this->radius = radius;
168  this->e_regularization = e_regularization;
169  nPixels = float(radius * radius * 4);
170 }
171 
173  BBox *box)
174 {
175  float I_mean, I_var;
176  float *p_mean = new float [p->channels];
177 
178  for(int j = box->y0; j < box->y1; j++) {
179  for(int i = box->x0; i < box->x1; i++) {
180  float *tmpQ = (*q)(i, j);
181 
182  BBox tmpBox(i - radius, i + radius, j - radius, j + radius);
183 
184  I->getMeanVal(&tmpBox, &I_mean);
185  I->getVarianceVal(&I_mean, &tmpBox, &I_var);
186 
187  p->getMeanVal(&tmpBox, p_mean);
188 
189  for(int c = 0; c < p->channels; c++) {
190  float I_mean_p_mean = I_mean * p_mean[c];
191  float a = 0.0f;
192 
193  for(int k = -radius; k < radius; k++) {
194  for(int l = -radius; l < radius; l++) {
195  float *I_i = (*I)(i + l, j + k);
196  float *p_i = (*p)(i + l, j + k);
197  a += I_i[0] * p_i[c] - I_mean_p_mean;
198  }
199  }
200 
201  a /= (nPixels * (I_var + e_regularization));
202  float b = p_mean[c] - a * I_mean;
203 
204  int index = c << 1;
205  tmpQ[index] = a;
206  tmpQ[index + 1] = b;
207  }
208  }
209  }
210 
211  delete[] p_mean;
212 }
213 
215  Image *q, BBox *box)
216 {
217  float *I_mean = new float[I->channels];
218  float *p_mean = new float[p->channels];
219 
220  float *a = new float[I->channels];
221  float *tmp_A = new float[I->channels];
222 
223  Matrix3x3 cov, inv;
224 
225  for(int j = box->y0; j < box->y1; j++) {
226  for(int i = box->x0; i < box->x1; i++) {
227  float *tmpQ = (*q)(i, j);
228 
229  BBox tmpBox(i - radius, i + radius, j - radius, j + radius);
230 
231  I->getMeanVal(&tmpBox, I_mean);
232  I->getCovMtxVal(I_mean, &tmpBox, cov.data);
233 
234  //regularization
235  cov.add(e_regularization);
236  //invert matrix
237  cov.inverse(&inv);
238 
239  p->getMeanVal(&tmpBox, p_mean);
240 
241  int index = 0;
242  for(int c = 0; c < p->channels; c++) {
243 
244  Array<float>::assign(0.0f, tmp_A, I->channels);
245 
246  for(int k = -radius; k < radius; k++) {
247  for(int l = -radius; l < radius; l++) {
248  float *I_i = (*I)(i + l, j + k);
249  float *p_i = (*p)(i + l, j + k);
250 
251  for(int n = 0; n < I->channels; n++) {
252  tmp_A[n] += I_i[n] * p_i[c] - I_mean[n] * p_mean[c];
253  }
254  }
255  }
256 
257  Array<float>::div(tmp_A, I->channels, nPixels);
258 
259  //multiply for inverted matrix
260  a = inv.mul(tmp_A, a);
261 
262  float a_dot_I_mean = Array<float>::dot(a, I_mean, I->channels);
263  //float a_dot_I = Array<float>::dot(a, tmpI, channels);
264 
265  for(int n = 0; n < I->channels; n++) {
266  tmpQ[index] = a[n];
267  index++;
268  }
269 
270  //b
271  tmpQ[index] = p_mean[c] - a_dot_I_mean;
272  index++;
273  }
274  }
275  }
276 }
277 
279  BBox *box)
280 {
281  Image *I = getI(src);
282  Image *p = getp(src);
283 
284  if(I->channels == 1) {
285  Process1Channel(I, p, dst, box);
286  }
287 
288  if(I->channels == 3) {
289  Process3Channel(I, p, dst, box);
290  }
291 }
292 
293 } // end namespace pic
294 
295 #endif /* PIC_FILTERING_FILTER_GUIDED_A_B_HPP */
296 
float data[9]
Definition: matrix_3_x_3.hpp:37
float * getCovMtxVal(float *meanVal, BBox *box, float *ret)
getCovMtxVal computes the convariance matrix for the current Image.
Matrix3x3 mul(const Matrix3x3 &mtx)
mul
Definition: matrix_3_x_3.hpp:116
The BBox class manages the creation of bounding boxes for images.
Definition: bbox.hpp:29
int size() const
size computes the number of values.
Definition: image.hpp:481
FilterGuidedAB(int radius, float e_regularization)
FilterGuidedAB.
Definition: filter_guided_a_b.hpp:82
int channels
Definition: image.hpp:80
std::vector< Image * > ImageVec
ImageVec an std::vector of pic::Image.
Definition: image_vec.hpp:29
int x0
Definition: bbox.hpp:32
float * getMeanVal(BBox *box, float *ret)
getMeanVal computes the mean for the current Image.
void add(float value)
Add adds a value to the diagonal.
Definition: matrix_3_x_3.hpp:234
FilterGuidedAB()
FilterGuidedAB.
Definition: filter_guided_a_b.hpp:72
The Matrix3x3 class provides methods for managing a 3 by 3 matrix.
Definition: matrix_3_x_3.hpp:29
The Filter class.
Definition: filter.hpp:50
virtual Image * Process(ImageVec imgIn, Image *imgOut)
Process.
Definition: filter.hpp:390
void ProcessBBox(Image *dst, ImageVec src, BBox *box)
ProcessBBox.
Definition: filter_guided_a_b.hpp:278
float e_regularization
Definition: filter_guided_a_b.hpp:39
Matrix3x3 * inverse(Matrix3x3 *ret)
inverse computes the inverse of the matrix.
Definition: matrix_3_x_3.hpp:257
Image * getI(ImageVec &imgIn)
getI
Definition: filter_guided_a_b.hpp:108
int y0
Definition: bbox.hpp:32
void Process3Channel(Image *I, Image *p, Image *q, BBox *box)
Process3Channel.
Definition: filter_guided_a_b.hpp:214
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
float nPixels
Definition: filter_guided_a_b.hpp:39
#define PIC_INLINE
Definition: base.hpp:33
The FilterGuidedAB class.
Definition: filter_guided_a_b.hpp:34
void update(int radius, float e_regularization)
update
Definition: filter_guided_a_b.hpp:165
static T dot(T *data0, T *data1, int n)
dot
Definition: array.hpp:281
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
virtual void f(FilterFData *data)
f
Definition: filter_radial_basis_function.hpp:69
Definition: bilateral_separation.hpp:25
void Process1Channel(Image *I, Image *p, Image *q, BBox *box)
Process1Channel.
Definition: filter_guided_a_b.hpp:172
static T * assign(T *data, int size, T *ret)
assign
Definition: array.hpp:464
void OutputSize(ImageVec imgIn, int &width, int &height, int &channels, int &frames)
OutputSize.
Definition: filter_guided_a_b.hpp:95
int radius
Definition: filter_guided_a_b.hpp:38
static Image * execute(Image *imgIn, Image *guide, Image *imgOut, int radius, float e_regularization)
execute
Definition: filter_guided_a_b.hpp:157
float * getVarianceVal(float *meanVal, BBox *box, float *ret)
getVarianceVal computes the variance for the current Image.
Image * getp(ImageVec &imgIn)
getp
Definition: filter_guided_a_b.hpp:127