Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
MultipleDepthWarp.cpp
1 /*
2  * MultipleDepthWarp.cpp
3  *
4  * Created on: Jan 28, 2010
5  * Author: africk
6  */
7 
8 #include <OpenGLFramework/SpecializedBatches/MultipleDepthWarp.hh>
9 #include <Utils/IOUtils.hh>
10 
11 using namespace std;
12 using namespace BIAS;
13 
14 MultipleDepthWarp::MultipleDepthWarp() {
15 
16  minDepth_ = 1000;
17  maxDepth_ = 7000;
18  numberOfSampForDepthCorr_ = 1000;
19 
20  depthCorrTexLUTP_ = NULL;
21 
22  useProjectiveTexturing_ = false;
23  zNear_ = 100;
24  zFar_ = 8000;
25  SetDiscardAngle(91);
26  initCalled_ = false;
27  depthScaleBeforeWarping_ = 1.0;
28  flop_ = false;
29  createDepthMaps_ = true;
30  multiStereoModus_ = false;
31  current_index_ = 0;
32  depthCorType_ = NONE;
33  warpType_ = DISPARITY;
34  flip_= false;
35 
36  clearColorBuffer_ = true;
37  baseline_ = 0.0;
38  focallengthContained_ = true;
39 }
40 
41 MultipleDepthWarp::~MultipleDepthWarp() {
42  for (unsigned int i = 0; i < depthMaps_.size(); i++) {
43  if (createDepthMaps_) {
44  delete depthMaps_[i];
45  }
46  delete resultDispTextures_[i];
47  }
48 }
49 
50 int MultipleDepthWarp::Init(const ProjectionParametersPerspective& targetCam,
51  std::vector<Projection>& sourceCameras, bool createDepthMaps) {
52  if (!initCalled_) {
53  createDepthMaps_ = createDepthMaps;
54  if (sourceCameras.empty()) {
55  BIASERR("sourceCameras.size() == 0 ");
56  return -1;
57  }
58 
59  targetParams_ = targetCam;
60  sourceParams_ = sourceCameras;
61 
62  unsigned int width, height;
63  targetParams_.GetImageSize(width, height);
64  viewport_.SetSize(width, height);
65  viewport_.SetOrigin(0, 0);
66 
67  modelViewMatrix_.MakeViewMatrixNew(targetParams_);
68  projectionMatrix_.MakeProjectionMatrixNew(targetParams_, zNear_, zFar_);
69 
70  depthMaps_.resize(sourceParams_.size());
71  resultDispTextures_.resize(sourceParams_.size());
72  resultColorTextures_.resize(sourceParams_.size());
73 
74  for (unsigned int i = 0; i < depthMaps_.size(); i++) {
75  if (createDepthMaps_) {
76  depthMaps_[i] = new glfTexture2D();
77 
78  depthMaps_[i]->Create();
79  depthMaps_[i]->SetMinFilter(GL_NEAREST);
80  depthMaps_[i]->SetMagFilter(GL_NEAREST);
81  depthMaps_[i]->SetWrapS(GL_CLAMP);
82  depthMaps_[i]->SetWrapT(GL_CLAMP);
83  batch_.SetTexture(depthMaps_[i], i);
84  }
85 
86  resultDispTextures_[i] = new glfTexture2D;
87  resultDispTextures_[i]->Create();
88  resultDispTextures_[i]->SetMagFilter(GL_NEAREST);
89  resultDispTextures_[i]->SetMinFilter(GL_NEAREST);
90  resultDispTextures_[i]->SetWrapS(GL_CLAMP);
91  resultDispTextures_[i]->SetWrapT(GL_CLAMP);
92  resultDispTextures_[i]->Allocate(width, height, GL_LUMINANCE32F_ARB);
93 
94  resultColorTextures_[i] = new glfTexture2D;
95  resultColorTextures_[i]->Create();
96  resultColorTextures_[i]->SetMagFilter(GL_LINEAR);
97  resultColorTextures_[i]->SetMinFilter(GL_LINEAR);
98  resultColorTextures_[i]->SetWrapS(GL_CLAMP);
99  resultColorTextures_[i]->SetWrapT(GL_CLAMP);
100  resultColorTextures_[i]->Allocate(width, height, GL_RGB);
101  }
102 
103  projectiveTexture_.Create();
104  projectiveTexture_.SetMinFilter(GL_LINEAR);
105  projectiveTexture_.SetMagFilter(GL_LINEAR);
106  projectiveTexture_.SetWrapS(GL_CLAMP);
107  projectiveTexture_.SetWrapT(GL_CLAMP);
108 
109  batch_.SetTexture(&projectiveTexture_, depthMaps_.size());
110 
112  * paramsDepth =
113  dynamic_cast<ProjectionParametersPerspectiveDepth*> (sourceParams_[0].GetParameters());
114  if (paramsDepth != NULL) {
115  CreateDepthCorrectionLUT_(*paramsDepth);
116  }
117 
118  depthBufferMode_.SetDepthTest(true);
119  batch_.SetDepthBufferMode(&depthBufferMode_);
120  batch_.SetProjectionMatrix(&projectionMatrix_);
121  batch_.SetModelViewMatrix(&modelViewMatrix_);
122  batch_.SetTextureMatrix(&textureMatrix_, 0);
123  batch_.SetViewport(&viewport_);
124 
125  resultZBufferTexture_.Create();
126  resultZBufferTexture_.SetMagFilter(GL_NEAREST);
127  resultZBufferTexture_.SetMinFilter(GL_NEAREST);
128  resultZBufferTexture_.SetWrapS(GL_CLAMP);
129  resultZBufferTexture_.SetWrapT(GL_CLAMP);
130  resultZBufferTexture_.Allocate(width, height, GL_DEPTH_COMPONENT);
131 
132  renderTarget_.Create();
133  renderTarget_.AttachTexture(*resultDispTextures_[0],
134  GL_COLOR_ATTACHMENT0_EXT);
135  renderTarget_.AttachTexture(*resultColorTextures_[0],
136  GL_COLOR_ATTACHMENT1_EXT);
137  renderTarget_.AttachTexture(resultZBufferTexture_,
138  GL_DEPTH_ATTACHMENT_EXT);
139  renderTarget_.CheckComplete();
140 
141  vector<GLenum> drawbuffers(2);
142  drawbuffers[0] = GL_COLOR_ATTACHMENT0_EXT;
143  drawbuffers[1] = GL_COLOR_ATTACHMENT1_EXT;
144  renderTarget_.SetDrawBuffers(drawbuffers);
145 
146  batch_.SetRenderTarget(&renderTarget_);
147  batch_.SetShaderProgram(&shaderProgram_);
148  if (multiStereoModus_) {
149  SetupShaders_(1);
150  } else {
151  SetupShaders_(0);
152  }
153  SetupPrimitiveRendering_();
154  }
155 
156  initCalled_ = true;
157  return 0;
158 }
159 
160 void MultipleDepthWarp::ChangeTargetCam(const ProjectionParametersPerspective& targetCam) {
161  targetParams_ = targetCam;
162 
163  unsigned int width, height;
164  targetParams_.GetImageSize(width, height);
165  viewport_.SetSize(width, height);
166  viewport_.SetOrigin(0, 0);
167 
168  modelViewMatrix_.MakeViewMatrixNew(targetParams_);
169  projectionMatrix_.MakeProjectionMatrixNew(targetParams_, zNear_, zFar_);
170 }
171 
172 int MultipleDepthWarp::SetProjectiveTextureCam(const ProjectionParametersPerspective& textureCam)
173 {
174  if (!initCalled_) {
175  return -1;
176  }
177 
178  textureMatrix_.MakeTextureMatrixNew(textureCam,false);
179 
180  return 0;
181 
182 }
183 
184 void
185  MultipleDepthWarp::UploadProjectiveTexture(const Image<unsigned char>& projectiveTexture)
186 {
187  projectiveTexture_.UploadImage(projectiveTexture);
188 }
189 
190 int MultipleDepthWarp::UploadDepthMap(Image<float>& depthMap,
191  unsigned int index) {
192  if (index >= depthMaps_.size()) {
193  BIASERR("could not upload depth map, index " << index << " out of bound " << depthMaps_.size());
194  return -1;
195  }
196 
197  depthMaps_[index]->UploadImage(depthMap);
198 
199  return 0;
200 }
201 
202 int MultipleDepthWarp::SetDepthMap(glfTexture2D* depthMap, unsigned int index) {
203  if (createDepthMaps_) {
204  BIASERR("to set depth map, Init must be called with createDepthMaps = false" << endl);
205  return -2;
206  }
207  if (index >= depthMaps_.size()) {
208  BIASERR("could not set depth map, index " << index << " out of bound " << depthMaps_.size());
209  return -1;
210  }
211 
212  depthMaps_[index] = depthMap;
213 
214  return 0;
215 }
216 
217 int MultipleDepthWarp::Warp(unsigned int index) {
218  if (initCalled_) {
219  if (index < sourceParams_.size()) {
220  current_index_ = index;
221  renderTarget_.AttachTexture(*resultDispTextures_[index],
222  GL_COLOR_ATTACHMENT0_EXT);
223  renderTarget_.AttachTexture(*resultColorTextures_[index],
224  GL_COLOR_ATTACHMENT1_EXT);
225  renderTarget_.ClearDepthBuffer(1.0);
226  if (clearColorBuffer_) {
227  renderTarget_.ClearColorBuffer(0, 0, 0, 0);
228  }
229  unsigned int width, height;
230  sourceParams_[index].GetParameters()->GetImageSize(width, height);
231  unsigned int numIndicesPerStrip = width * 2;
232  unsigned int first = index * numIndicesPerStrip * (height - 1);
233  unsigned int targetWidth, targetHeight;
234  targetParams_.GetImageSize(targetWidth, targetHeight);
235 
236  shaderProgram_.SetUniform("imageWidth", (float) targetWidth);
237  shaderProgram_.SetUniform("depthScaleBefore",
238  depthScaleBeforeWarping_);
239  shaderProgram_.SetUniform("depthImage", (int) index);
240  shaderProgram_.SetUniform("C", cameraCenters_[index]);
241  shaderProgram_.SetUniform("thr", thr_);
242  // shaderProgram_.SetUniform("dist_from_cam", dist_from_cam_);
243  // shaderProgram_.SetUniform("disp_for_dist_from_cam", disp_);
244  if(focallengthContained_) {
245  shaderProgram_.SetUniform("baselineFocallength", baseline_);
246  } else {
247  shaderProgram_.SetUniform("baselineFocallength", baseline_*(float)targetParams_.GetFocalLength());
248  }
249  shaderProgram_.SetUniform("warpType", (int) warpType_);
250  if (flop_) {
251  shaderProgram_.SetUniform("flop", (int) 1);
252  } else {
253  shaderProgram_.SetUniform("flop", (int) 0);
254  }
255 
256  for (unsigned int y = 0; y < height - 1; y++) {
257  batch_.SetRange(first, numIndicesPerStrip);
258  batch_.Draw();
259  first += numIndicesPerStrip;
260  }
261  } else {
262  BIASERR("index exceeds number of source parameters");
263  return -1;
264  }
265 
266  } else {
267  BIASERR("call SetProjectios(...) first");
268  return -1;
269  }
270 
271  return 0;
272 }
273 
274 int MultipleDepthWarp::Warp() {
275  if (initCalled_) {
276  renderTarget_.ClearDepthBuffer(1.0);
277  if (clearColorBuffer_) {
278  renderTarget_.ClearColorBuffer(0, 0, 0, 0);
279  }
280  unsigned int first = 0;
281  for (unsigned int i = 0; i < sourceParams_.size(); i++) {
282 
283  unsigned int targetWidth, targetHeight;
284  targetParams_.GetImageSize(targetWidth, targetHeight);
285 
286  shaderProgram_.SetUniform("depthImage", (int) i);
287  shaderProgram_.SetUniform("projTexture", (int) depthMaps_.size());
288 
289  shaderProgram_.SetUniform("C", cameraCenters_[i]);
290  if (flop_) {
291  shaderProgram_.SetUniform("flop", (int) 1);
292  } else {
293  shaderProgram_.SetUniform("flop", (int) 0);
294  }
295  if (flip_) {
296  shaderProgram_.SetUniform("flip", (int) 1);
297  } else {
298  shaderProgram_.SetUniform("flip", (int) 0);
299  }
300 
301  unsigned int width, height;
302  sourceParams_[i].GetParameters()->GetImageSize(width, height);
303  if (!multiStereoModus_) {
304  shaderProgram_.SetUniform("imageWidth", (float) targetWidth);
305  shaderProgram_.SetUniform("depthScaleBefore",
306  depthScaleBeforeWarping_);
307  shaderProgram_.SetUniform("thr", thr_);
308  shaderProgram_.SetUniform("corrTexture", (int) (depthMaps_.size() + 1));
309  if (useProjectiveTexturing_) {
310  shaderProgram_.SetUniform("useProjTex", (int) 1);
311  } else {
312  shaderProgram_.SetUniform("useProjTex", (int) 0);
313  }
314  shaderProgram_.SetUniform("minDepth", minDepth_);
315  shaderProgram_.SetUniform("maxDepth", maxDepth_);
316  shaderProgram_.SetUniform("depthRange", depthRange_);
317 // shaderProgram_.SetUniform("dist_from_cam", dist_from_cam_);
318 // shaderProgram_.SetUniform("disp_for_dist_from_cam", disp_);
319  if(focallengthContained_) {
320  shaderProgram_.SetUniform("baselineFocallength", baseline_);
321  } else {
322  shaderProgram_.SetUniform("baselineFocallength", baseline_*(float)targetParams_.GetFocalLength());
323  }
324  // cout << "warp type = " << warpType_ << endl;
325  shaderProgram_.SetUniform("warpType", (int) warpType_);
326  shaderProgram_.SetUniform("sourceImageWidth", (float) width);
327  shaderProgram_.SetUniform("sourceImageHeight", (float) height);
328 
329  if (depthCorType_ == LINEAR) {
331  * paramsDepth =
332  dynamic_cast<ProjectionParametersPerspectiveDepth*> (sourceParams_[i].GetParameters());
333  std::vector<double> params;
334  paramsDepth->GetDepthCalibrationParameters(params);
335  shaderProgram_.SetUniform("d0", (float) params[0]);
336  shaderProgram_.SetUniform("d1", (float) params[1]);
337 
338  }
339 
340  shaderProgram_.SetUniform("depthCorType", (int) depthCorType_);
341  }
342 
343 
344 
345  batch_.SetTexture(&projectiveTexture_,0);
346  batch_.SetTexture(depthMaps_[i], i);
347 
348  unsigned int numIndicesPerStrip = width * 2;
349  for (unsigned int y = 0; y < height - 1; y++) {
350  batch_.SetRange(first, numIndicesPerStrip);
351  batch_.Draw();
352  first += numIndicesPerStrip;
353  }
354  }
355  } else {
356  BIASERR("call SetProjectios(...) first");
357  return -1;
358  }
359 
360  return 0;
361 }
362 
363 int MultipleDepthWarp::SetupNViewsWarp(const double& distToScreen,
364  const double& zoom, const double& shift,
365  unsigned int numberOfViews, unsigned int centralViewIndex, bool separate)
366 {
367  if (initCalled_) {
368 
369  double dScreen = distToScreen;
370 
371  if (dScreen <= 0) {
372  dScreen = 10e-9;
373  }
374 
375  numberOfViews_ = numberOfViews;
376  separate_ = separate;
377 
378  if (resultDepthMapsForNViews_.size() != numberOfViews) {
379 
380  for (unsigned int i = 0; i < resultDepthMapsForNViews_.size(); i++) {
381  delete resultDepthMapsForNViews_[i];
382  delete resultTexturesForNViews_[i];
383  }
384 
385  resultDepthMapsForNViews_.resize(numberOfViews);
386  resultTexturesForNViews_.resize(numberOfViews);
387  modelViewMatricesForNViewWarp_.resize(numberOfViews);
388  projectionMatricesForNViewWarp_.resize(numberOfViews);
389  }
390  unsigned int width, height;
391  targetParams_.GetImageSize(width,height);
392 
393  for (unsigned int i = 0; i < numberOfViews; i++) {
394  ProjectionParametersPerspective ppp = targetParams_;
395 
396  int index = (int) i - (int) centralViewIndex;
397 
398  HomgPoint2D leftTop(0.5,0.5,1);
399  HomgPoint2D rightBottom((double)width-0.5, (double) height - 0.5,1);
400 
401  Vector3<double> p, pos;
402  ppp.UnProjectLocal(leftTop, pos, p, true);
403 
404  p = (p / p[2]) * dScreen;
405 
406  p[0] /= zoom;
407  p[1] /=zoom;
408 
409  p[0] = p[0]- (index* shift);
410 
411  Vector3<double> q;
412  ppp.UnProjectLocal(rightBottom, pos, q, true);
413 
414  q = (q / q[2]) * dScreen;
415 
416  q[0] /= zoom;
417  q[1] /= zoom;
418 
419  q[0] = q[0] - (index*shift);
420 
421  ppp.SetIntrinsics(p,q,width,height);
422 
423  ppp.SetC(ppp.GetC() + Vector3<double>((index*shift),0,0));
424 
425  modelViewMatricesForNViewWarp_[i].MakeViewMatrixNew(ppp);
426  projectionMatricesForNViewWarp_[i].MakeProjectionMatrixNew(ppp, zNear_, zFar_);
427 
428  if (separate) {
429 
430 
431  for (unsigned int i = 0; i < numberOfViews; i++) {
432  resultDepthMapsForNViews_[i] = new glfTexture2D();
433  resultDepthMapsForNViews_[i]->Create();
434  resultDepthMapsForNViews_[i]->SetMagFilter(GL_NEAREST);
435  resultDepthMapsForNViews_[i]->SetMinFilter(GL_NEAREST);
436  resultDepthMapsForNViews_[i]->SetWrapS(GL_CLAMP);
437  resultDepthMapsForNViews_[i]->SetWrapT(GL_CLAMP);
438  resultDepthMapsForNViews_[i]->Allocate(width, height, GL_LUMINANCE32F_ARB);
439 
440  resultTexturesForNViews_[i] = new glfTexture2D;
441  resultTexturesForNViews_[i]->Create();
442  resultTexturesForNViews_[i]->SetMagFilter(GL_LINEAR);
443  resultTexturesForNViews_[i]->SetMinFilter(GL_LINEAR);
444  resultTexturesForNViews_[i]->SetWrapS(GL_CLAMP);
445  resultTexturesForNViews_[i]->SetWrapT(GL_CLAMP);
446  resultTexturesForNViews_[i]->Allocate(width, height, GL_RGB);
447  }
448  } else {
449  resultDepthMapsForNViews_.resize(1);
450  resultTexturesForNViews_.resize(1);
451  resultDepthMapsForNViews_[0] = new glfTexture2D();
452  resultDepthMapsForNViews_[0]->Create();
453  resultDepthMapsForNViews_[0]->SetMagFilter(GL_NEAREST);
454  resultDepthMapsForNViews_[0]->SetMinFilter(GL_NEAREST);
455  resultDepthMapsForNViews_[0]->SetWrapS(GL_CLAMP);
456  resultDepthMapsForNViews_[0]->SetWrapT(GL_CLAMP);
457  resultDepthMapsForNViews_[0]->Allocate(width, height*numberOfViews, GL_LUMINANCE32F_ARB);
458 
459  resultTexturesForNViews_[0] = new glfTexture2D;
460  resultTexturesForNViews_[0]->Create();
461  resultTexturesForNViews_[0]->SetMagFilter(GL_LINEAR);
462  resultTexturesForNViews_[0]->SetMinFilter(GL_LINEAR);
463  resultTexturesForNViews_[0]->SetWrapS(GL_CLAMP);
464  resultTexturesForNViews_[0]->SetWrapT(GL_CLAMP);
465  resultTexturesForNViews_[0]->Allocate(width, height*numberOfViews, GL_RGB);
466 
467  renderTarget_.AttachTexture(*resultDepthMapsForNViews_[0],
468  GL_COLOR_ATTACHMENT0_EXT);
469  renderTarget_.AttachTexture(*resultTexturesForNViews_[0],
470  GL_COLOR_ATTACHMENT1_EXT);
471  resultZBufferTexture_.Allocate(width, height*numberOfViews_, GL_DEPTH_COMPONENT);
472 
473  }
474  }
475 
476  } else {
477  BIASERR("call SetProjectios(...) first");
478  return -1;
479  }
480 
481  return 0;
482 }
483 
484 int MultipleDepthWarp::WarpNViews()
485 {
486  if (initCalled_) {
487 
488  if (separate_) {
489  for (unsigned int i = 0; i < numberOfViews_; i++) {
490  batch_.SetModelViewMatrix(&modelViewMatricesForNViewWarp_[i]);
491  batch_.SetProjectionMatrix(&projectionMatricesForNViewWarp_[i]);
492 
493  renderTarget_.AttachTexture(*resultDepthMapsForNViews_[i],
494  GL_COLOR_ATTACHMENT0_EXT);
495  renderTarget_.AttachTexture(*resultTexturesForNViews_[i],
496  GL_COLOR_ATTACHMENT1_EXT);
497 
498  Warp();
499  }
500  } else {
501 
502  unsigned int width, height;
503 
504  targetParams_.GetImageSize(width,height);
505 
506 
507  for (unsigned int i = 0; i < numberOfViews_ ; i++) {
508 
509  batch_.SetModelViewMatrix(&modelViewMatricesForNViewWarp_[i]);
510  batch_.SetProjectionMatrix(&projectionMatricesForNViewWarp_[i]);
511 
512  viewport_.SetOrigin(0, (numberOfViews_ - 1 - i) *height);
513  if (i==0) {
514  clearColorBuffer_ = true;
515  } else {
516  clearColorBuffer_ = false;
517  }
518  Warp();
519  }
520  }
521  } else {
522  BIASERR("call SetProjectios(...) first");
523  return -1;
524  }
525 
526  return 0;
527 }
528 
529 
530 int MultipleDepthWarp::GetWarpedDisparity(Image<float>& dispMap) {
531  unsigned int width, height;
532  targetParams_.GetImageSize(width, height);
533  if (dispMap.GetWidth() != width || dispMap.GetHeight() != height
534  || dispMap.GetChannelCount() != 1) {
535  dispMap.Release();
536  dispMap.Init(width, height, 1);
537  }
538  resultDispTextures_[current_index_]->CopyToImage(dispMap);
539 
540  return 0;
541 }
542 
543 
544 int MultipleDepthWarp::GetProjectedTexture(Image<unsigned char>& texture) {
545  unsigned int width, height;
546  targetParams_.GetImageSize(width, height);
547  if (texture.GetWidth() != width || texture.GetHeight() != height
548  || texture.GetChannelCount() != 3) {
549  texture.Release();
550  texture.Init(width, height, 3);
551  }
552  resultColorTextures_[current_index_]->CopyToImage(texture);
553 
554  return 0;
555 }
556 
557 int MultipleDepthWarp::GetWarpedZBuffer(Image<float>& zbuffer) {
558  unsigned int width, height;
559  targetParams_.GetImageSize(width, height);
560  if (zbuffer.GetWidth() != width || zbuffer.GetHeight() != height
561  || zbuffer.GetChannelCount() != 1) {
562  zbuffer.Release();
563  zbuffer.Init(width, height, 1);
564  }
565  resultZBufferTexture_.CopyToImage(zbuffer);
566 
567  return 0;
568 }
569 
570 void MultipleDepthWarp::SetDispForDistance(const float& dist_from_cam,
571  const float& disp) {
572  //dist_from_cam_ = dist_from_cam;
573  //disp_ = disp;
574  baseline_ = disp*dist_from_cam;
575  focallengthContained_= true;
576 }
577 
578 void MultipleDepthWarp::
579  SetBaseline(const float &baseline)
580 {
581  baseline_ = baseline;
582  focallengthContained_= false;
583 }
584 
585 void MultipleDepthWarp::SetZNearAndZFar(const float& zNear, const float& zFar) {
586  zNear_ = zNear;
587  zFar_ = zFar;
588 
589  if (initCalled_) {
590  projectionMatrix_.MakeProjectionMatrixNew(targetParams_, zNear_, zFar_);
591  }
592 }
593 
594 void MultipleDepthWarp::SetDiscardAngle(float degree) {
595  thr_ = cos(M_PI * degree / 180.0);
596 }
597 
598 void MultipleDepthWarp::SetDepthScaleBeforeWarping(float scale) {
599  depthScaleBeforeWarping_ = scale;
600 }
601 
602 //#####################################
603 // PRIVATE
604 //#####################################
605 void MultipleDepthWarp::SetupPrimitiveRendering_() {
606  glfVertexFormat vertexFormat;
607  vertexFormat.AddAttribute(glfVertexFormat::ATTRIB_POSITION, GL_FLOAT, 4);
608  vertexFormat.AddAttribute(glfVertexFormat::ATTRIB_TEXCOORD, 0, GL_FLOAT, 2);
609 
610  const int numComponenents = 6;//4 for vertex 2 for tex coord
611 
612  // count number of vertices
613  unsigned int sizeOfVertexBuffer = 0;
614  unsigned int sizeOfElementBuffer = 0;
615  for (unsigned int i = 0; i < sourceParams_.size(); i++) {
616  unsigned int width, height;
617  sourceParams_[i].GetParameters()->GetImageSize(width, height);
618  sizeOfElementBuffer += width * (height - 1) * 2;
619  sizeOfVertexBuffer += width * height * numComponenents;
620  }
621 
622  float* vertexData = new float[sizeOfVertexBuffer];
623  GLuint* triangleIndices = new GLuint[sizeOfElementBuffer];
624 
625  unsigned int numTriangleIndex = 0;
626  unsigned int numVertexIndex = 0;
627  unsigned int bufferOffset = 0;
628  for (unsigned int i = 0; i < sourceParams_.size(); i++) {
629  unsigned int width, height;
630  sourceParams_[i].GetParameters()->GetImageSize(width, height);
631  cameraCenters_.push_back(sourceParams_[i].GetC());
632 
633  for (unsigned int y = 0; y < height - 1; y++) {
634  for (unsigned int x = 0; x < width; x++) {
635  /* v1
636  * i0--- i2
637  * | / |
638  * | / |
639  * i1 i3
640  */
641  triangleIndices[numTriangleIndex++] = y * width + x
642  + bufferOffset;//up
643  triangleIndices[numTriangleIndex++] = (y + 1) * width + x
644  + bufferOffset;//below
645  }
646  }
647 
648  bufferOffset += width * height;
649 
650  // create vertices for source camera i
651  for (unsigned int y = 0; y < height; y++) {
652  for (unsigned int x = 0; x < width; x++) {
653  HomgPoint2D imgPoint(x, y);
654  Vector3<double> ray, p;
655  sourceParams_[i].UnProjectToRay(imgPoint, p, ray, 0, false);
656 
657  if (ray.NormL2() > 1e-12) {
658  ray.Normalize();
659  } else {
660  BIASERR("error");
661  }
662 
663  vertexData[numVertexIndex++] = static_cast<float> (ray[0]);
664  vertexData[numVertexIndex++] = static_cast<float> (ray[1]);
665  vertexData[numVertexIndex++] = static_cast<float> (ray[2]);
666  vertexData[numVertexIndex++] = 1.0;
667 
668  vertexData[numVertexIndex++] = (static_cast<float> (x) + 0.5)
669  / static_cast<float> (width);
670  vertexData[numVertexIndex++] = (static_cast<float> (y) + 0.5)
671  / static_cast<float> (height);
672  }
673  }
674  }
675 
676  vertices_.Create(sizeOfVertexBuffer / numComponenents, vertexFormat,
677  vertexData);
678  elements_.Create(sizeOfElementBuffer, GL_UNSIGNED_INT, GL_TRIANGLE_STRIP,
679  triangleIndices);
680 
681  batch_.SetElementBuffer(&elements_);
682  batch_.SetVertexBuffer(&vertices_);
683  delete[] triangleIndices;
684  delete[] vertexData;
685 
686 }
687 
688 void MultipleDepthWarp::SetupShaders_(int shaderType) {
689  if (shaderType == 0) {
690  string
691  vertexShaderCode =
692  ""
693  "uniform sampler2D depthImage;\n"
694  "uniform sampler2D corrTexture;"
695  "uniform vec3 C;\n"
696  "uniform float depthScaleBefore;\n"
697  "uniform float imageWidth;\n"
698  "uniform float sourceImageHeight;"
699  "uniform float sourceImageWidth;"
700  "//uniform float dist_from_cam;\n"
701  "//uniform float disp_for_dist_from_cam;\n"
702  "uniform float baselineFocallength;\n"
703  "uniform int flop;"
704  "uniform int flip;"
705  "uniform int warpType;"
706  "uniform float d0;"
707  "uniform float d1;"
708  "uniform float minDepth;"
709  "uniform float maxDepth;"
710  "uniform float depthRange;"
711  "uniform int depthCorType;"
712  ""
713  "varying float disp;\n"
714  ""
715  "void main() {\n"
716  "\n"
717  "vec2 coord = gl_MultiTexCoord0.st;\n"
718  "vec2 tmp_coord = coord;\n"
719  "if (flop==1)\n"
720  "coord[0] = 1.0-coord[0];\n"
721  "if (flip ==1)\n"
722  "coord[1] = 1.0 - coord[1];\n"
723  "float depth = texture2D(depthImage, coord).r * depthScaleBefore;\n"
724  "if (depthCorType == 2) {\n"
725  "depth = (d1 + 1)* depth + d0;\n"
726  "}\n"
727  "\n"
728  //"if (depth == 0) depth = 10000;\n" //how to treat this? better move to negative and discard in geometry shader
729  "vec4 depthAdjustedVertex = gl_Vertex * depth;\n"
730  "if(depth > 0) {\n"
731  " if (depthCorType == 1) {\n"
732  " if (depthAdjustedVertex[2] < maxDepth && depthAdjustedVertex[2] > minDepth) {\n"
733  " float texCoordForZ = (depthAdjustedVertex[2] - minDepth) / depthRange;\n"
734  " float newZValue = texture2D(corrTexture, vec2(texCoordForZ,0.5)).r;\n"
735  " depthAdjustedVertex = (depthAdjustedVertex / depthAdjustedVertex[2])*newZValue;\n"
736  " }\n"
737  " }\n"
738  " depthAdjustedVertex.w = 1.0;\n"
739  " depthAdjustedVertex[0]+=C[0];\n"
740  " depthAdjustedVertex[1]+=C[1];\n"
741  " depthAdjustedVertex[2]+=C[2];\n"
742  " \n"
743  " if (warpType == 0) {\n"
744  " //vec4 tmp = gl_ModelViewProjectionMatrix * vec4(imageWidth,0.0,0.0,0.0);\n"
745  " //vec4 t = vec4(abs(((dist_from_cam*disp_for_dist_from_cam)/tmp[0])), 0.0,0.0,0.0);\n"
746  " //vec4 proj_t = gl_ModelViewProjectionMatrix * t;\n"
747  " "
748  " //disp = proj_t[0]*imageWidth;\n"
749  " // if(baseline>0)\n"
750  " disp = baselineFocallength;\n"
751  " } else {//else depth > 0 \n"
752  " disp = length(depthAdjustedVertex.xyz);\n"
753  " }\n"
754  "} else {\n"
755  " disp = -1.0; \n"
756  "}\n"
757  "\n"
758  "gl_Position = depthAdjustedVertex;\n"
759  "\n"
760  "}\n";
761 
762 
763  // IOUtils::PrintWithLineNumbers(vertexShaderCode);
764 
765  string fragmentShaderCode = ""
766  "uniform sampler2D projTexture;"
767  "varying float resDisp;\n"
768  ""
769  "void main() {\n"
770  "gl_FragData[0].r = resDisp;\n"
771  // "vec2 coord = gl_TexCoord[0];"
772  // "coord = coord / gl_TexCoord[0].p;"
773  // "coord[1] = 1.0 - coord[1];"
774  "gl_FragData[1].rgb = texture2DProj(projTexture, gl_TexCoord[0]);"
775  // "gl_FragData[1].rgb = texture2D(projTexture, coord);"
776  // "gl_FragData[1].rgb = vec3(1,0,0);"
777  "}\n";
778 
779  string geometryShaderCode = ""
780  "#extension GL_EXT_geometry_shader4 : enable\n"
781  ""
782  "varying in float disp[3];\n"
783  "varying out float resDisp;\n"
784  "uniform vec3 C;\n"
785  "uniform float thr;\n"
786  "uniform int warpType;"
787  "uniform int useProjTex;"
788  ""
789  "void main() {\n"
790  ""
791  ""
792  "vec4 v0 = gl_PositionIn[0];"
793  "vec4 v1 = gl_PositionIn[1];"
794  "vec4 v2 = gl_PositionIn[2];"
795  ""
796  "vec3 mean_vec = (v0.xyz+v1.xyz+v2.xyz)/3.0;"
797  ""
798  "vec3 cam_dir = C-mean_vec;"
799  "vec3 dir1 = v0.xyz - v1.xyz;"
800  "vec3 dir2 = v2.xyz - v1.xyz;"
801  ""
802  "vec3 n = cross(dir1,dir2);"
803  "vec3 norm_n = normalize(n);"
804  "vec3 norm_cam = normalize(cam_dir);"
805  ""
806  "float res = dot(norm_n,norm_cam);"
807  ""
808  "if (res < thr && disp[0] >= 0 && disp[1] >= 0 && disp[2] >= 0) {"
809  ""
810  "gl_Position = gl_ModelViewProjectionMatrix*v0;"
811  "if (useProjTex == 1)"
812  "gl_TexCoord[0] = gl_TextureMatrix[0] * v0;"
813  "if (warpType == 0) {"
814  "resDisp = disp[0]/gl_Position[3];\n"
815  // "resDisp = disp[0];\n"
816  "} else {"
817  "resDisp = disp[0];\n"
818  "}"
819  "EmitVertex();"
820  ""
821  "gl_Position = gl_ModelViewProjectionMatrix*v1;"
822  "if (useProjTex == 1)"
823  "gl_TexCoord[0] = gl_TextureMatrix[0] * v1;"
824  "if (warpType == 0) {"
825  "resDisp = disp[1]/gl_Position[3];\n"
826  // "resDisp = disp[0];\n"
827  "} else {"
828  "resDisp = disp[1];\n"
829  "}"
830  "EmitVertex();"
831  ""
832  "gl_Position = gl_ModelViewProjectionMatrix*v2;"
833  "if (useProjTex == 1)"
834  "gl_TexCoord[0] = gl_TextureMatrix[0] * v2;"
835  "if (warpType == 0) {"
836  "resDisp = disp[2]/gl_Position[3];\n"
837  // "resDisp = disp[0];\n"
838  "} else {"
839  "resDisp = disp[2];\n"
840  "}"
841  "EmitVertex();"
842  ""
843  "}"
844  ""
845  ""
846  "}\n";
847 
848  vertexShader_.Create(GL_VERTEX_SHADER, vertexShaderCode);
849  fragmentShader_.Create(GL_FRAGMENT_SHADER, fragmentShaderCode);
850  geometryShader_.Create(GL_GEOMETRY_SHADER_EXT, geometryShaderCode);
851  shaderProgram_.Create();
852  shaderProgram_.AttachShader(vertexShader_);
853  shaderProgram_.AttachShader(fragmentShader_);
854  shaderProgram_.AttachShader(geometryShader_);
855 
856  glProgramParameteriEXT(shaderProgram_.GetProgramId(),
857  GL_GEOMETRY_VERTICES_OUT_EXT, 3);
858  glProgramParameteriEXT(shaderProgram_.GetProgramId(),
859  GL_GEOMETRY_INPUT_TYPE_EXT, GL_TRIANGLES);
860  glProgramParameteriEXT(shaderProgram_.GetProgramId(),
861  GL_GEOMETRY_OUTPUT_TYPE_EXT, GL_TRIANGLE_STRIP);
862  shaderProgram_.Link();
863 
864  } else {
865 
866  string fragmentShaderCode="";
867  string
868  vertexShaderCode =
869  ""
870  "uniform sampler2D depthImage;\n"
871  "uniform vec3 C;\n"
872  "uniform int flop;"
873  "uniform int flip;"
874  ""
875  "void main() {\n"
876  ""
877  "vec2 coord = gl_MultiTexCoord0.st;"
878  ""
879  "if (flop==1)"
880  "coord[0] = 1.0-coord[0];"
881  "if (flip ==1)"
882  "coord[1] = 1.0 - coord[1];"
883  ""
884  "float depth = texture2D(depthImage, coord).r;\n"
885  ""
886  "if (depth == 0) depth = 10000;\n"
887  "vec4 depthAdjustedVertex = gl_Vertex * depth;\n"
888  "depthAdjustedVertex.w = 1.0;\n"
889  "depthAdjustedVertex[0]+=C[0];\n"
890  "depthAdjustedVertex[1]+=C[1];\n"
891  "depthAdjustedVertex[2]+=C[2];\n"
892  ""
893  "gl_Position = gl_ModelViewProjectionMatrix*depthAdjustedVertex;"
894  "gl_TexCoord[0] = gl_TextureMatrix[0] * depthAdjustedVertex;"
895  ""
896  "}\n";
897  if (shaderType == 1) {
898  fragmentShaderCode = ""
899  "uniform sampler2D projTexture;"
900  ""
901  "void main() {\n"
902  "gl_FragData[1].rgb = texture2DProj(projTexture, gl_TexCoord[0]);"
903  "}\n";
904  }
905 
906  vertexShader_.Create(GL_VERTEX_SHADER, vertexShaderCode);
907  fragmentShader_.Create(GL_FRAGMENT_SHADER, fragmentShaderCode);
908 
909  shaderProgram_.Create();
910  shaderProgram_.AttachShader(vertexShader_);
911  shaderProgram_.AttachShader(fragmentShader_);
912 
913  shaderProgram_.Link();
914  }
915 
916 }
917 
918 void MultipleDepthWarp::CreateDepthCorrectionLUT_(ProjectionParametersPerspectiveDepth& pppd)
919 {
920  cout << "---------------------" << endl;
921  depthCorrImageLUT_.Init(numberOfSampForDepthCorr_, 2, 1);
922  depthCorrImageLUT_.SetColorModel(ImageBase::CM_Grey);
923  pppd.GetMinMaxDepth(minDepth_,maxDepth_);
924 
925  depthRange_ = maxDepth_ - minDepth_;
926 
927  cout << minDepth_ << " max depth " << maxDepth_ << endl;
928 
929  float step = depthRange_ / (float) numberOfSampForDepthCorr_;
930 
931 //#pragma omp parallel for
932  for (int i = 0; i < (int)numberOfSampForDepthCorr_; i++) {
933  float depth = i*step + minDepth_;
934  // cout << "depth = " << depth;
935  HomgPoint2D pos(0,0,1);
936  pppd.UnDistortDepth(pos,depth,true);
937  // cout << "undistort depth = " << depth << endl;
938  depthCorrImageLUT_.SetPixel(depth, i, 0);
939  depthCorrImageLUT_.SetPixel(depth, i, 1);
940 // depthCorrImageLUT_.SetPixel(depth, 1, 0);
941  }
942 
943 // return;
944 
945  if (depthCorrTexLUTP_ != NULL) {
946  delete depthCorrTexLUTP_;
947  depthCorrTexLUTP_ = NULL;
948  }
949  depthCorrTexLUTP_ = new glfTexture2D();
950  depthCorrTexLUTP_->Create();
951  depthCorrTexLUTP_->SetMagFilter(GL_LINEAR);
952  depthCorrTexLUTP_->SetMinFilter(GL_LINEAR);
953  depthCorrTexLUTP_->SetWrapS(GL_CLAMP);
954  depthCorrTexLUTP_->SetWrapT(GL_CLAMP);
955  depthCorrTexLUTP_->UploadImage(depthCorrImageLUT_);
956 
957  batch_.SetTexture(depthCorrTexLUTP_, depthMaps_.size() + 1);
958 }
virtual BIAS::Vector3< double > GetC() const
Get projection center.
void Release()
reimplemented from ImageBase
Definition: Image.cpp:1579
int SetIntrinsics(double minPhi, double maxPhi, double minTheta, double maxTheta, double angleStep, double aspectratio=1.0)
Method calculates K-Matrix and image size from specified angles.
class HomgPoint2D describes a point with 2 degrees of freedom in projective coordinates.
Definition: HomgPoint2D.hh:67
additional depth calibration parameters for a perspective depth camera to be used for ToF-(PMD) camer...
A 2D texture.
Definition: glfTexture2D.hh:40
void Create()
Creates the texture but does not upload any data yet.
Definition: glfTexture.cpp:80
camera parameters which define the mapping between rays in the camera coordinate system and pixels in...
void UnDistortDepth(HomgPoint2D const &pos, float &d, bool bIsInCartesianCoords=false)
UnDistort depth value d at image position pos.
unsigned int GetWidth() const
Definition: ImageBase.hh:312
unsigned int GetChannelCount() const
returns the number of Color channels, e.g.
Definition: ImageBase.hh:382
void AddAttribute(Attribute attrib, int index, GLenum type, int size, bool normalized=false)
Adds a vertex attribute to the format.
unsigned int GetHeight() const
Definition: ImageBase.hh:319
virtual int GetImageSize(unsigned int &Width, unsigned int &Height) const
Obtain image dimensions.
void Init(unsigned int Width, unsigned int Height, unsigned int channels=1, enum EStorageType storageType=ST_unsignedchar, const bool interleaved=true)
calls Init from ImageBase storageType is ignored, just dummy argument
Definition: Image.cpp:421
A vertex format describes the attributes of a vertex.
void GetMinMaxDepth(float &minDepth, float &maxDepth)
get the minimum and maximum depth values with which the calibration has been done ...
void GetDepthCalibrationParameters(std::vector< double > &params)
Get the depth calibration parameters.
virtual void UnProjectLocal(const HomgPoint2D &pos, Vector3< double > &pointOnRay, Vector3< double > &direction, bool IgnoreDistortion=false) const
calculates the viewing ray from the camera center (in the camera coordinate system) which belongs to ...
virtual void SetC(const BIAS::Vector3< double > &C)
Set projection center.
Vector3< T > & Normalize()
normalize this vector to length 1
Definition: Vector3.hh:663
double NormL2() const
the L2 norm sqrt(a^2 + b^2 + c^2)
Definition: Vector3.hh:633