Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
RectificationViaProjectionMappingBase.cpp
1 /*
2  This file is part of the BIAS library (Basic ImageAlgorithmS).
3 
4  Copyright (C) 2003-2009 (see file CONTACT for details)
5  Multimediale Systeme der Informationsverarbeitung
6  Institut fuer Informatik
7  Christian-Albrechts-Universitaet Kiel
8 
9 
10  BIAS is free software; you can redistribute it and/or modify
11  it under the terms of the GNU Lesser General Public License as published by
12  the Free Software Foundation; either version 2.1 of the License, or
13  (at your option) any later version.
14 
15  BIAS is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  GNU Lesser General Public License for more details.
19 
20  You should have received a copy of the GNU Lesser General Public License
21  along with BIAS; if not, write to the Free Software
22  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23  */
24 
25 #include <Image/RectificationViaProjectionMappingBase.hh>
26 
27 #include <Image/RectificationViaProjectionMappingBase.hh>
28 #include <Image/ProjectionMapping.hh>
29 #include <Geometry/Triangulation.hh>
30 #include <limits>
31 
32 //#define validitydebug
33 #ifdef validitydebug
34 #include <Base/Image/ImageIO.hh>
35 #endif
36 
37 // enable this for gradient based alignemnt of grey values along epipolar lines
38 //#define SUBPIXEL_REFINEMENT
39 #ifdef SUBPIXEL_REFINEMENT
40 # include <Matcher2D/TrackerBaseWeighted1D.hh>
41 # include <Base/Image/ImageConvert.hh>
42 # include <Filter/GradientSimple.hh>
43 # include <Filter/Gauss.hh>
44 # include <Base/Image/ImageIO.hh>
45 #endif
46 
47 #define PARENT RectificationBase<InputStorageType, OutputStorageType>
48 
49 using namespace BIAS;
50 using namespace std;
51 
52 template<class InputStorageType, class OutputStorageType>
54  OutputStorageType>::~RectificationViaProjectionMappingBase()
55  {
56  delete rectPPA_;
57  delete rectPPB_;
58  }
59 
60 template<class InputStorageType, class OutputStorageType>
63  const std::string& stringID, const double& scale) :
64  stringID_(stringID), rectPPA_(NULL), rectPPB_(NULL), scale_(scale),
65  targetWidth_(0), rectificationParamsAreValid_(false),
66  interpolationType_(MapTrilinear), mappingInitialized_(false),
67  thetaMinOverride_(0), thetaMaxOverride_(M_PI), phiMinOverride_(-M_PI),
68  phiMaxOverride_(M_PI), useLookUpTables_(true)
69  {
70  secondFill_ = std::numeric_limits<OutputStorageType>::max();
71  }
72 
73 template<class InputStorageType, class OutputStorageType>
74  int
76  OutputStorageType>::SetCameraA(BIAS::Camera<InputStorageType>& cam)
77  {
78  /* rectificationParamsAreValid_ = false;
79  return PARENT::SetCameraA(cam);*/
80  cam.ParseMetaData();
81  return SetCameraA(cam, cam.GetProj().GetParameters());
82  }
83 
84 template<class InputStorageType, class OutputStorageType>
85  int
87  OutputStorageType>::SetCameraA(const BIAS::Image<InputStorageType>& img,
89  {
90  int res = PARENT::SetCameraA(img, proj);
91  if (res == 0)
92  {
93  rectificationParamsAreValid_ = false;
94  }
95  return res;
96  }
97 
98 template<class InputStorageType, class OutputStorageType>
99  int
101  OutputStorageType>::SetCameraB(BIAS::Camera<InputStorageType>& cam)
102  {
103  //rectificationParamsAreValid_ = false;
104  //return PARENT::SetCameraB(cam);
105  cam.ParseMetaData();
106  return SetCameraB(cam, cam.GetProj().GetParameters());
107  }
108 
109 template<class InputStorageType, class OutputStorageType>
110  int
112  OutputStorageType>::SetCameraB(const BIAS::Image<InputStorageType>& img,
113  const BIAS::ProjectionParametersBase* proj)
114  {
115  int res = PARENT::SetCameraB(img, proj);
116  if (res == 0)
117  {
118  rectificationParamsAreValid_ = false;
119  }
120  return res;
121  }
122 
123 template<class InputStorageType, class OutputStorageType>
124  void
126  OutputStorageType>::SetInterpolationMethod(
127  InterpolationMethod interpolationType)
128  {
129  interpolationType_ = interpolationType;
130  rectificationParamsAreValid_ = false;
131  }
132 
133 template<class InputStorageType, class OutputStorageType>
134  bool
136  OutputStorageType>::AreRectificationParametersValid_()
137  {
138  if (!rectificationParamsAreValid_)
139  {
140  if (DetermineScaledRectificationParameters_() == 0)
141  {
142  rectificationParamsAreValid_ = true;
143  mappingInitialized_ = false;
144  }
145  }
146  return rectificationParamsAreValid_;
147  }
148 
149 template<class InputStorageType, class OutputStorageType>
150  int
152  OutputStorageType>::DetermineScaledRectificationParameters_()
153  {
154  int res = DetermineRectificationParameters_();
155  if (res == 0)
156  {
157  BIASASSERT(rectPPA_!=NULL);
158  BIASASSERT(rectPPB_!=NULL);
159  if (targetWidth_ > 0)
160  {
161  unsigned int width, height;
162  rectPPA_->GetImageSize(width, height);
163  float scale = float(width) / float(targetWidth_);
164  rectPPA_->Rescale(float(1.0 / scale));
165 
166  rectPPB_->GetImageSize(width, height);
167  scale = float(width) / float(targetWidth_);
168  rectPPB_->Rescale(float(1.0 / scale));
169  }
170  else
171  {
172  rectPPA_->Rescale(float(1.0 / scale_));
173  rectPPB_->Rescale(float(1.0 / scale_));
174  }
175  }
176 
177  return res;
178  }
179 
180 template<class InputStorageType, class OutputStorageType>
181  void
183  OutputStorageType>::InitializeSinkImages_()
184  {
185  //init sink image sizes and luts:
186  unsigned int width, height;
187 
188  rectPPA_->GetImageSize(width, height);
189  if (!PARENT::rectImageA_.IsEmpty())
190  PARENT::rectImageA_.Release();
191  PARENT::rectImageA_.Init(width, height, PARENT::imageA_.GetChannelCount());
192  PARENT::rectImageA_.Clear();
193 
194  rectPPB_->GetImageSize(width, height);
195  if (!PARENT::rectImageB_.IsEmpty())
196  PARENT::rectImageB_.Release();
197  PARENT::rectImageB_.Init(width, height, PARENT::imageB_.GetChannelCount());
198 
199  }
200 
201 template<class InputStorageType, class OutputStorageType>
202  void
204  OutputStorageType>::InitializeProjectionMappingObjects_()
205  {
206  rectMapperA_.SetSourceCam(Projection(*PARENT::ppBA_));
207  rectMapperA_.SetSinkCam(Projection(*rectPPA_));
208 
209  rectMapperB_.SetSourceCam(Projection(*PARENT::ppBB_));
210  rectMapperB_.SetSinkCam(Projection(*rectPPB_));
211  }
212 
213 template<class InputStorageType, class OutputStorageType>
214  void
216  OutputStorageType>::InitializeMapping_()
217  {
218  if (mappingInitialized_)
219  return;
220 
221  InitializeSinkImages_();
222  InitializeProjectionMappingObjects_();
223 
224  if (useLookUpTables_)
225  {
226  rectMapperA_.PrepareLookupTableMapping(PARENT::imageA_,
227  PARENT::rectImageA_, interpolationType_);
228 
229  rectMapperB_.PrepareLookupTableMapping(PARENT::imageB_,
230  PARENT::rectImageB_, interpolationType_);
231  }
232  mappingInitialized_ = true;
233  }
234 
235 template<class InputStorageType, class OutputStorageType>
236  int
238  OutputStorageType>::GetClonesOfRectificationParameters(
240  {
241  rectPPA = NULL;
242  rectPPB = NULL;
243 
244  if (!AreRectificationParametersValid_())
245  {
246  return -1;
247  }
248 
249  if (rectPPA_ == NULL || rectPPB_ == NULL)
250  {
251  return -1;
252  }
253 
254  rectPPA = rectPPA_->Clone();
255  rectPPB = rectPPB_->Clone();
256  return 0;
257  }
258 
259 template<class InputStorageType, class OutputStorageType>
260  int
262  OutputStorageType>::GetRectifyingDisplacementMaps(
263  Image<float>& displacementA, Image<float>& displacementB)
264  {
265  if (!AreRectificationParametersValid_())
266  {
267  return -1;
268  }
269  InitializeProjectionMappingObjects_();
270 
271  unsigned int width, height;
272  rectPPA_->GetImageSize(width, height);
273  if (!displacementA.IsEmpty())
274  displacementA.Release();
275  displacementA.Init(width, height, 3);
276  if (rectMapperA_.GetDisplacementMap(displacementA, PARENT::imageA_) != 0)
277  {
278  return -1;
279  }
280 
281  rectPPB_->GetImageSize(width, height);
282  if (!displacementB.IsEmpty())
283  displacementB.Release();
284  displacementB.Init(width, height, 3);
285  if (rectMapperB_.GetDisplacementMap(displacementB, PARENT::imageB_) != 0)
286  {
287  return -1;
288  }
289 
290  return 0;
291  }
292 
293 template<class InputStorageType, class OutputStorageType>
294  int
296  OutputStorageType>::GetRectificationSetup(Camera<float>& rectSetup)
297  {
298 
299  if (!AreRectificationParametersValid_())
300  {
301  return -1;
302  }
303 
304  InitializeMapping_();
305 
306  unsigned int width, channels;
307  unsigned int widthB, channelsB;
308  if (rectMapperA_.GetLookupTableSize(width, channels, interpolationType_)
309  < 0)
310  return -1;
311  if (rectMapperB_.GetLookupTableSize(widthB, channelsB, interpolationType_)
312  < 0)
313  return -1;
314 
315  BIASASSERT(width == widthB);
316  BIASASSERT(channels == channelsB);
317  rectSetup.Init(width, 2, channels);
318 
319  //build projection here and set to metadata!
320  //all data is relative -> this does not allow for classical
321  // interpretation of the external cameras
322  Projection Proj;
323  Proj.AddRelativeCamera(PARENT::ppBA_);
324  Proj.AddRelativeCamera(PARENT::ppBB_);
325  Proj.AddRelativeCamera(rectPPA_);
326  Proj.AddRelativeCamera(rectPPB_);
327  rectSetup.SetProj(Proj);
328 
329  //add the id here!
330  rectSetup.SetASCIIString(stringID_);
331 
332  rectSetup.UpdateMetaData();
333 
334  //set image content:
335  float** rows = rectSetup.GetImageDataArray();
336  if (rectMapperA_.GetLookupTable(rows[0], interpolationType_) < 0)
337  return -1;
338  if (rectMapperB_.GetLookupTable(rows[1], interpolationType_) < 0)
339  return -1;
340 
341  return 0;
342  }
343 
344 template<class InputStorageType, class OutputStorageType>
345  int
347  OutputStorageType>::SetRectificationSetup(Camera<float>& rectSetup)
348  {
349  rectSetup.ParseMetaData();
350 
351  if (rectSetup.GetASCIIString() != stringID_)
352  {
353  BIASERR("loading rectification setup with wrong class");
354  return -1;
355  }
356 
357  Projection Proj = rectSetup.GetProj();
358  PARENT::ppBA_ = Proj.GetParameters(0)->Clone();
359  PARENT::ppBB_ = Proj.GetParameters(1)->Clone();
360  rectPPA_ = Proj.GetParameters(2)->Clone();
361  rectPPB_ = Proj.GetParameters(3)->Clone();
362 
363  float** rows = rectSetup.GetImageDataArray();
364  InterpolationMethod method;
365  rectMapperA_.SetLookupTable(rows[0], rectSetup.GetWidth(), method);
366  rectMapperB_.SetLookupTable(rows[1], rectSetup.GetWidth(),
367  interpolationType_);
368  BIASASSERT(method == interpolationType_);
369 
370  InitializeSinkImages_();
371 
372  rectificationParamsAreValid_ = true;
373  mappingInitialized_ = true;
374  useLookUpTables_ = true;
375 
376  return 0;
377  }
378 
379 template<class InputStorageType, class OutputStorageType>
380  void
382  OutputStorageType>::SetOverrideAngles(double thetaMinOverride,
383  double thetaMaxOverride, double phiMinOverride, double phiMaxOverride)
384  {
385  BIASASSERT(thetaMinOverride>=0 && thetaMinOverride<thetaMaxOverride);
386  BIASASSERT(thetaMaxOverride>0 && thetaMaxOverride<=M_PI);
387  BIASASSERT(phiMinOverride>=-M_PI && phiMinOverride<phiMaxOverride);
388  BIASASSERT(phiMaxOverride>0 && phiMaxOverride<=M_PI);
389 
390  thetaMinOverride_ = thetaMinOverride;
391  thetaMaxOverride_ = thetaMaxOverride;
392  phiMinOverride_ = phiMinOverride;
393  phiMaxOverride_ = phiMaxOverride;
394  rectificationParamsAreValid_ = false;
395  }
396 
397 template<class InputStorageType, class OutputStorageType>
398  int
400  OutputStorageType>::Rectify()
401  {
402  if (!AreRectificationParametersValid_())
403  {
404  return -1;
405  }
406 
407  InitializeMapping_();
408 
409  //clear images:
410  PARENT::rectImageA_.SetZero();
411  OutputStorageType* fill =
412  new OutputStorageType[PARENT::imageB_.GetChannelCount()];
413  for (unsigned int i = 0; i < PARENT::imageB_.GetChannelCount(); i++)
414  {
415  fill[i] = secondFill_;
416  }
417  PARENT::rectImageB_.FillImageWithConstValue(*fill);
418  delete[] fill;
419 
420  if (useLookUpTables_)
421  {
422  if (rectMapperA_.MapWithLookupTable(PARENT::imageA_,
423  PARENT::rectImageA_, interpolationType_) < 0)
424  {
425  BIASERR("LUT rectification of image A failed");
426  return -1;
427  }
428 
429  if (rectMapperB_.MapWithLookupTable(PARENT::imageB_,
430  PARENT::rectImageB_, interpolationType_) < 0)
431  {
432  BIASERR("LUT rectification of image B failed");
433  return -1;
434  }
435  }
436  else
437  {
438  if (rectMapperA_.Map(PARENT::imageA_, PARENT::rectImageA_,
439  interpolationType_) < 0)
440  {
441  BIASERR("rectification of image A failed");
442  return -1;
443  }
444 
445  if (rectMapperB_.Map(PARENT::imageB_, PARENT::rectImageB_,
446  interpolationType_) < 0)
447  {
448  BIASERR("rectification of image B failed");
449  return -1;
450  }
451  }
452 
453  return 0;
454  }
455 
456 template<class InputStorageType, class OutputStorageType>
457  int
459  OutputStorageType>::Disp2Depth(const Image<float>& DisparityMap, Image<
460  float>& DepthMap, const ProjectionParametersBase* ppBA,
461  const ProjectionParametersBase* ppBB, const ProjectionParametersBase* rectPPA,
462  const ProjectionParametersBase* rectPPB, unsigned int border)
463  {
464  unsigned int width, height;
465  ppBA->GetImageSize(width, height);
466 
467  if (!DepthMap.IsEmpty())
468  DepthMap.Release();
469  DepthMap.Init(width, height);
470  DepthMap.SetZero();
471 
472 #ifdef validitydebug
473  Image<unsigned char> ValidityMap;
474  ValidityMap.Init(width, height);
475  ValidityMap.SetZero();
476  unsigned char** ValidityMapPel =
477  ValidityMap.GetImageDataArray();
478 #endif
479 
480  float** DepthMapPel = DepthMap.GetImageDataArray();
481  // float** DispMapPel = DisparityMap.GetImageDataArray();
482  // unsigned int dispMapWidth = DisparityMap.GetWidth();
483  // unsigned int dispMapHeight = DisparityMap.GetHeight();
484 
485  float disparityThreshold = 0.0001f
486  + (float) DisparityMap.GetMinPixelValue();
487 
488  //allows acces from Orig A to Rect A via GetSourceCoords
490  //allows acces from Rect B to Orig B via GetSourceCoords
492 
493  relativeOrigAToRectA.SetSinkCam(Projection(*ppBA));
494  relativeOrigAToRectA.SetSourceCam(Projection(*rectPPA));
495  relativeRectBToOrigB.SetSinkCam(Projection(*rectPPB));
496  relativeRectBToOrigB.SetSourceCam(Projection(*ppBB));
497 
498 #ifdef SUBPIXEL_REFINEMENT
499 
500  // want to track in float to avoid messing around with templates
501  // compute blurred texture and gradient images in float:
503  Blurrer.SetSigma(0.1);
504  Image<float> rectAf, gradax, graday;
505  Blurrer.Filter(this->rectImageA_, rectAf);
506  Image<float> rectBf, gradbx, gradby;
507  Blurrer.Filter(this->rectImageB_, rectBf);
508 #ifdef BIAS_DEBUG_KK
509  //ImageIO::Save("rectAf.mip", rectAf);
510  //ImageIO::Save("rectBf.mip", rectBf);
511  ImageIO::Save("rectAf.mip", rectAf);
512  ImageIO::Save("rectBf.mip", rectBf);
513 #endif
514  // assume that images are already blurred
515  GradientSimple<float, float> MyGradient;
516  MyGradient.Filter(rectAf, gradax, graday);
517  MyGradient.Filter(rectBf, gradbx, gradby);
518 #ifdef BIAS_DEBUG_KK
519  //ImageIO::Save("gradax.mip", gradax);
520  //ImageIO::Save("gradbx.mip", gradbx);
521  ImageIO::Save("gradax.mip", gradax);
522  ImageIO::Save("gradbx.mip", gradbx);
523 #endif
524 
525  // generate tracker which searches only for dx
526  TrackerBaseWeighted1D<float> SubPixelRefiner;
527  //SubPixelRefiner.SetDebugLevel(D_TRACKERB_KLT);
528  SubPixelRefiner.SetHalfWinSize(7);
529  SubPixelRefiner.SetMaxIterations(25);
530  SubPixelRefiner.SetMaxError(0.05);
531  SubPixelRefiner.SetMaxResiduumMAD(1e10);
532  SubPixelRefiner.SetRejectionType(RT_MAD);
533  SubPixelRefiner.SetAffineBrightnessInvariance(true);
534  SubPixelRefiner.Init(rectAf, rectBf, gradax, graday, gradbx, gradby);
535 
536  // some variables which we need but which we wont evaluate ...
537  KLT_TYPE kltsteperror = 0;
538  int kltiterations = 0;
539  KLT_TYPE residuumMAD = 0;
540  KLT_TYPE residuumMSD = 0;
541  Matrix<KLT_TYPE> cov(2,2,MatrixZero);
542 #endif
543 
544  HomgPoint2D depthMapPoint, dispMapPoint;
545  HomgPoint2D correspondenceInRectB, correspondenceInOrigB;
546  HomgPoint3D point3D;
547 
548  Triangulation triangulator;
549  double disparity = 0;
550 
551  depthMapPoint[2] = 1.0;
552  dispMapPoint[2] = 1.0;
553  for (unsigned int y = border; y < height - border; y++)
554  {
555  for (unsigned int x = border; x < width - border; x++)
556  {
557 
558  depthMapPoint[0] = x;
559  depthMapPoint[1] = y;
560 
561  bool valid = true;
562  if (relativeOrigAToRectA.GetSourceCoordinates(depthMapPoint,
563  dispMapPoint) == 0)
564  {
565  //have rect A coords get me the disp map value
566  disparity = DisparityMap.BilinearInterpolationGreyMinVal(
567  dispMapPoint[0], dispMapPoint[1], disparityThreshold);
568  if (disparity > disparityThreshold)
569  { //valid disparity
570  correspondenceInRectB.Set(dispMapPoint[0] - disparity,
571  dispMapPoint[1], 1.0);
572  // dont let the refiner compute an offset larger than this
573 #define MAX_OFFSET_REFINEMENT 0.6
574 #ifdef SUBPIXEL_REFINEMENT
575  HomgPoint2D refinedPoint = correspondenceInRectB;
576 
577  // track only those points which are triangulated
578 
579 
580  // Instead of using a constant gaussian weighted window for every
581  // correspondence, it would be much more intelligent to use
582  // something like 1/(0.5+fabs(disparity difference)) as a weight for
583  // each pixel in the neighborhood. This automatically decreases
584  // the window at non-fronto-parallel structures or depth
585  // discontinuities.
586  // simply add a SetWeight method to Tracker1D
587 
588 
589  int refinementresult =
590  SubPixelRefiner.Track(dispMapPoint, correspondenceInRectB,
591  refinedPoint,
592  kltsteperror, kltiterations,residuumMAD,
593  residuumMSD, cov);
594 
595  // did the refinement succeed at all ?
596  if (refinementresult==0)
597  {
598  // fine, check if the step is consistent with our guess or
599  // whether it is too large (violates smoothness in neighborhood)
600  double diff = refinedPoint[0]-correspondenceInRectB[0];
601  // make sure y does not change
602  BIASASSERT(Equal(refinedPoint[1], correspondenceInRectB[1]));
603  if (fabs(diff)<MAX_OFFSET_REFINEMENT)
604  {
605  // fine! set this as the new correspondence for the point
606  correspondenceInRectB = refinedPoint;
607  //cout<<"+("<<diff<<") ";
608  }
609  else
610  {
611  // step to big, presumably other local minimum
612  //cout<<"-("<<diff<<") ";
613  }
614  }
615  else
616  {
617  // klt complained, presumably no structure or too many iterations
618  //cout<<"!"<<refinementresult<<"!";
619  }
620 #endif
621 
622  if (relativeRectBToOrigB. GetSourceCoordinates(
623  correspondenceInRectB, correspondenceInOrigB) == 0)
624  {
625 
626  //have got correspondance in orig B!
627  if (triangulator.Triangulate(ppBA, ppBB, depthMapPoint,
628  correspondenceInOrigB, point3D) == 0)
629  {
630  //ok triangulation was good calc depth
631  Vector3<double> euc;
632  point3D.GetEuclidean(euc);
633  Vector3<double> diff = euc - ppBA->GetC();
634 
635  BIASASSERT(diff.NormL2()>1e-5);
636  DepthMapPel[y][x] = (float) diff.NormL2();
637  valid = true;
638  }
639  } //no correspondance in orig B :(
640  else
641  valid = false;
642  }//disprity is too small:(
643  else
644  valid = false;
645 
646  } //end of check if rect coord available
647  else
648  valid = false;
649 
650  if (!valid)
651  {//ok did we get valid depth ?
652  DepthMapPel[y][x] = UNDEFINED_DEPTH;
653 #ifdef validitydebug
654  ValidityMapPel[y][x] = 0;
655 #endif
656  }
657 #ifdef validitydebug
658  else
659  ValidityMapPel[y][x] = 255;
660 #endif
661 
662  }//end of for x
663 #ifdef SUBPIXEL_REFINEMENT
664  // a new line is completed
665  cout<<"S"<<flush;
666 #endif
667  }//end of for y
668 #ifdef validitydebug
669  //ImageIO::Save("D2DValidityMap.mip", ValidityMap);
670  ImageIO::Save("D2DValidityMap.mip", ValidityMap);
671 #endif
672 
673  return 0;
674  }
675 
676 template<class InputStorageType, class OutputStorageType>
677  int
679  OutputStorageType>::Disp2Depth(const Image<float>& DisparityMap, Image<
680  float>& DepthMap, unsigned int border)
681  {
682  if (!AreRectificationParametersValid_())
683  {
684  return -1;
685  }
686 
688  DisparityMap, DepthMap, PARENT::ppBA_, PARENT::ppBB_, rectPPA_,
689  rectPPB_, border);
690 
691  return 0;
692 
693  // if (!AreRectificationParametersValid_())
694  // {
695  // return -1;
696  // }
697  //
698  // unsigned int width, height;
699  // PARENT::ppBA_->GetImageSize(width, height);
700  //
701  // if (!DepthMap.IsEmpty())
702  // DepthMap.Release();
703  // DepthMap.Init(width, height);
704  // DepthMap.SetZero();
705  //
706  //#ifdef validitydebug
707  // Image<unsigned char> ValidityMap;
708  // ValidityMap.Init(width, height);
709  // ValidityMap.SetZero();
710  // unsigned char** ValidityMapPel =
711  // ValidityMap.GetImageDataArray();
712  //#endif
713  //
714  // float** DepthMapPel = DepthMap.GetImageDataArray();
715  // // float** DispMapPel = DisparityMap.GetImageDataArray();
716  // // unsigned int dispMapWidth = DisparityMap.GetWidth();
717  // // unsigned int dispMapHeight = DisparityMap.GetHeight();
718  //
719  // float disparityThreshold = 0.0001f
720  // + (float) DisparityMap.GetMinPixelValue();
721  //
722  // //allows acces from Orig A to Rect A via GetSourceCoords
723  // ProjectionMapping<InputStorageType, OutputStorageType> relativeOrigAToRectA;
724  // //allows acces from Rect B to Orig B via GetSourceCoords
725  // ProjectionMapping<InputStorageType, OutputStorageType> relativeRectBToOrigB;
726  //
727  // relativeOrigAToRectA.SetSinkCam(Projection(*PARENT::ppBA_));
728  // relativeOrigAToRectA.SetSourceCam(Projection(*rectPPA_));
729  // relativeRectBToOrigB.SetSinkCam(Projection(*rectPPB_));
730  // relativeRectBToOrigB.SetSourceCam(Projection(*PARENT::ppBB_));
731  //
732  //#ifdef SUBPIXEL_REFINEMENT
733  //
734  // // want to track in float to avoid messing around with templates
735  // // compute blurred texture and gradient images in float:
736  // Gauss<OutputStorageType, float> Blurrer;
737  // Blurrer.SetSigma(0.1);
738  // Image<float> rectAf, gradax, graday;
739  // Blurrer.Filter(this->rectImageA_, rectAf);
740  // Image<float> rectBf, gradbx, gradby;
741  // Blurrer.Filter(this->rectImageB_, rectBf);
742  //#ifdef BIAS_DEBUG_KK
743  // ImageIO::Save("rectAf.mip", rectAf);
744  // ImageIO::Save("rectBf.mip", rectBf);
745  //#endif
746  // // assume that images are already blurred
747  // GradientSimple<float, float> MyGradient;
748  // MyGradient.Filter(rectAf, gradax, graday);
749  // MyGradient.Filter(rectBf, gradbx, gradby);
750  //#ifdef BIAS_DEBUG_KK
751  // ImageIO::Save("gradax.mip", gradax);
752  // ImageIO::Save("gradbx.mip", gradbx);
753  //#endif
754  //
755  // // generate tracker which searches only for dx
756  // TrackerBaseWeighted1D<float> SubPixelRefiner;
757  // //SubPixelRefiner.SetDebugLevel(D_TRACKERB_KLT);
758  // SubPixelRefiner.SetHalfWinSize(7);
759  // SubPixelRefiner.SetMaxIterations(25);
760  // SubPixelRefiner.SetMaxError(0.05);
761  // SubPixelRefiner.SetMaxResiduumMAD(1e10);
762  // SubPixelRefiner.SetRejectionType(RT_MAD);
763  // SubPixelRefiner.SetAffineBrightnessInvariance(true);
764  // SubPixelRefiner.Init(rectAf, rectBf, gradax, graday, gradbx, gradby);
765  //
766  // // some variables which we need but which we wont evaluate ...
767  // KLT_TYPE kltsteperror = 0;
768  // int kltiterations = 0;
769  // KLT_TYPE residuumMAD = 0;
770  // KLT_TYPE residuumMSD = 0;
771  // Matrix<KLT_TYPE> cov(2,2,MatrixZero);
772  //#endif
773  //
774  // HomgPoint2D depthMapPoint, dispMapPoint;
775  // HomgPoint2D correspondenceInRectB, correspondenceInOrigB;
776  // HomgPoint3D point3D;
777  //
778  // Triangulation triangulator;
779  // double disparity = 0;
780  //
781  // depthMapPoint[2] = 1.0;
782  // dispMapPoint[2] = 1.0;
783  // for (unsigned int y = border; y < height - border; y++)
784  // {
785  // for (unsigned int x = border; x < width - border; x++)
786  // {
787  //
788  // depthMapPoint[0] = x;
789  // depthMapPoint[1] = y;
790  //
791  // bool valid = true;
792  // if (relativeOrigAToRectA.GetSourceCoordinates(depthMapPoint,
793  // dispMapPoint) == 0)
794  // {
795  // //have rect A coords get me the disp map value
796  // disparity = DisparityMap.BilinearInterpolationGreyMinVal(
797  // dispMapPoint[0], dispMapPoint[1], disparityThreshold);
798  // if (disparity > disparityThreshold)
799  // { //valid disparity
800  // correspondenceInRectB.Set(dispMapPoint[0] - disparity,
801  // dispMapPoint[1], 1.0);
802  // // dont let the refiner compute an offset larger than this
803  //#define MAX_OFFSET_REFINEMENT 0.6
804  //#ifdef SUBPIXEL_REFINEMENT
805  // HomgPoint2D refinedPoint = correspondenceInRectB;
806  //
807  // // track only those points which are triangulated
808  //
809  //
810  // // Instead of using a constant gaussian weighted window for every
811  // // correspondence, it would be much more intelligent to use
812  // // something like 1/(0.5+fabs(disparity difference)) as a weight for
813  // // each pixel in the neighborhood. This automatically decreases
814  // // the window at non-fronto-parallel structures or depth
815  // // discontinuities.
816  // // simply add a SetWeight method to Tracker1D
817  //
818  //
819  // int refinementresult =
820  // SubPixelRefiner.Track(dispMapPoint, correspondenceInRectB,
821  // refinedPoint,
822  // kltsteperror, kltiterations,residuumMAD,
823  // residuumMSD, cov);
824  //
825  // // did the refinement succeed at all ?
826  // if (refinementresult==0)
827  // {
828  // // fine, check if the step is consistent with our guess or
829  // // whether it is too large (violates smoothness in neighborhood)
830  // double diff = refinedPoint[0]-correspondenceInRectB[0];
831  // // make sure y does not change
832  // BIASASSERT(Equal(refinedPoint[1], correspondenceInRectB[1]));
833  // if (fabs(diff)<MAX_OFFSET_REFINEMENT)
834  // {
835  // // fine! set this as the new correspondence for the point
836  // correspondenceInRectB = refinedPoint;
837  // //cout<<"+("<<diff<<") ";
838  // }
839  // else
840  // {
841  // // step to big, presumably other local minimum
842  // //cout<<"-("<<diff<<") ";
843  // }
844  // }
845  // else
846  // {
847  // // klt complained, presumably no structure or too many iterations
848  // //cout<<"!"<<refinementresult<<"!";
849  // }
850  //#endif
851  //
852  // if (relativeRectBToOrigB. GetSourceCoordinates(
853  // correspondenceInRectB, correspondenceInOrigB) == 0)
854  // {
855  //
856  // //have got correspondance in orig B!
857  // if (triangulator.Triangulate(PARENT::ppBA_,
858  // PARENT::ppBB_, depthMapPoint,
859  // correspondenceInOrigB, point3D) == 0)
860  // {
861  // //ok triangulation was good calc depth
862  // Vector3<double> euc;
863  // point3D.GetEuclidean(euc);
864  // Vector3<double> diff = euc - PARENT::ppBA_->GetC();
865  //
866  // BIASASSERT(diff.NormL2()>1e-5);
867  // DepthMapPel[y][x] = (float) diff.NormL2();
868  // valid = true;
869  // }
870  // } //no correspondance in orig B :(
871  // else
872  // valid = false;
873  // }//disprity is too small:(
874  // else
875  // valid = false;
876  //
877  // } //end of check if rect coord available
878  // else
879  // valid = false;
880  //
881  // if (!valid)
882  // {//ok did we get valid depth ?
883  // DepthMapPel[y][x] = UNDEFINED_DEPTH;
884  //#ifdef validitydebug
885  // ValidityMapPel[y][x] = 0;
886  //#endif
887  // }
888  //#ifdef validitydebug
889  // else
890  // ValidityMapPel[y][x] = 255;
891  //#endif
892  //
893  // }//end of for x
894  //#ifdef SUBPIXEL_REFINEMENT
895  // // a new line is completed
896  // cout<<"S"<<flush;
897  //#endif
898  // }//end of for y
899  //#ifdef validitydebug
900  // ImageIO::Save("D2DValidityMap.mip", ValidityMap);
901  //#endif
902  //
903  }
904 
905 template<class InputStorageType, class OutputStorageType>
906  void
908  OutputStorageType>::SetTargetWidth(unsigned int targetWidth)
909  {
910  targetWidth_ = targetWidth;
911  }
912 
913 template<class InputStorageType, class OutputStorageType>
914  void
916  OutputStorageType>::UseLookUpTables(bool useLUT)
917  {
918  //toggling of LUT mapping should only trigger a new initialization
919  //of the mapping structures if LUT was not active.
920  //For simple mapping the necessary init does depend on other
921  //interfaces only.
922  if (useLUT && !useLookUpTables_)
923  mappingInitialized_ = false;
924  useLookUpTables_ = useLUT;
925  }
926 
927 namespace BIAS{
928 template class RectificationViaProjectionMappingBase<unsigned char,
929  unsigned char> ;
933 
934 #if defined(BUILD_IMAGE_CHAR)
937 #endif
938 
939 #if defined(BUILD_IMAGE_USHORT)
940 template class RectificationViaProjectionMappingBase<unsigned short,
941  unsigned short> ;
942 #endif
943 
944 #if defined(BUILD_IMAGE_SHORT)
946 #endif
947 
948 #if defined(BUILD_IMAGE_SHORT)&&defined(BUILD_IMAGE_USHORT)
950 #endif
951 
952 #if defined(BUILD_IMAGE_INT)
954 #endif
955 
956 #if defined(BUILD_IMAGE_USHORT)
958 #endif
959 
960 #if defined(BUILD_IMAGE_USHORT) && defined(BUILD_IMAGE_INT)
962 #endif
963 
964 #if defined(BUILD_IMAGE_DOUBLE)
966 #endif
967 }
virtual BIAS::Vector3< double > GetC() const
Get projection center.
void Release()
reimplemented from ImageBase
Definition: Image.cpp:1579
void AddRelativeCamera(ProjectionParametersBase *ppb)
Add a camera to the projection,the coordinates of the pose are given in relative Coordinates, first cam is origin.
Definition: Projection.cpp:194
virtual int Disp2Depth(const Image< float > &DisparityMap, Image< float > &DepthMap, unsigned int border)
Uses the passed disparity map for camera A to calculate the corresponding depth map.
void GetEuclidean(Vector3< HOMGPOINT3D_TYPE > &dest) const
calculate affine coordinates of this and write them to dest affine coordinates are projective coordin...
Definition: HomgPoint3D.hh:336
InterpolationMethod
accuracy for resampling
class HomgPoint2D describes a point with 2 degrees of freedom in projective coordinates.
Definition: HomgPoint2D.hh:67
Base class for rectification implementations that make use of projections to represent rectified stat...
void SetASCIIString(const std::string &ASCIIString)
Definition: Camera.hh:112
void Init(Image< StorageType > &im1, Image< StorageType > &im2, Image< StorageType > &gradx1, Image< StorageType > &grady1, Image< StorageType > &gradx2, Image< StorageType > &grady2)
Prepare for tracking with prefiltered images.
bool IsEmpty() const
check if ImageData_ points to allocated image buffer or not
Definition: ImageBase.hh:245
void SetSinkCam(const Projection &P, const Image< float > *sinkdepth=NULL)
Set your sink projection before calling Map(),.
void SetSourceCam(const Projection &P)
Set your source projection before calling Map()
virtual ProjectionParametersBase * Clone() const =0
Covariant virtual copy constructor used in BIAS::Projection.
Maps source pixel to sink pixel of given projections.
void SetMaxResiduumMAD(const KLT_TYPE maxres)
!!! Also used for X84M as maximal residuum.
void SetMaxError(const KLT_TYPE maxerr)
unsigned int GetWidth() const
Definition: ImageBase.hh:312
void SetHalfWinSize(const int hws)
void SetMaxIterations(const int maxiter)
simple gradient calculation gx(x,y) = I(x+1,y) - I(x-1,y) gy(x,y) = I(x,y+1) - I(x,y-1)
Class for triangulation of 3Dpoints from 2D matches. Covariance matrix (refering to an uncertainty el...
smoothing with gaussian kernel
Definition: Gauss.hh:51
const ProjectionParametersBase * GetParameters(unsigned int cam=0) const
const parameter access function
Definition: Projection.hh:194
This class hides the underlying projection model, like projection matrix, spherical camera...
Definition: Projection.hh:70
int Track(HomgPoint2D &p1, HomgPoint2D &p2, HomgPoint2D &p2tracked, KLT_TYPE &error, int &iter, KLT_TYPE &residuumMAD, KLT_TYPE &residuumMSD, Matrix< KLT_TYPE > &cov, const Matrix2x2< KLT_TYPE > &AffinePred=Matrix2x2< KLT_TYPE >(MatrixIdentity), Matrix2x2< KLT_TYPE > *AffineResult=NULL)
Calculates correspondence from image1 to image2.
int SetProj(const Projection &Proj)
Definition: Camera.hh:106
int Triangulate(PMatrix &P1, PMatrix &P2, const HomgPoint2D &p1, const HomgPoint2D &p2, BIAS::Vector3< double > &point3d)
Triangulation for metric PMatrices (using C and Hinf)
void SetSigma(const double si)
Definition: Gauss.hh:162
std::string GetASCIIString()
Definition: Camera.hh:117
static int Save(const std::string &filename, const ImageBase &img, const enum TFileFormat FileFormat=FF_auto, const bool sync=BIAS_DEFAULT_SYNC, const int c_jpeg_quality=BIAS_DEFAULT_IMAGE_QUALITY, const bool forceNewID=BIAS_DEFAULT_FORCENEWID, const bool &writeMetaData=true)
Export image as file using extrnal libs.
Definition: ImageIO.cpp:725
class HomgPoint3D describes a point with 3 degrees of freedom in projective coordinates.
Definition: HomgPoint3D.hh:61
virtual int Filter(const Image< InputStorageType > &src, Image< OutputStorageType > &dst)
sets gauss kernel if params changed and calls convolution or fast grey implementation if possible ...
Definition: Gauss.cpp:89
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
int GetSourceCoordinates(const HomgPoint2D &sink, HomgPoint2D &source) const
wrapper function to allow the lookup implementation to be shared with other algorithms.
bool Equal(const T left, const T right, const T eps)
comparison function for floating point values See http://www.boost.org/libs/test/doc/components/test_...
int UpdateMetaData()
copy P_ and co.
Definition: Camera.cpp:446
virtual void SetAffineBrightnessInvariance(bool bi)
enable brightness variance and offset invariant computation
void SetRejectionType(const int rejection_type)
double BilinearInterpolationGreyMinVal(const double x, const double y, const StorageType &minVal) const
Bilinear interpolation for grey-value images with pixel value check.
Definition: Image.hh:335
StorageType GetMinPixelValue(unsigned short int channel=0, unsigned int *coo=NULL) const
Get the minimal pixel value if coo!=NULL the coo[0]=x of min and coo[1]=y of min. ...
Definition: Image.cpp:977
Camera parameters which define the mapping between rays in the camera coordinate system and pixels in...
void Set(const HOMGPOINT2D_TYPE &x, const HOMGPOINT2D_TYPE &y)
set elementwise with given 2 euclidean scalar values.
Definition: HomgPoint2D.hh:174
const BIAS::Projection & GetProj() const
Definition: Camera.hh:109
int ParseMetaData(bool bUse2x64bitTS=true)
After ImageIO::Load() operated on AppData_, this method fills P_, Timestamp, DC_*, ...
Definition: Camera.cpp:154
void SetZero()
zeroes the image
Definition: ImageBase.hh:83
double NormL2() const
the L2 norm sqrt(a^2 + b^2 + c^2)
Definition: Vector3.hh:633
virtual int Filter(const Image< InputStorageType > &src, Image< OutputStorageType > &grad)
returns a 2 channel image containing gx and gy
const StorageType ** GetImageDataArray() const
overloaded GetImageDataArray() from ImageBase
Definition: Image.hh:153