PICCANTE  0.4
The hottest HDR imaging library!
filter_bilateral_2ds_e.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_2DSE_HPP
19 #define PIC_GL_FILTERING_FILTER_BILATERAL_2DSE_HPP
20 
21 #include "../../gl/filtering/filter.hpp"
22 #include "../../util/file_lister.hpp"
23 #include "../../gl/point_samplers/sampler_random_m.hpp"
24 
25 namespace pic {
26 
31 {
32 protected:
35 
36  //Random numbers tile
38 
42  void initShaders();
43 
47  void FragmentShader();
48 
49 public:
57  FilterGLBilateral2DSE(float sigma_s, float sigma_p, float sigma_n, float sigma_a);
58 
60 
68  void update(float sigma_s, float sigma_p, float sigma_n, float sigma_a);
69 
76  ImageGL *Process(ImageGLVec imgIn, ImageGL *imgOut);
77 
84  static int main(int argc, char* argv[])
85  {
86  if(argc < 6) {
87  printf("Usage: name_input sigma_s sigma_pos sigma_nor sigma_alb\n");
88  return 0;
89  }
90 
91  execute(argv[1], float(atof(argv[2])), float(atof(argv[3])), float(atof(argv[4])), float(atof(argv[5])));
92 
93  return 0;
94  }
95 
106  static ImageGL *execute( std::string nameIn,
107  float sigma_s, float sigma_p, float sigma_n, float sigma_a, int testing = 1)
108  {
109 
110  std::string name = removeExtension(nameIn);
111  std::string ext = getExtension(nameIn);
112 
113  std::string nameOut = name + "_flt." + ext;
114 
115  std::string namePos = name +"_pos." + ext;
116  std::string nameNor = name +"_nor." + ext;
117  std::string nameAlb = name +"_alb." + ext;
118 
119 
120  ImageGL imgIn(nameIn);
121  imgIn.generateTextureGL(GL_TEXTURE_2D, false);
122 
123  ImageGL imgPos(namePos);
124  imgPos.generateTextureGL(GL_TEXTURE_2D, false);
125 
126  ImageGL imgNor(nameNor);
127  imgNor.generateTextureGL(GL_TEXTURE_2D, false);
128 
129  ImageGL imgAlb(nameAlb);
130  imgAlb.generateTextureGL(GL_TEXTURE_2D, false);
131 
132  ImageGLVec vec;
133  vec.push_back(&imgIn);
134  vec.push_back(&imgPos);
135  vec.push_back(&imgNor);
136  vec.push_back(&imgAlb);
137 
139  sigma_n, sigma_a);
140 
141  ImageGL *imgOut = new ImageGL(1, imgIn.width, imgIn.height, imgIn.channels,
142  IMG_GPU_CPU, GL_TEXTURE_2D);
143 
144  GLuint testTQ1;
145 
146  if(testing > 1) {
147  filter->Process(vec, imgOut);
148 
149  testTQ1 = glBeginTimeQuery();
150 
151  for(int i = 0; i < testing; i++) {
152  filter->Process(vec, imgOut);
153  }
154  } else {
155  testTQ1 = glBeginTimeQuery();
156  filter->Process(vec, imgOut);
157  }
158 
159  GLuint64EXT timeVal = glEndTimeQuery(testTQ1);
160  double ms = double(timeVal) / (double(testing) * 1000000.0);
161  printf("Cross Bilateral Filter with G-buffer on GPU time: %f ms\n", ms);
162 
163  //Read from the GPU
164  imgOut->loadToMemory();
165  imgOut->Write(nameOut);
166 
167  return imgOut;
168  }
169 
170 };
171 
172 FilterGLBilateral2DSE::FilterGLBilateral2DSE(float sigma_s, float sigma_p, float sigma_n, float sigma_a): FilterGL()
173 {
174  //protected values are assigned/computed
175  this->sigma_s = sigma_s;
176  this->sigma_p = sigma_p;
177  this->sigma_n = sigma_n;
178  this->sigma_a = sigma_a;
179 
180  //Precomputation of the Gaussian Kernel
181  int kernelSize = PrecomputedGaussian::getKernelSize(sigma_s);//,sigma_r);
182  int halfKernelSize = kernelSize >> 1;
183 
184  //Random numbers
185  int nRand = 32;
186  int nSamplers;
187 
188  Image tmp_imageRand(1, 128, 128, 1);
189  tmp_imageRand.setRand();
190  tmp_imageRand *= float(nRand - 1);
191 
192  imageRand = new ImageGL(&tmp_imageRand, true);
193  imageRand->generateTextureGL(GL_TEXTURE_2D, GL_INT);
194 
195  nSamplers = nRand;
196 
197  //Poisson samples
198 #ifdef PIC_DEBUG
199  printf("Window: %d\n", halfKernelSize);
200 #endif
201 
202  Vec2i window = Vec2i(halfKernelSize, halfKernelSize);
203  ms = new MRSamplersGL<2>(ST_BRIDSON, window, 4*halfKernelSize, 1,
204  nSamplers);
205  ms->generateTexture();
206 
207  FragmentShader();
208  initShaders();
209 }
210 
212 {
213  delete imageRand;
214  delete ms;
215 
216  //free shader etc...
217 }
218 
220 {
222  uniform sampler2D u_tex;
223  uniform sampler2D u_edge_pos;
224  uniform sampler2D u_edge_nor;
225  uniform sampler2D u_edge_alb;
226  uniform isampler2D u_poisson;
227  uniform sampler2D u_rand;
228  uniform int nSamples;
229  uniform float sigma_s2;
230  uniform float sigma_pos2;
231  uniform float sigma_nor2;
232  uniform float sigma_alb2;
233  out vec4 f_color;
234 
235  void main(void) {
236  vec3 color = vec3(0.0, 0.0, 0.0);
237  ivec2 coordsFrag = ivec2(gl_FragCoord.xy);
238 
239  vec3 colRef = texelFetch(u_tex, coordsFrag, 0).xyz;
240  vec3 edge_posRef = texelFetch(u_edge_pos, coordsFrag, 0).xyz;
241  vec3 edge_norRef = texelFetch(u_edge_nor, coordsFrag, 0).xyz;
242  vec3 edge_albRef = texelFetch(u_edge_alb, coordsFrag, 0).xyz;
243 
244  float weight = 0.0;
245  float shifter = texture2D(u_rand, gl_FragCoord.xy, 0).x;
246 
247  for(int i = 0; i < nSamples; i++) {
248  //Coordinates
249  ivec3 coords = texelFetch(u_poisson, ivec2(i, shifter), 0).xyz;
250  //pos difference
251  vec3 tmpEdge = texelFetch(u_edge_pos, coordsFrag.xy + coords.xy, 0).xyz;
252  vec3 tmpEdge2 = tmpEdge - edge_posRef;
253  float dstPos = dot(tmpEdge2.xyz, tmpEdge2.xyz);
254  //nor difference
255  tmpEdge = texelFetch(u_edge_nor, coordsFrag.xy + coords.xy, 0).xyz;
256  float dstNor = 1.0 - abs(dot(tmpEdge, edge_norRef));
257  //alb difference
258  tmpEdge = texelFetch(u_edge_alb, coordsFrag.xy + coords.xy, 0).xyz;
259  tmpEdge2 = tmpEdge - edge_albRef;
260  float dstAlb = dot(tmpEdge2.xyz, tmpEdge2.xyz);
261 
262  float tmp = dstPos / sigma_pos2 + dstAlb / sigma_alb2 + float(coords.z) / sigma_s2 + dstNor / sigma_nor2 ;
263  tmp = exp(-tmp);
264  //Texture Fetch
265  vec3 tmpCol = texelFetch(u_tex, coordsFrag.xy + coords.xy, 0).xyz;
266  color.xyz += tmpCol * tmp;
267  weight += tmp;
268  }
269 
270  f_color = vec4(weight > 0.0 ? color / weight : colRef, 1.0);
271  }
272  );
273 
274 }
275 
277 {
278 #ifdef PIC_DEBUG
279  printf("Number of samples: %d\n", ms->nSamples);
280 #endif
281 
282  technique.initStandard("330", vertex_source, fragment_source, "FilterGLBilateral2DSE");
283 
284  update(-1.0f, -1.0f, -1.0f, -1.0f);
285 }
286 
287 void FilterGLBilateral2DSE::update(float sigma_s, float sigma_p, float sigma_n, float sigma_a)
288 {
289 
290  bool flag = false;
291 
292  if(sigma_s > 0.0f) {
293  flag = (this->sigma_s == sigma_s);
294  this->sigma_s = sigma_s;
295  }
296 
297  if(sigma_p > 0.0f) {
298  flag = flag || (this->sigma_p == sigma_p);
299  this->sigma_p = sigma_p;
300  }
301 
302  if(sigma_n > 0.0f) {
303  flag = flag || (this->sigma_n == sigma_n);
304  this->sigma_n = sigma_n;
305  }
306 
307  if(sigma_a > 0.0f) {
308  flag = flag || (this->sigma_a == sigma_a);
309  this->sigma_a = sigma_a;
310  }
311 
312  int kernelSize = PrecomputedGaussian::getKernelSize(this->sigma_s);
313  int halfKernelSize = kernelSize >> 1;
314 
315  if(flag) {
316  Vec2i window = Vec2i(halfKernelSize, halfKernelSize);
317  ms->updateGL(window, halfKernelSize);
318  }
319 
320  //shader update
321  float sigmas2 = 2.0f * this->sigma_s * this->sigma_s;
322  float sigmap2 = 2.0f * this->sigma_p * this->sigma_p;
323  float sigman2 = 2.0f * this->sigma_n * this->sigma_n;
324  float sigmaa2 = 2.0f * this->sigma_a * this->sigma_a;
325 
326  technique.bind();
327  technique.setUniform1i("u_tex", 0);
328  technique.setUniform1i("u_poisson", 1);
329  technique.setUniform1i("u_rand", 2);
330 
331  technique.setUniform1i("u_edge_pos", 3);
332  technique.setUniform1i("u_edge_nor", 4);
333  technique.setUniform1i("u_edge_alb", 5);
334 
335  technique.setUniform1i("kernelSize", kernelSize);
336  technique.setUniform1f("kernelSizef", float(kernelSize));
337  technique.setUniform1f("sigma_s2", sigmas2);
338  technique.setUniform1f("sigma_pos2", sigmap2);
339  technique.setUniform1f("sigma_nor2", sigman2);
340  technique.setUniform1f("sigma_alb2", sigmaa2);
341  technique.setUniform1i("nSamples", ms->nSamples >> 1);
342  technique.unbind();
343 }
344 
346  ImageGL *imgOut)
347 {
348  if(imgIn[0] == NULL) {
349  return imgOut;
350  }
351 
352  int w = imgIn[0]->width;
353  int h = imgIn[0]->height;
354 
355  //TODO: check if other have height and frames swapped
356  if(imgOut == NULL) {
357  imgOut = new ImageGL(imgIn[0]->frames, w, h, imgIn[0]->channels, IMG_GPU, GL_TEXTURE_2D);
358  }
359 
360  if(fbo == NULL) {
361  fbo = new Fbo();
362  }
363 
364  fbo->create(w, h, imgIn[0]->frames, false, imgOut->getTexture());
365 
366  ImageGL *base = imgIn[0];
367  ImageGL *edge_pos = imgIn[1];
368  ImageGL *edge_nor = imgIn[2];
369  ImageGL *edge_alb = imgIn[3];
370 
371  //Rendering
372  fbo->bind();
373  glViewport(0, 0, (GLsizei)w, (GLsizei)h);
374 
375  //Shaders
376  technique.bind();
377 
378  //Textures
379  glActiveTexture(GL_TEXTURE5);
380  glBindTexture(GL_TEXTURE_2D, edge_alb->getTexture());
381 
382  glActiveTexture(GL_TEXTURE4);
383  glBindTexture(GL_TEXTURE_2D, edge_nor->getTexture());
384 
385  glActiveTexture(GL_TEXTURE3);
386  glBindTexture(GL_TEXTURE_2D, edge_pos->getTexture());
387 
388  glActiveTexture(GL_TEXTURE2);
389  glBindTexture(GL_TEXTURE_2D, imageRand->getTexture());
390 
391  glActiveTexture(GL_TEXTURE1);
392  glBindTexture(GL_TEXTURE_2D, ms->getTexture());
393 
394  glActiveTexture(GL_TEXTURE0);
395  glBindTexture(GL_TEXTURE_2D, base->getTexture());
396 
397  //Rendering aligned quad
398  quad->Render();
399 
400  //Fbo
401  fbo->unbind();
402 
403  //Shaders
404  technique.unbind();
405 
406  //Textures
407  glActiveTexture(GL_TEXTURE5);
408  glBindTexture(GL_TEXTURE_2D, 0);
409 
410  glActiveTexture(GL_TEXTURE4);
411  glBindTexture(GL_TEXTURE_2D, 0);
412 
413  glActiveTexture(GL_TEXTURE3);
414  glBindTexture(GL_TEXTURE_2D, 0);
415 
416  glActiveTexture(GL_TEXTURE2);
417  glBindTexture(GL_TEXTURE_2D, 0);
418 
419  glActiveTexture(GL_TEXTURE1);
420  glBindTexture(GL_TEXTURE_2D, 0);
421 
422  glActiveTexture(GL_TEXTURE0);
423  glBindTexture(GL_TEXTURE_2D, 0);
424 
425  return imgOut;
426 }
427 
428 } // end namespace pic
429 
430 #endif /* PIC_GL_FILTERING_FILTER_BILATERAL_2DS_HPP */
431 
static ImageGL * execute(std::string nameIn, float sigma_s, float sigma_p, float sigma_n, float sigma_a, int testing=1)
execute
Definition: filter_bilateral_2ds_e.hpp:106
void update(float sigma_s, float sigma_p, float sigma_n, float sigma_a)
update
TechniqueGL technique
Definition: display.hpp:45
The Fbo class.
Definition: display.hpp:32
Definition: image.hpp:37
int channels
Definition: filter_radial_basis_function.hpp:80
FilterGLBilateral2DSE(float sigma_s, float sigma_p, float sigma_n, float sigma_a)
FilterGLBilateral2DSE.
static int getKernelSize(float sigma)
KernelSize computes the size of a kernel in pixel give its sigma.
Definition: precomputed_gaussian.hpp:121
bool create(int width, int height, bool bDepth)
create
Definition: display.hpp:207
MRSamplersGL< 2 > * ms
Definition: filter_bilateral_2ds_e.hpp:34
GLuint generateTextureGL(GLenum target, GLenum format_type, bool mipmap)
generateTextureGL
void bind()
bind
Definition: display.hpp:189
GLuint glBeginTimeQuery()
glBeginTimeQuery
Definition: timings.hpp:29
GLuint getTexture()
getTexture
Definition: display.hpp:80
float sigma_n
Definition: filter_bilateral_2ds_e.hpp:33
#define MAKE_STRING(input_string)
The Image class stores an image as buffer of float.
Definition: filter_radial_basis_function.hpp:60
float sigma_a
Definition: filter_bilateral_2ds_e.hpp:33
GLuint64 glEndTimeQuery(GLuint64 ret)
glEndTimeQuery
Definition: timings.hpp:46
void initShaders()
initShaders
The ImageGL class.
Definition: image.hpp:42
GLuint getTexture() const
getTexture
Definition: display.hpp:369
Vec< 2, int > Vec2i
Vec2i.
Definition: vec.hpp:829
bool Write(std::string nameFile, LDR_type typeWrite, int writerCounter)
Write saves an Image into a file on the disk.
Definition: filter_radial_basis_function.hpp:1924
void setUniform1f(const char *name_uniform, float value0)
SetUniform1f.
Definition: display.hpp:247
Fbo * fbo
Definition: display.hpp:39
void FragmentShader()
FragmentShader.
The FilterGLBilateral2DSE class.
Definition: filter_bilateral_2ds_e.hpp:30
void updateGL(Vec< N, int > window, int nSamples)
updateGL
Definition: sampler_random_m.hpp:129
void bind()
bind
Definition: display.hpp:427
QuadGL * quad
Definition: display.hpp:42
The FilterGL class.
Definition: filter.hpp:35
static int main(int argc, char *argv[])
main
Definition: filter_bilateral_2ds_e.hpp:84
std::string getExtension(std::string name)
getExtension gets the extension of a file name.
Definition: string.hpp:186
void Render()
Render draws a quad on screen.
Definition: display.hpp:140
void setRand(unsigned int seed)
setRand
Definition: filter_radial_basis_function.hpp:1392
GLuint generateTexture()
generateTexture
Definition: sampler_random_m.hpp:151
The FilterGL class.
Definition: display.hpp:35
The MRSamplersGL class.
Definition: sampler_random_m.hpp:45
The ImageGL class.
Definition: display.hpp:42
The Vec class.
Definition: display.hpp:35
float sigma_s
Definition: filter_bilateral_2ds_e.hpp:33
int width
Definition: filter_radial_basis_function.hpp:80
bool initStandard(std::string version_number, std::string vertex_shader_source, std::string fragment_shader_source, std::string name)
initStandard
Definition: display.hpp:114
ImageGL * Process(ImageGLVec imgIn, ImageGL *imgOut)
Process.
float sigma_p
Definition: filter_bilateral_2ds_e.hpp:33
Definition: point_samplers.hpp:51
void unbind()
unbind
Definition: display.hpp:197
void loadToMemory()
loadToMemory
std::string vertex_source
Definition: display.hpp:57
GLuint getTexture() const
getTexture
Definition: image.hpp:369
Definition: bilateral_separation.hpp:25
std::string removeExtension(std::string name)
RemoveExtension removes the extension of a string.
Definition: string.hpp:132
void unbind()
unbind
Definition: display.hpp:442
std::vector< ImageGL * > ImageGLVec
ImageGLVec an std::vector of pic::ImageGL.
Definition: display.hpp:32
ImageGL * imageRand
Definition: filter_bilateral_2ds_e.hpp:37
std::string fragment_source
Definition: display.hpp:57
int nSamples
Definition: display.hpp:53
Definition: image.hpp:37
std::vector< ImageGL * > ImageGLVec
ImageGLVec an std::vector of pic::ImageGL.
Definition: image_vec.hpp:32
int height
Definition: filter_radial_basis_function.hpp:80
void setUniform1i(const char *name_uniform, int value0)
SetUniform.
Definition: display.hpp:236