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_GL_FILTERING_FILTER_BILATERAL_1D_HPP
19 #define PIC_GL_FILTERING_FILTER_BILATERAL_1D_HPP
20 
21 #include "../../base.hpp"
22 
23 #include "../../gl/filtering/filter_1d.hpp"
24 
25 namespace pic {
26 
31 {
32 protected:
33  float sigma_s, sigma_r;
34 
35  void FragmentShader();
36 
37 public:
38 
46  FilterGLBilateral1D(float sigma_s, float sigma_r, int direction,
47  GLenum target);
48 
50 
54  void setUniformAux();
55 
61  void update(float sigma_s, float sigma_r);
62 };
63 
65  int direction, GLenum target): FilterGL1D(direction, target)
66 {
67  //protected values are assigned/computed
68  this->sigma_s = sigma_s;
69  this->sigma_r = sigma_r;
70 
72  initShaders();
73 }
74 
76 {
77  release();
78 }
79 
81 {
82  std::string fragment_source_2D = MAKE_STRING
83  (
84  uniform sampler2D u_tex;
85  uniform float sigma_s2;
86  uniform float sigma_r2;
87  uniform int iX;
88  uniform int iY;
89  uniform int halfKernelSize;
90  out vec4 f_color;
91 
92  void main(void) {
93  vec3 color = vec3(0.0);
94  ivec2 coordsFrag = ivec2(gl_FragCoord.xy);
95  vec3 tmpCol;
96  float weight = 0.0;
97  vec3 colRef = texelFetch(u_tex, coordsFrag.xy, 0).xyz;
98 
99  for(int i = -halfKernelSize; i <= halfKernelSize; i++) {
100  //Coordinates
101  ivec2 coords = ivec2(i * iX, i * iY);
102  //Texture fetch
103  tmpCol = texelFetch(u_tex, coordsFrag.xy + coords.xy, 0).xyz;
104  vec3 tmpCol2 = tmpCol - colRef;
105  float dstR = dot(tmpCol2.xyz, tmpCol2.xyz);
106  float tmp = exp(-dstR / sigma_r2 - float(coords.x * coords.x + coords.y *
107  coords.y) / sigma_s2);
108  color.xyz += tmpCol.xyz * tmp;
109  weight += tmp;
110  }
111 
112  color = weight > 0.0 ? color / weight : colRef;
113  f_color = vec4(color.xyz, 1.0);
114  }
115  );
116 
117  std::string fragment_source_3D = MAKE_STRING
118  (
119  uniform sampler2DArray u_tex;
120  uniform float sigma_s2;
121  uniform float sigma_r2;
122  uniform int slice;
123  uniform int iX;
124  uniform int iY;
125  uniform int iZ;
126  out vec4 f_color;
127 
128  void main(void) {
129  vec3 color = vec3(0.0);
130  ivec3 coordsFrag = ivec3(ivec2(gl_FragCoord.xy), slice);
131  vec3 tmpCol;
132  float weight = 0.0;
133  vec3 colRef = texelFetch(u_tex, coordsFrag, 0).xyz;
134 
135  for(int i = -halfKernelSize; i <= halfKernelSize; i++) {
136  //Coordinates
137  ivec3 coords = coordsFrag.xyz + ivec3(i * iX, i * iY, i * iZ);
138  //Texture fetch
139  tmpCol = texelFetch(u_tex, coordsFrag + coords, 0).xyz;
140  vec3 tmpCol2 = tmpCol - colRef;
141  float dstR = dot(tmpCol2.xyz, tmpCol2.xyz);
142  float tmp = exp(-dstR / sigma_r2 - float(coords.x * coords.x + coords.y *
143  coords.y) / sigma_s2);
144  color.xyz += tmpCol.xyz * tmp;
145  weight += tmp;
146  }
147 
148  color = weight > 0.0 ? color / weight : colRef;
149  f_color = vec4(color.xyz, 1.0);
150  }
151  );
152 
153  switch(target) {
154  case GL_TEXTURE_2D: {
155  fragment_source = fragment_source_2D;
156  }
157  break;
158 
159  case GL_TEXTURE_2D_ARRAY: {
160  fragment_source = fragment_source_3D;
161  }
162  break;
163 
164  case GL_TEXTURE_3D: {
165  fragment_source = fragment_source_3D;
166  }
167  break;
168  }
169 }
170 
172 {
173  float sigma_s_sq2 = 2.0f * sigma_s * sigma_s;
174  float sigma_r_sq2 = 2.0f * sigma_r * sigma_r;
175 
176  //Precomputation of the Gaussian Kernel
177  int halfKernelSize = PrecomputedGaussian::getKernelSize(MAX(sigma_s, sigma_r)) >> 1;
178 
179  technique.setUniform1f("sigma_s2", sigma_s_sq2);
180  technique.setUniform1f("sigma_r2", sigma_r_sq2);
181  technique.setUniform1i("halfKernelSize", halfKernelSize);
182 }
183 
184 PIC_INLINE void FilterGLBilateral1D::update(float sigma_s, float sigma_r)
185 {
186  this->sigma_s = sigma_s;
187  this->sigma_r = sigma_r;
188 
189  setUniform();
190 }
191 
192 } // end namespace pic
193 
194 #endif /* PIC_GL_FILTERING_FILTER_BILATERAL_1D_HPP */
195 
TechniqueGL technique
Definition: display.hpp:45
int slice
Definition: display.hpp:37
The FilterGL1D class.
Definition: filter_1d.hpp:32
static int getKernelSize(float sigma)
KernelSize computes the size of a kernel in pixel give its sigma.
Definition: precomputed_gaussian.hpp:121
float sigma_r
Definition: filter_bilateral_1d.hpp:33
float sigma_s
Definition: filter_bilateral_1d.hpp:33
virtual void initShaders()
initShaders
Definition: filter_1d.hpp:175
GLenum target
Definition: display.hpp:47
#define MAKE_STRING(input_string)
void setUniformAux()
setUniformAux
The FilterGLBilateral1D class.
Definition: filter_bilateral_1d.hpp:30
void setUniform1f(const char *name_uniform, float value0)
SetUniform1f.
Definition: display.hpp:247
FilterGLBilateral1D(float sigma_s, float sigma_r, int direction, GLenum target)
FilterGLBilateral1D.
#define PIC_INLINE
Definition: base.hpp:33
void update(float sigma_s, float sigma_r)
update
void setUniform()
setUniform
Definition: filter_1d.hpp:158
Definition: bilateral_separation.hpp:25
#define MAX(a, b)
Definition: math.hpp:73
void FragmentShader()
FragmentShader.
std::string fragment_source
Definition: display.hpp:57
The FilterGL1D class.
Definition: display.hpp:32
void release()
release
Definition: display.hpp:85
void setUniform1i(const char *name_uniform, int value0)
SetUniform.
Definition: display.hpp:236