Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
CylindricalRectification.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/CylindricalRectification.hh>
26 #include <Geometry/ProjectionParametersSpherical.hh>
27 #include <Geometry/ProjectionParametersPerspective.hh>
28 #include <Geometry/ProjectionParametersCylindric.hh>
29 #include <Base/Geometry/HomgPoint3D.hh>
30 #include <Base/Common/CompareFloatingPoint.hh>
31 #include <Base/ImageUtils/BresenhamCircle.hh>
32 
33 using namespace BIAS;
34 using namespace std;
35 
36 #define SUPERPARENT RectificationBase<InputStorageType, OutputStorageType>
37 #define PARENT RectificationViaProjectionMappingBase<InputStorageType, OutputStorageType>
38 
39 
40 template <class InputStorageType, class OutputStorageType>
42 CylindricalRectification(double maxAngle) :
43 PARENT::RectificationViaProjectionMappingBase("CylindricalRectification"),
44 maxHalfAngleInX_(maxAngle)
45 { }
46 
47 template <class InputStorageType, class OutputStorageType>
50 { }
51 
52 template <class InputStorageType, class OutputStorageType>
56 {
58  dynamic_cast<const ProjectionParametersPerspective*>(proj);
60  dynamic_cast<const ProjectionParametersSpherical*>(proj);
62  dynamic_cast<const ProjectionParametersCylindric*>(proj);
63 
64  if (ppp == NULL && pps == NULL && ppc == NULL) {
65  return false;
66  }
67 
68  return true;
69 }
70 
71 
72 template <class InputStorageType, class OutputStorageType>
75 {
76 
77  Pose rectPoseA, rectPoseB;//, relativeTransformA, relativeTransformB;
78 
79  if (SUPERPARENT::CalculateRectifiedBases(SUPERPARENT::ppBA_->GetPose(),
80  SUPERPARENT::ppBB_->GetPose(),
81  rectPoseA, rectPoseB) != 0) {
82  BIASERR("Failed calculating rectified base");
83  return -1;
84  }
85  // relativeTransformA.BecomeRelativeTransform(cameraA->GetPose(), rectPoseA);
86  // relativeTransformB.BecomeRelativeTransform(cameraB->GetPose(), rectPoseB);
87 
88 /**
89  Determine the camera type and the needed resolutions!
90  If perspective determine the min max angles of both cameras in phi and
91  theta by projection onto the cylinder. Choose minimal phi range and maximal
92  x range. Prohibit theta larger then maxTheta.
93 */
94 
95  double minX, maxX;
96  double minPhi, maxPhi;
97  double xMinA, xMinB;
98  double xMaxA, xMaxB;
99  double phiMinA, phiMinB;
100  double phiMaxA, phiMaxB;
101  //samples per unit length
102  double relativeXResA, relativeXResB;
103  //samples per radians
104  double relativePhiResA, relativePhiResB;
105 
106  if (DetermineCylindricCameraBoundries_(SUPERPARENT::ppBA_,
107  rectPoseA,
108  xMinA, xMaxA, phiMinA, phiMaxA,
109  relativeXResA, relativePhiResA) != 0) {
110  BIASERR("Error calculating rectification boundaries.\n");
111  return -1;
112  }
113 
114  if (DetermineCylindricCameraBoundries_(SUPERPARENT::ppBB_,
115  rectPoseB,
116  xMinB, xMaxB, phiMinB, phiMaxB,
117  relativeXResB, relativePhiResB) != 0) {
118  BIASERR("Error calculating rectification boundaries.\n");
119  return -1;
120  }
121 
122  //check for overlap
123  // exploit that ordering between minA and maxA respectively minB and maxB
124  // is guaranteed
125  if(xMinB > xMaxA || xMinA > xMaxB) {
126  BIASERR("it seems that cameras do not have a viewing overlap within epipolar planes!");
127  return -1;
128  }
129  if(phiMinB > phiMaxA || phiMinA > phiMaxB) {
130  BIASERR("it seems that cameras do not have shared epipolar lines!");
131  return -1;
132  }
133 
134  //final values
135  //the angle for phi and theta has to be used
136  if (xMinA > xMinB) minX = xMinB;
137  else minX = xMinA;
138  if (xMaxA > xMaxB) maxX = xMaxA;
139  else maxX = xMaxB;
140 
141  // do not use extremal angles here because these angles
142  //represent the common epipolar line range
143  if(phiMinA > phiMinB) minPhi = phiMinA;
144  else minPhi = phiMinB;
145  if(phiMaxA < phiMaxB) maxPhi = phiMaxB;
146  else maxPhi = phiMaxA;
147 
148  double relativeXRes, relativePhiRes;
149  if(relativeXResA > relativeXResB) relativeXRes = relativeXResA;
150  else relativeXRes = relativeXResB;
151  if(relativePhiResA > relativePhiResB) relativePhiRes = relativePhiResA;
152  else relativePhiRes = relativePhiResB;
153 
154  unsigned int xRes = (unsigned int) ceil(relativeXRes*(maxX - minX));
155  unsigned int phiRes = (unsigned int) ceil(relativePhiRes*(maxPhi - minPhi));
156 
157  delete PARENT::rectPPA_;
158  delete PARENT::rectPPB_;
159  PARENT::rectPPA_ = new ProjectionParametersCylindric(minX, maxX,
160  minPhi, maxPhi,
161  xRes, phiRes);
162  PARENT::rectPPB_ = new ProjectionParametersCylindric(minX, maxX,
163  minPhi, maxPhi,
164  xRes, phiRes);
165  PARENT::rectPPA_->SetPose(rectPoseA);
166  PARENT::rectPPB_->SetPose(rectPoseB);
167 /*
168 #ifdef BIAS_DEBUG
169  std::cout<<"orig A:\n";
170  std::cout<<*SUPERPARENT::ppBA_;
171  std::cout<<"rect A:\n";
172  PARENT::rectPPA_->Print();
173  std::cout<<"orig B:\n";
174  std::cout<<*SUPERPARENT::ppBB_;
175  std::cout<<"rect B:\n";
176  PARENT::rectPPB_->Print();
177 #endif
178 */
179 
180  return 0;
181 }
182 
183 
184 /** Helper for DetermineCylindricCameraBoundries_.
185  * Finds the corresponding x and phi coordinates for optical ray and
186  * returns results by rescaling the passed point and updating passed phi.
187  * If point lies on cylinder axis -1 is returned.
188  *
189  */
190 template <class InputStorageType, class OutputStorageType>
193 {
194  double radius= sqrt(point[1]*point[1] + point[2]*point[2]);
195  if(Equal(radius, 0.0)) {
196  phi = 0.0;
197  return -1;
198  } else {
199  double scale = 1.0 / sqrt(point[1]*point[1] + point[2]*point[2]);
200  point *= scale;
201  phi = atan2(point[1], point[2]);
202  }
203  return 0;
204 }
205 
206 /** Helper for DetermineCylindricCameraBoundries_.
207  * Finds the corresponding x and phi coordinates for optical ray
208  * and updates min/max values accordingly.
209  */
210 template <class InputStorageType, class OutputStorageType>
213  double& minX, double& maxX,
214  double& minPhi, double& maxPhi)
215 {
216  double phi;
217  if(ProjectOntoUnitCylinder_(rectPoint, phi)==0) {
218  if(rectPoint[0]>maxX) maxX = rectPoint[0];
219  if(rectPoint[0]<minX) minX = rectPoint[0];
220  if(phi>maxPhi) maxPhi = phi;
221  if(phi<minPhi) minPhi = phi;
222  }
223 }
224 
225 template <class InputStorageType, class OutputStorageType>
228  const ProjectionParametersBase* camera,
229  const Pose& rectPose,
230  double& minX, double& maxX,
231  double& minPhi, double& maxPhi,
232  double& relativeXRes,
233  double& relativePhiRes) const
234 {
235  //determine bounding volume on cylinder
236  Pose relativeTransform;
237  //transforms points from camera coords (local) to cylinder coords (global)
238  relativeTransform.BecomeRelativeTransform(camera->GetPose(), rectPose);
239  unsigned int width, height;
240  camera->GetImageSize(width, height);
241 
242  maxX = DBL_MIN;
243  minX = DBL_MAX;
244  maxPhi = -M_PI;
245  minPhi = M_PI;
246 
247  Vector3<double> testedPoint;
248  HomgPoint3D rectPoint;
249  // double phi;
250  //check upper and lower image border
251  Vector3<double> p;
252  for(unsigned int x=0; x<width; x++) {
253  camera->UnProjectLocal(HomgPoint2D(x, 0, 1.0), p, testedPoint);
254  if(testedPoint.NormL2() < 1e-10) BIASABORT;
255  rectPoint = relativeTransform.LocalToGlobal(HomgPoint3D(testedPoint));
256  SetMinMaxFrom_(rectPoint, minX, maxX, minPhi, maxPhi);
257 
258  camera->UnProjectLocal(HomgPoint2D(x, height-1, 1.0), p, testedPoint);
259  if(testedPoint.NormL2() < 1e-10) BIASABORT;
260  rectPoint = relativeTransform.LocalToGlobal(HomgPoint3D(testedPoint));
261  SetMinMaxFrom_(rectPoint, minX, maxX, minPhi, maxPhi);
262  }
263 
264  for(unsigned int y=0; y<height; y++) {
265  camera->UnProjectLocal(HomgPoint2D(0, y, 1.0), p, testedPoint);
266  if(testedPoint.NormL2() < 1e-10) BIASABORT;
267  rectPoint = relativeTransform.LocalToGlobal(HomgPoint3D(testedPoint));
268  SetMinMaxFrom_(rectPoint, minX, maxX, minPhi, maxPhi);
269 
270  camera->UnProjectLocal(HomgPoint2D(width-1, y, 1.0), p, testedPoint);
271  if(testedPoint.NormL2() < 1e-10) BIASABORT;
272  rectPoint = relativeTransform.LocalToGlobal(HomgPoint3D(testedPoint));
273  SetMinMaxFrom_(rectPoint, minX, maxX, minPhi, maxPhi);
274  }
275 
276  double clippingMaxX = tan(maxHalfAngleInX_);
277 // #ifdef BIAS_DEBUG
278 // cerr<<"detemined image spaceing:\n";
279 // cerr<<"clipMinX/clipMaxX = "<<-clippingMaxX<<"/"<<clippingMaxX<<endl;
280 // cerr<<"minX/maxX = "<<minX<<"/"<<maxX<<endl;
281 // cerr<<"minPhi/maxPhi = "<<minPhi<<"/"<<maxPhi<<endl;
282 // #endif
283 
284 
285  if(minX < -clippingMaxX) minX = -clippingMaxX;
286  if(maxX > clippingMaxX) maxX = clippingMaxX;
287 
288  /* replaced by code below:
289  //epipole is in image all angles are present
290  HomgPoint3D epiDir = relativeTransform.GlobalToLocal(HomgPoint3D(1,0,0));
291  HomgPoint2D temp;
292  if(camera->DoesPointProjectIntoImage(epiDir, temp)) {
293  maxPhi = M_PI;
294  minPhi = -M_PI;
295  }
296  */
297 
298  /* find out if the camera is receiving optical rays
299  along direction of cylinder axis: */
300  HomgPoint3D epiDirHomg = relativeTransform.GlobalToLocal(HomgPoint3D(1,0,0));
301  Vector3<double> epiDir;
302  epiDirHomg.GetEuclidean(epiDir);
303 // cerr<<"epiDir = "<<epiDir<<endl;
304  HomgPoint3D epiDirNegHomg =
305  relativeTransform.GlobalToLocal(HomgPoint3D(-1,0,0));
306  Vector3<double> epiDirNeg;
307  epiDirHomg.GetEuclidean(epiDirNeg);
308 // cerr<<"epiDirNeg = "<<epiDirNeg<<endl;
309  HomgPoint2D temp;
310 
311 
312 
313  if(camera->DoesPointProjectIntoImageLocal(epiDir, temp)) {
314  maxX = clippingMaxX;//positive x is fully visible!
315 // cerr<<"maximizing X...\n";
316  }
317  if(camera->DoesPointProjectIntoImageLocal(epiDirNeg, temp)) {
318  minX = -clippingMaxX;//negative x is fully visible!
319 // cerr<<"minimizing X...\n";
320  }
321 
322  if(maxPhi<=minPhi)
323  return -1;
324 
325  double deltPhi = maxPhi - minPhi;
326  //heuristic number of epilines:
327  relativePhiRes = (width+height)/deltPhi;
328  //heuristic!
329  double deltaX = maxX - minX;
330  relativeXRes = sqrt( (double)(width*width+height*height ))/deltaX;
331  return 0;
332 }
333 
334 template <class InputStorageType, class OutputStorageType>
337  const ProjectionParametersBase* camera,
338  const Pose& rectPose,
339  double& minX, double& maxX,
340  double& minPhi, double& maxPhi,
341  double& relativeXRes,
342  double& relativePhiRes) const
343 {
344  const ProjectionParametersSpherical* pps =
345  dynamic_cast<const ProjectionParametersSpherical*>(camera);
346 
347  // BIASWARN("Spherical camera rectification is not optimized yet.");
348  Pose relativeTransform;
349  //transforms points from camera coords (local) to cylinder coords (global)
350  relativeTransform.BecomeRelativeTransform(camera->GetPose(), rectPose);
351 
352  unsigned int width, height;
353  camera->GetImageSize(width, height);
354 
355  maxX = DBL_MIN;
356  minX = DBL_MAX;
357  maxPhi = -M_PI;
358  minPhi = M_PI;
359 
360  //run over max image circle and calculate intersections with unit cylinder
361  Vector3<double> testedPoint, p;
362  HomgPoint3D rectPoint;
363  // double phi;
364  int radius = (int)rint(pps->GetRadius());
365  double ppx, ppy;
366  pps->GetPrincipal(ppx, ppy);
367  int pp[2] = {(int)rint(ppx), (int)rint(ppy)};
368  BresenhamCircle circle(pp, radius);
369  int ciclePoint[] = {0,0};
370  while(circle.GetNext(ciclePoint)) {
371  camera->UnProjectLocal(HomgPoint2D(ciclePoint[0], ciclePoint[1], 1.0), p, testedPoint);
372  rectPoint = relativeTransform.LocalToGlobal(HomgPoint3D(testedPoint));
373  SetMinMaxFrom_(rectPoint, minX, maxX, minPhi, maxPhi);
374  }
375 
376 
377  double clippingMaxX = tan(maxHalfAngleInX_);
378  if(minX < -clippingMaxX) minX = -clippingMaxX;
379  if(maxX > clippingMaxX) maxX = clippingMaxX;
380 
381  /* find out if the camera is receiving optical rays
382  along direction of cylinder axis: */
383  HomgPoint3D epiDirHomg = relativeTransform.GlobalToLocal(HomgPoint3D(1,0,0));
384  Vector3<double> epiDir;
385  epiDirHomg.GetEuclidean(epiDir);
386  // cerr<<"epiDir = "<<epiDir<<endl;
387 
388  HomgPoint3D epiDirNegHomg =
389  relativeTransform.GlobalToLocal(HomgPoint3D(-1,0,0));
390  Vector3<double> epiDirNeg;
391  epiDirHomg.GetEuclidean(epiDirNeg);
392  // cerr<<"epiDirNeg = "<<epiDirNeg<<endl;
393 
394  HomgPoint2D temp;
395  //bool epipoleIsInImage = false;
396  if(camera->DoesPointProjectIntoImageLocal(epiDir, temp)) {
397  maxX = clippingMaxX;//positive x is fully visible!
398  //epipoleIsInImage = true;
399  // cerr<<"maximizing X...\n";
400  }
401  if(camera->DoesPointProjectIntoImageLocal(epiDirNeg, temp)) {
402  minX = -clippingMaxX;//negative x is fully visible!
403  //epipoleIsInImage = true;
404  // cerr<<"minimizing X...\n";
405  }
406 
407  // cerr<<"minX = "<<minX<<endl;
408  // cerr<<"maxX = "<<maxX<<endl;
409  if(maxPhi<=minPhi)
410  return -1;
411 
412  /*heuristic:
413  if worst case is taken the circumference in pixels will give the count
414  of distinguishable epipolar curves. If image resolution is not to bad
415  those curves will be most likely be only distinguishable by the one pixel
416  on the circumference.
417  The loss of information by halfing the number of used
418  epipolar curves would hence be acceptable.
419  Note: the code below represents the worst case assumption.
420  */
421  double numEpiLines = 2.0*M_PI*pps->GetRadius();
422  // if(epipoleIsInImage) numEpiLines*=2.0;
423  double deltaPhi = maxPhi - minPhi;
424  relativePhiRes = numEpiLines/deltaPhi;
425 
426  /*heuristic:
427  The worst case is that an epipolar curve lies on the circumference
428  so that number of pixel on half of the circumference are the number
429  of samples along an epipolar plane. This is only possible if the
430  viewing angle is larger then 2*90Deg. Other wise the arclength of every
431  great circle passing through the fov is the same.
432  */
433  // double numSamplesOnEpiLine = M_PI*pps->GetRadius()*2.0;
434 
435  //we assume that the circumference is the circle with the most samples
436  //and no great circle exists that gets more.
437  double anglePerSample = 1.0/pps->GetRadius();
438  //the minimale stepsize along cylinder not leaving out pixels
439  //max length over anglePerSample
440  double minXStepSize = tan(anglePerSample);
441  relativeXRes = 1.0/minXStepSize;
442 
443  //focallengthTheta is the number of pixels per radians in worst case
444  // double focallengthTheta = numSamplesOnEpiLine/pps->GetMaxCamAngle();
445  // pps->GetRadius()/pps->GetMaxCamAngle();
446  // cerr<<"focallengthTheta = "<<focallengthTheta<<endl;
447  //heuristic!
448  //find angle range over maxX and minX
449 // double maxTheta = atan2(maxX,1);
450 // // cerr<<"maxX theta = "<<maxTheta<<endl;
451 // double minTheta = atan2(minX,1);
452 // // cerr<<"minX theta = "<<minTheta<<endl;
453 // double thetaRange = maxTheta-minTheta;
454 
455 
456 // /* If sampling is applied along the radius how many pixel a spherical image
457 // would have in the viewing angle of the cylinder camera: */
458 // double pixelsInThetaRange = thetaRange * focallengthTheta;
459  /* Since the cylinder is sampled equidistantly not equiangularily
460  * a scale to the number of samples neccessary to reach the same sampling
461  */
462 
463 // double deltaX = maxX - minX;
464 // relativeXRes = pixelsInThetaRange/deltaX;
465 // cerr<<"relativeXRes = "<<relativeXRes<<endl;
466 
467  return 0;
468 }
469 
470 template <class InputStorageType, class OutputStorageType>
473  const ProjectionParametersBase* camera,
474  const Pose& rectPose,
475  double& minX, double& maxX,
476  double& minPhi, double& maxPhi,
477  double& relativeXRes,
478  double& relativePhiRes) const
479 {
480  //determine bounding volume on cylinder
481  Pose relativeTransform;
482  //transforms points from camera coords (local) to cylinder coords (global)
483  relativeTransform.BecomeRelativeTransform(camera->GetPose(), rectPose);
484  unsigned int width, height;
485  camera->GetImageSize(width, height);
486 
487  maxX = DBL_MIN;
488  minX = DBL_MAX;
489  maxPhi = -M_PI;
490  minPhi = M_PI;
491 
492  Vector3<double> testedPoint;
493  HomgPoint3D rectPoint;
494  Vector3<double> p;
495  // double phi;
496  //check upper and lower image border
497  for(unsigned int x=0; x<width; x++) {
498  camera->UnProjectLocal(HomgPoint2D(x, 0, 1.0), p, testedPoint);
499  if(testedPoint.NormL2() < 1e-10) BIASABORT;
500  rectPoint = relativeTransform.LocalToGlobal(HomgPoint3D(testedPoint));
501  SetMinMaxFrom_(rectPoint, minX, maxX, minPhi, maxPhi);
502 
503  camera->UnProjectLocal(HomgPoint2D(x, height-1, 1.0), p, testedPoint);
504  if(testedPoint.NormL2() < 1e-10) BIASABORT;
505  rectPoint = relativeTransform.LocalToGlobal(HomgPoint3D(testedPoint));
506  SetMinMaxFrom_(rectPoint, minX, maxX, minPhi, maxPhi);
507  }
508 
509  for(unsigned int y=0; y<height; y++) {
510  camera->UnProjectLocal(HomgPoint2D(0, y, 1.0), p, testedPoint);
511  if(testedPoint.NormL2() < 1e-10) BIASABORT;
512  rectPoint = relativeTransform.LocalToGlobal(HomgPoint3D(testedPoint));
513  SetMinMaxFrom_(rectPoint, minX, maxX, minPhi, maxPhi);
514 
515  camera->UnProjectLocal(HomgPoint2D(width-1, y, 1.0), p, testedPoint);
516  if(testedPoint.NormL2() < 1e-10) BIASABORT;
517  rectPoint = relativeTransform.LocalToGlobal(HomgPoint3D(testedPoint));
518  SetMinMaxFrom_(rectPoint, minX, maxX, minPhi, maxPhi);
519  }
520 
521  double clippingMaxX = tan(maxHalfAngleInX_);
522 // #ifdef BIAS_DEBUG
523 // cerr<<"detemined image spaceing:\n";
524 // cerr<<"clipMinX/clipMaxX = "<<-clippingMaxX<<"/"<<clippingMaxX<<endl;
525 // cerr<<"minX/maxX = "<<minX<<"/"<<maxX<<endl;
526 // cerr<<"minPhi/maxPhi = "<<minPhi<<"/"<<maxPhi<<endl;
527 // #endif
528 
529  if(minX < -clippingMaxX) minX = -clippingMaxX;
530  if(maxX > clippingMaxX) maxX = clippingMaxX;
531 
532  /* find out if the camera is receiving optical rays
533  along direction of cylinder axis: */
534  HomgPoint3D epiDirHomg = relativeTransform.GlobalToLocal(HomgPoint3D(1,0,0));
535  Vector3<double> epiDir;
536  epiDirHomg.GetEuclidean(epiDir);
537  // cerr<<"epiDir = "<<epiDir<<endl;
538  HomgPoint3D epiDirNegHomg =
539  relativeTransform.GlobalToLocal(HomgPoint3D(-1,0,0));
540  Vector3<double> epiDirNeg;
541  epiDirHomg.GetEuclidean(epiDirNeg);
542  // cerr<<"epiDirNeg = "<<epiDirNeg<<endl;
543  HomgPoint2D temp;
544 
545  if(camera->DoesPointProjectIntoImageLocal(epiDir, temp)) {
546  maxX = clippingMaxX;//positive x is fully visible!
547  maxPhi = M_PI;
548  minPhi = -M_PI;
549 // cerr<<"maximizing X...\n";
550  }
551  if(camera->DoesPointProjectIntoImageLocal(epiDirNeg, temp)) {
552  minX = -clippingMaxX;//negative x is fully visible!
553  maxPhi = M_PI;
554  minPhi = -M_PI;
555 // cerr<<"minimizing X...\n";
556  }
557 
558  if(maxPhi<=minPhi)
559  return -1;
560 
561  //very! heuristic!
562  double deltPhi = maxPhi - minPhi;
563  //heuristic number of epilines:
564  relativePhiRes = double(height)/deltPhi;
565 
566  double deltaX = maxX - minX;
567  relativeXRes = double(width)/deltaX;
568  return 0;
569 }
570 
571 template <class InputStorageType, class OutputStorageType>
574  const Pose& rectPose,
575  double& minX, double& maxX,
576  double& minPhi, double& maxPhi,
577  double& relativeXRes,
578  double& relativePhiRes) const
579 {
581  dynamic_cast<const ProjectionParametersPerspective*>(camera);
582  if (ppp == NULL) {
583  const ProjectionParametersSpherical* pps =
584  dynamic_cast<const ProjectionParametersSpherical*>(camera);
585  if (pps == NULL) {
586  const ProjectionParametersCylindric* ppc =
587  dynamic_cast<const ProjectionParametersCylindric*>(camera);
588  if (ppc == NULL) {
589  BIASERR("unexpected ProjectionParameter type\n");
590  return -1;
591  } else {
592  return DetermineCylindricCameraBoundriesCylindric_(camera,
593  rectPose,
594  minX, maxX,
595  minPhi, maxPhi,
596  relativeXRes,
597  relativePhiRes);
598  }
599  } else {
600  return DetermineCylindricCameraBoundriesSpherical_(camera,
601  rectPose,
602  minX, maxX,
603  minPhi, maxPhi,
604  relativeXRes,
605  relativePhiRes);
606  }
607  } else {
608  return DetermineCylindricCameraBoundriesPerspective_(camera,
609  rectPose,
610  minX, maxX,
611  minPhi, maxPhi,
612  relativeXRes,
613  relativePhiRes);
614  }
615 
616  return 0;
617 }
618 
619 namespace BIAS{
620 // TODO FIXME win32 template instantiation problem (JW)
622 template class BIASImage_EXPORT CylindricalRectification<float, float>;
623 template class BIASImage_EXPORT CylindricalRectification<unsigned char, float>;
624 template class BIASImage_EXPORT CylindricalRectification<float, unsigned char>;
625 
626 #if defined(BUILD_IMAGE_CHAR)
627 // TODO FIXME win32 template instantiation problem (JW)
628 template class BIASImage_EXPORT CylindricalRectification<unsigned char, char>;
629 template class BIASImage_EXPORT CylindricalRectification<char, char>;
630 #endif
631 
632 #if defined(BUILD_IMAGE_USHORT)
634 #endif
635 
636 #if defined(BUILD_IMAGE_SHORT)
637 template class BIASImage_EXPORT CylindricalRectification<short, short>;
638 #endif
639 
640 #if defined(BUILD_IMAGE_SHORT)&&defined(BUILD_IMAGE_USHORT)
641 template class BIASImage_EXPORT CylindricalRectification<unsigned short, short>;
642 #endif
643 
644 #if defined(BUILD_IMAGE_INT)
645 template class BIASImage_EXPORT CylindricalRectification<int,int>;
646 #endif
647 
648 #if defined(BUILD_IMAGE_USHORT)
649 template class BIASImage_EXPORT CylindricalRectification<unsigned short,float>;
650 #endif
651 
652 #if defined(BUILD_IMAGE_USHORT) && defined(BUILD_IMAGE_INT)
653 template class BIASImage_EXPORT CylindricalRectification<unsigned short,int>;
654 #endif
655 
656 #if defined(BUILD_IMAGE_DOUBLE)
657 template class BIASImage_EXPORT CylindricalRectification<double,double>;
658 #endif
659 }
void BecomeRelativeTransform(const CoordinateTransform3D &newLocal, const CoordinateTransform3D &newGlobal)
Changes this coordinate transformation so that parameter newLocal becomes the local coordinate frame ...
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
class HomgPoint2D describes a point with 2 degrees of freedom in projective coordinates.
Definition: HomgPoint2D.hh:67
int DetermineCylindricCameraBoundries_(const ProjectionParametersBase *camera, const Pose &rectPose, double &minX, double &maxX, double &minPhi, double &maxPhi, double &relativeXRes, double &relativePhiRes) const
Base class for rectification implementations that make use of projections to represent rectified stat...
virtual int DetermineRectificationParameters_()
Calculating the projection parameters for specific rectification.
CylindricalRectification(double maxAngleRAD=70 *DEG_TO_RAD)
Parameter determines the extend of the cylinder along the cylinder axis.
Scans a circle using Bresenham&#39;s integer arithmetic algorithm.
camera parameters which define the mapping between rays in the camera coordinate system and pixels in...
virtual int GetPrincipal(double &PrincipalX, double &PrincipalY) const
Get principal point (in pixels relative to top left corner).
Class implements rectification by image projection onto a cylinder.
HomgPoint3D GlobalToLocal(const HomgPoint3D &X_G) const
Transform point from world frame to local coordinate frame.
int DetermineCylindricCameraBoundriesCylindric_(const ProjectionParametersBase *camera, const Pose &rectPose, double &minX, double &maxX, double &minPhi, double &maxPhi, double &relativeXRes, double &relativePhiRes) const
int DetermineCylindricCameraBoundriesSpherical_(const ProjectionParametersBase *camera, const Pose &rectPose, double &minX, double &maxX, double &minPhi, double &maxPhi, double &relativeXRes, double &relativePhiRes) const
Represents 3d pose transformations, parametrized as Euclidean translation and unit quaternion orienta...
Definition: Pose.hh:73
virtual bool DoesPointProjectIntoImageLocal(const Vector3< double > &localX, HomgPoint2D &x, bool IgnoreDistortion=false) const
Checks if 3D point projects into specified image and returns belonging 2D image point.
bool GetNext(int next[2])
Returns the coordinate of the next point on the circle.
camera parameters which define the mapping between rays in the camera coordinate system and pixels in...
virtual void UnProjectLocal(const HomgPoint2D &pos, Vector3< double > &origin, Vector3< double > &direction, bool ignoreDistortion=false) const =0
Calculates the view ray, which belongs to the given position on the image plane, in local coordinates...
class HomgPoint3D describes a point with 3 degrees of freedom in projective coordinates.
Definition: HomgPoint3D.hh:61
virtual int GetImageSize(unsigned int &Width, unsigned int &Height) const
Obtain image dimensions.
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_...
HomgPoint3D LocalToGlobal(const HomgPoint3D &X_L) const
Transform point from local frame to world coordinate frame.
Camera parameters which define the mapping between rays in the camera coordinate system and pixels in...
virtual bool IsInputCameraValid(const BIAS::Image< InputStorageType > &img, const BIAS::ProjectionParametersBase *proj)
only perspective and spherical cameras are allowed
static void SetMinMaxFrom_(BIAS::HomgPoint3D &rectPoint, double &minX, double &maxX, double &minPhi, double &maxPhi)
Helper for DetermineCylindricCameraBoundries_.
int DetermineCylindricCameraBoundriesPerspective_(const ProjectionParametersBase *camera, const Pose &rectPose, double &minX, double &maxX, double &minPhi, double &maxPhi, double &relativeXRes, double &relativePhiRes) const
double GetRadius() const
Return radius of spherical image in pixels.
Camera parameters which define the mapping between rays in the camera coordinate system and pixels in...
static int ProjectOntoUnitCylinder_(BIAS::HomgPoint3D &point, double &phi)
Helper for DetermineCylindricCameraBoundries_.
virtual const BIAS::Pose & GetPose() const
Return complete pose object.
double NormL2() const
the L2 norm sqrt(a^2 + b^2 + c^2)
Definition: Vector3.hh:633
class BIASGeometryBase_EXPORT HomgPoint2D
class BIASGeometryBase_EXPORT HomgPoint3D