Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
EpipolarLine.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 
26 #include "EpipolarLine.hh"
27 
28 #include <Base/Debug/Debug.hh>
29 #include <Base/ImageUtils/ImageDraw.hh>
30 #include <Base/ImageUtils/Bresenham.hh>
31 #include <cmath>
32 #include <cfloat>
33 
34 #define MY_DBL_PRECISION 1e-10
35 
36 #include <Base/Common/BIASpragma.hh>
37 
38 using namespace BIAS;
39 using namespace std;
40 
41 // the following is used in DetermineIntersectionsAndEpipoleDistances_
42 int CompIntersect(const void *left, const void *right);
43 
44 ostream& operator<<(ostream& os, const enum TEdge edge)
45 {
46  switch(edge){
47  case TopEdge: os << "top"; break;
48  case RightEdge: os << "right"; break;
49  case BottomEdge: os << "bottom"; break;
50  case LeftEdge: os << "left"; break;
51  case InvalidEdge: os << "invalid"; break;
52  }
53  return os;
54 }
55 
56 
58 {
59  //Width_ = Height_ = 0;
60  minx_ = maxx_ = miny_ = maxy_ = 0.0;
61 
62  Angle_ = DeltaR_ = RMinLine_ = RMaxLine_ = 0.0;
63  // set all HomgPoints2D to (0,0,1)
64  CloseIntersection_.Set (0.0, 0.0);
67  dx_ = dy_ = 0.0;
68 }
69 
71  :HomgLine2D(line)
72 {
73  Epipole_ = line.GetCopyOfEpipole();
75  Type_ = line.GetLineType();
76 
77  //Width_ = line.GetImageWidth();
78  //Height_ = line.GetImageHeight();
80 
81  Angle_ = line.GetAngle();
84  FarEdge_ = line.GetFarEdge();
85  CloseEdge_ = line.GetCloseEdge();
86  RMinLine_ = line.GetRMin();
87  RMaxLine_ = line.GetRMax();
88  dx_ = line.GetDx();
89  dy_ = line.GetDy();
90 }
91 
92 
94 {
95  (*this).HomgLine2D::operator=(line);
96  Epipole_ = line.GetCopyOfEpipole();
98  Type_ = line.GetLineType();
99  // Width_ = line.GetImageWidth();
100  //Height_ = line.GetImageHeight();
102  Angle_ = line.GetAngle();
105  FarEdge_ = line.GetFarEdge();
106  CloseEdge_ = line.GetCloseEdge();
107  RMinLine_ = line.GetRMin();
108  RMaxLine_ = line.GetRMax();
109  dx_ = line.GetDx();
110  dy_ = line.GetDy();
111  return *this;
112 }
113 
115  :HomgLine2D(vec)
116 {}
117 
119 {}
120 
121 void
122 EpipolarLine::GetNextLine(bool clockwise, EpipolarLine& nextline,
123  double dist)
124 {
125  double dx, dy;
126  HomgPoint2D newpoint;
127 
128  Homogenize();
129  // cerr <<"slope: "<<slope<<"\tinv. slope: "<<bool2string(invslope)
130  // <<"\tdr: "<<GetDeltaR)<<"\ttype: "<<GetLineType()
131  // <<"\tangle: "<<GetAngle()<<"\tclockwise: "<<bool2string(clockwise)
132  // <<endl;
133 
134  dx = dist*fabs(data_[0]);
135  dy = dist*fabs(data_[1]);
136 
137  if (data_[0] * data_[1] < 0)
138  dx *= -1;
139 
140  if (fabs(GetAngle())>M_PI_2){
141  dx *= -1;
142  dy *= -1;
143  }
144 
145  if (!clockwise){
146  dx *= -1;
147  dy *= -1;
148  }
149 
151 
152  // maybe newpoint.Homogenize() ?
153  newpoint[0] += dx;
154  newpoint[1] += dy;
155 
156  nextline.Init(minx_, miny_, maxx_, maxy_,
157  GetEpipole(),
158  newpoint, GetEpipolePosition());
159 
160  BIASDOUT(D_EL_NEXTLINE,"dx: "<<dx<<"\tdy: "<<dy<<"\tnewpoint: ("
161  <<newpoint[0]<<", "<<newpoint[1]<<") far int.: ("
162  <<nextline.GetFarIntersectionWithImageBorder()[0]<<", "
163  <<nextline.GetFarIntersectionWithImageBorder()[1]<<") angle: "
164  <<nextline.GetAngle());
165 }
166 
167 
168 int
169 EpipolarLine::Recalc(unsigned int width, unsigned int height,
170  HomgPoint2D& epipole, enum HomgPoint2D::EPosition epos)
171 {
172  return Recalc(0.0, 0.0, double(width-1), double(height-1), epipole, epos);
173 }
174 
175 int EpipolarLine::Recalc(const double& minx,
176  const double& miny,
177  const double& maxx,
178  const double& maxy,
179  HomgPoint2D& epipole,
180  enum HomgPoint2D::EPosition epos) {
181  minx_ = minx;
182  miny_ = miny;
183  maxx_ = maxx;
184  maxy_ = maxy;
185 
186  Epipole_ = epipole;
187  EpipolePosition_ = epos;
188  return Recalc();
189 }
190 
191 int
193 {
194  Homogenize();
195  // argument point is only used as dummy, to
196  // verify if (argument-)point sits on image border
197  HomgPoint2D point(minx_-1.0, miny_-1.0);
198 
199  if (!DetermineIntersectionsAndEpipoleDistances_(point)) return -1;
200  Angle_ = atan2(FarIntersection_[1]-Epipole_[1],
201  FarIntersection_[0]-Epipole_[0]);
203  Homogenize();
204  DeltaR_ = (fabs(data_[0]) > fabs(data_[1]))?(fabs(data_[0]/data_[1])):
205  (fabs(data_[1]/data_[0]));
206  return 0;
207 }
208 
209 
210 void
211 EpipolarLine::Init(unsigned int width, unsigned int height,
212  HomgPoint2D& epipole, HomgPoint2D& otherpoint,
213  enum HomgPoint2D::EPosition epos)
214 {
215  double minx = 0.0;
216  double maxx = double(width-1);
217  double miny = 0.0;
218  double maxy = double(height-1);
219  Init(minx, miny, maxx, maxy, epipole, otherpoint, epos);
220 }
221 
222 void
223 EpipolarLine::Init(const double& minx, const double& miny,
224  const double& maxx, const double& maxy,
225  HomgPoint2D& epipole, HomgPoint2D& otherpoint,
226  enum HomgPoint2D::EPosition epos)
227 {
228  PInfinity_ = otherpoint;
229  PInfinityPosition_ = otherpoint.DeterminePosition(minx, miny,
230  maxx, maxy);
231  epipole.CrossProduct(otherpoint, *this);
232  Homogenize();
233  Epipole_ = epipole;
234 
235  minx_ = minx;
236  miny_ = miny;
237  maxx_ = maxx;
238  maxy_ = maxy;
239 
240  Homogenize();
241  DeltaR_ = (fabs(data_[0]) > fabs(data_[1]))?(fabs(data_[0]/data_[1])):
242  (fabs(data_[1]/data_[0]));
243 
245  Angle_ = atan2(FarIntersection_[1]-Epipole_[1],
246  FarIntersection_[0]-Epipole_[0]);
248  EpipolePosition_ = epos;
249 }
250 
251 
252 
253 void
254 EpipolarLine::Init(unsigned int width, unsigned int height,
255  HomgPoint2D& epipole, HomgPoint2D& pinf)
256 {
257  Init(width, height, epipole, pinf,
258  epipole.DeterminePosition(width, height));
259 }
260 
261 
262 // template <class PixelType> double
263 // EpipolarLine::ScanLine(Image<PixelType>& Source, HomgPoint2D& epipole,
264 // double ROffset, unsigned int& DestLength,
265 // PixelType *Destination, bool forward)
266 double
268  enum HomgPoint2D::EPosition epos, double RMinImage,
269  double RMaxImage, bool forward,
270  unsigned int& DestLength, unsigned char *Destination)
271 {
272  DestLength = 0;
273  Homogenize();
274  Epipole_ = epipole;
275  minx_ = 0;
276  maxx_ = Source.GetWidth()-1;
277  miny_ = 0;
278  maxy_ = Source.GetHeight()-1;
279 
280  Homogenize();
281  DeltaR_ = (fabs(data_[0]) > fabs(data_[1]))?(fabs(data_[0]/data_[1])):
282  (fabs(data_[1]/data_[0]));
284  return -1.0;
285  Angle_ = atan2(FarIntersection_[1]-Epipole_[1],
286  FarIntersection_[0]-Epipole_[0]);
287  EpipolePosition_ = epos;
288 
290 
292 
293  BIASDOUT(D_EL_TRANSF,"TransformedLine ("<<TransformedStart_[0]<<", "
294  <<TransformedStart_[1]<<") -> ("<<TransformedEnd_[0]<<", "
295  <<TransformedEnd_[1]<<")");
296 
297  ROffset_ = (unsigned int)ceil(RMinLine_) - (unsigned int)ceil(RMinImage);
298 
299  BIASDOUT(D_EL_OFFSET,"RMinLine_: "<< RMinLine_ <<"\tRMaxLine_: "<< RMaxLine_
300  <<"\tRMinImage:"<<RMinImage<<"\tRMaxImage:"<<RMaxImage
301  <<"\tROffset_: "<< ROffset_);
302 
303  return ScanLine_(Source, ROffset_, DestLength, Destination, forward);
304 }
305 
306 
307 // input : Source, ROffset
308 // output : DestLength, Destination
309 // assumes that EpipolarLine is fully initialized
310 // template <class PixelType> double
311 // EpipolarLine::ScanLine_(Image<PixelType>& Source, double ROffset,
312 // unsigned int& DestLength, PixelType *Destination,
313 // bool forward)
314 double
315 EpipolarLine::ScanLine_(Image<unsigned char>& Source, unsigned int ROffset,
316  unsigned int& DestLength, unsigned char *Destination,
317  bool forward)
318 {
319  unsigned int counter= 0;
320  int counterincr = 0;
321  unsigned int DestImageWidth =
322  (unsigned int)floor(sqrt(pow(Source.GetWidth(),2.0) +
323  pow(Source.GetHeight(),2.0)))+ 1;
324 
325  if (Destination == NULL){
326  Destination = new unsigned char[DestImageWidth];
327  ROffset = 0;
328  }
329 
330  DestLength = ROffset;
331 
332  if(forward){
333  counter = DestLength;
334  counterincr = 1;
335  } else {
336  counter = DestImageWidth - DestLength;
337  counterincr = -1;
338  }
339  while ((TransformedCurrent_[0]<=TransformedEnd_[0])&&
341  // bilinear interpolation
342  //Current_=InverseTransform_(TransformedCurrent_);
344  BIASDOUT(D_EL_ROUND,"x: "<<Current_[0]<<" y: "<<Current_[1]
345  <<"\tdest: "<<(int)Destination[DestLength]);
346  Destination[counter] = (unsigned char)
348 
351  DestLength++;
352  counter += counterincr;
353  }
354  BIASDOUT(D_EL_OFFSET,"DestLength: " << DestLength);
356  Length_ = DestLength - ROffset_;
357  return ROffset - RMinLine_;
358 }
359 
360 void
361 EpipolarLine::Interpolate_(enum TLineType& type, unsigned char **ida, int& x,
362  int& y, double& g, unsigned char& result)
363 {
364  result = 0;
365  double gm = 1.0 - g;
366  switch(type){
367  case SE_E:
368  BIASDOUT(D_EL_BRESROUND,x << ", " << y << " : "<< gm << "\t"
369  << x << ", " << y+1 << " : "<<g);
370  result = (unsigned char)((double)ida[y][x]*gm +
371  (double)ida[y+1][x]*g);
372  break;
373  case S_SE:
374  BIASDOUT(D_EL_BRESROUND,y << ", " << y << " : "<< gm << "\t"
375  << y << ", " << x+1 << " : "<<g);
376  result = (unsigned char)((double)ida[x][y]*gm +
377  (double)ida[x+1][y]*g);
378  // Original[0] = Transformed[1];
379  // Original[1] = Transformed[0];
380  break;
381  case SW_S:
382  BIASDOUT(D_EL_BRESROUND,y << ", " << -x << " : "<< gm << "\t"
383  << y << ", " << -x+1 << " : "<<g);
384  result = (unsigned char)((double)ida[x][-y]*gm +
385  (double)ida[x+1][-y]*g);
386  // Original[0] = Transformed[1];
387  // Original[1] = -Transformed[0];
388  break;
389  case W_SW:
390  BIASDOUT(D_EL_BRESROUND,-x << ", " << y << " : "<< gm << "\t"
391  << -x << ", " << y+1 << " : "<<g);
392  result = (unsigned char)((double)ida[y][-x]*gm +
393  (double)ida[y+1][-x]*g);
394  // Original[0] = -Transformed[0];
395  // Original[1] = Transformed[1];
396  break;
397  case NW_W:
398  BIASDOUT(D_EL_BRESROUND,-x << ", " << -y << " : "<< gm << " : "
399  <<(int)ida[-y][-x]<<"\t" << -x << ", " << -y-1 << " : "<<g
400  <<" : "<<(int)ida[-y-1][-x]);
401  result = (unsigned char)((double)ida[-y][-x]*gm +
402  (double)ida[-y-1][-x]*g);
403  BIASDOUT(D_EL_BRESROUND,"result: "<<(int)result);
404  // Original = Transformed * (-1);
405  break;
406  case N_NW:
407  BIASDOUT(D_EL_BRESROUND,-y << ", " << -x << " : "<< gm << "\t"
408  << -y << ", " << -x+1 << " : "<<g);
409  result = (unsigned char)((double)ida[-x][-y]*gm +
410  (double)ida[-x-1][-y]*g);
411  // Original[0] = -Transformed[1];
412  // Original[1] = -Transformed[0];
413  break;
414  case NE_N:
415  BIASDOUT(D_EL_BRESROUND,-y << ", " << x << " : "<< gm << "\t"
416  << -y << ", " << x+1 << " : "<<g);
417  result = (unsigned char)((double)ida[-x][y]*gm +
418  (double)ida[-x-1][y]*g);
419  // Original[0] = -Transformed[1];
420  // Original[1] = Transformed[0];
421  break;
422  case E_NE:
423  BIASDOUT(D_EL_BRESROUND,x << ", " << -y << " : "<< gm << "\t"
424  << x << ", " << -y+1 << " : "<<g);
425  result = (unsigned char)((double)ida[-y][x]*gm +
426  (double)ida[-y-1][x]*g);
427  //cerr << " y " << -y << " g " << gm << endl;
428  // Original[0] = Transformed[0];
429  // Original[1] = -Transformed[1];
430  break;
431  case LT_Invalid:
432  BIASERR("Invalid LineType, maybe wrong slope in EpipolarLine");
433  break;
434  }
435 }
436 
438 {
439  double dr=0.0;
440  Vector2<double> Transfslope(0.0, 0.0), Slope(data_[1], data_[0]);
441 // dx_ = fabs(data_[0]);
442 // dy_ = fabs(data_[1]);
443  Sym_.Transform(Type_, Slope, Transfslope);
444  dx_ = fabs(Transfslope[0]);
445  dy_ = fabs(Transfslope[1]);
446 
447  BIASDOUT(D_EL_TRANSF," dx_ "<<dx_<<"\tdy_ "<<dy_<<"\ttype: "<<Type_);
448 
451 
452  dr = ceil(RMinLine_) - RMinLine_;
453  BIASDOUT(D_EL_TRANSF," dr start: "<<dr<<"\tstart befor "
455  TransformedStart_[0] += dx_ * dr;
456  TransformedStart_[1] += dy_ * dr;
457 
458  Sym_.InverseTransform(Type_, TransformedStart_, Start_);
459 
460  dr = RMaxLine_ - floor(RMaxLine_);
461  BIASDOUT(D_EL_TRANSF," dr end: "<<dr<<"\tend befor "
463  TransformedEnd_[0] -= dx_ * dr;
464  TransformedEnd_[1] -= dy_ * dr;
465 
466  Sym_.InverseTransform(Type_, TransformedEnd_, End_);
467 
468  BIASDOUT(D_EL_TRANSF,"("<<CloseIntersection_[0]<<", "<<CloseIntersection_[1]
469  <<") -> ("<<FarIntersection_[0]<<", "<<FarIntersection_[1]
470  <<") transf: ("<<TransformedStart_[0]<<", "<<TransformedStart_[1]
471  <<") -> ("<<TransformedEnd_[0]<<", "<<TransformedEnd_[1]<<")");
472 
475 
476 }
477 
478 // the following is used in DetermineIntersectionsAndEpipoleDistances_
479 int CompIntersect(const void *left, const void *right)
480 {
481  struct TIntersect *Left = (struct TIntersect *)left;
482  struct TIntersect *Right = (struct TIntersect *)right;
483  return (Left->EpipoleDistance < Right->EpipoleDistance);
484 }
485 
486 bool
488 {
489  bool result = true;
490  int intersectioncount = 0;
491  struct TIntersect edges[4]; // 0=left, 1=right, 2=top, 3=bottom
492  HomgLine2D left(-1.0, 0.0, minx_);
493  HomgLine2D right(-1.0, 0.0, maxx_);
494  HomgLine2D top(0.0, -1.0, miny_);
495  HomgLine2D bottom(0.0, -1.0, maxy_);
496 
497  edges[0].IntersectsInImage = edges[1].IntersectsInImage
498  = edges[2].IntersectsInImage = edges[3].IntersectsInImage = false;
499  edges[0].EpipoleDistance = edges[1].EpipoleDistance
500  = edges[2].EpipoleDistance = edges[3].EpipoleDistance = -1.0;
501  /// the lines describing the image borders
502  edges[0].Edge = LeftEdge;
503  edges[1].Edge = RightEdge;
504  edges[2].Edge = TopEdge;
505  edges[3].Edge = BottomEdge;
506  /// compute the intersection of the image borders with the epipolar lines
507  edges[0].Point = Intersection(left);
508  if (!edges[0].Point.IsAtInfinity()) edges[0].Point.Homogenize();
509  else edges[0].Point.Set(DBL_MAX, DBL_MAX, 0.0);
510  edges[1].Point = Intersection(right);
511  if (!edges[1].Point.IsAtInfinity()) edges[1].Point.Homogenize();
512  else edges[1].Point.Set(DBL_MAX, DBL_MAX, 0.0);
513  edges[2].Point = Intersection(top);
514  if (!edges[2].Point.IsAtInfinity()) edges[2].Point.Homogenize();
515  else edges[2].Point.Set(DBL_MAX, DBL_MAX, 0.0);
516  edges[3].Point = Intersection(bottom);
517  if (!edges[3].Point.IsAtInfinity()) edges[3].Point.Homogenize();
518  else edges[3].Point.Set(DBL_MAX, DBL_MAX, 0.0);
519 
520  // deal with compiler precision
521  for (unsigned int i=0; i<4; i++){
522  if (edges[i].Point[0]<minx_ && edges[i].Point[0]>minx_-MY_DBL_PRECISION)
523  edges[i].Point[0] = minx_;
524  if (edges[i].Point[1]<miny_ && edges[i].Point[1] >miny_-MY_DBL_PRECISION)
525  edges[i].Point[1] = miny_;
526  if (edges[i].Point[0] > maxx_ &&
527  edges[i].Point[0] < maxx_+MY_DBL_PRECISION)
528  edges[i].Point[0] = maxx_;
529  if (edges[i].Point[1] > maxy_ &&
530  edges[i].Point[1] < maxy_+MY_DBL_PRECISION)
531  edges[i].Point[1] = maxy_;
532  }
533 
534  // #ifdef BIAS_DEBUG
535  // cout << "untested intersections: " << endl;
536  // for (int i=0; i<4; i++){
537  // cout << i <<": (" << edges[i].Point[0] << ", "
538  // << edges[i].Point[1] << ", "<< edges[i].Point[2] <<")\t"
539  // << edges[i].EpipoleDistance << endl;
540  // }
541  // #endif
542 
543  // check which intersection lie actually in the image
544  if ((point[0]==minx_) ||
545  ((edges[0].Point[2]!=0.0) &&
546  (edges[0].Point[1]>=miny_ && edges[0].Point[1]<=maxy_))){
547  if(point[0]==minx_) edges[0].Point=point;
548  edges[0].IntersectsInImage = true; intersectioncount++;
549  edges[0].EpipoleDistance = sqrt(pow(edges[0].Point[1]-Epipole_[1],2) +
550  pow(edges[0].Point[0]-Epipole_[0],2));
551  }
552  if ((point[0]==maxx_) ||
553  ((edges[1].Point[2]!=0.0) &&
554  (edges[1].Point[1]>=miny_ && edges[1].Point[1]<=maxy_))){
555  if(point[0]==maxx_) edges[1].Point=point;
556  edges[1].IntersectsInImage = true; intersectioncount++;
557  edges[1].EpipoleDistance = sqrt(pow(edges[1].Point[1]-Epipole_[1],2) +
558  pow(edges[1].Point[0]-Epipole_[0],2));
559  }
560  if ((point[1]==miny_) ||
561  ((edges[2].Point[2]!=0.0) &&
562  (edges[2].Point[0]>=minx_ && edges[2].Point[0]<=maxx_))){
563  if(point[1]==miny_) edges[2].Point=point;
564  edges[2].IntersectsInImage = true; intersectioncount++;
565  edges[2].EpipoleDistance = sqrt(pow(edges[2].Point[1]-Epipole_[1],2) +
566  pow(edges[2].Point[0]-Epipole_[0],2));
567  }
568  if ((point[1]==maxy_) ||
569  ((edges[3].Point[2]!=0.0) &&
570  (edges[3].Point[0]>=minx_ && edges[3].Point[0]<=maxx_))){
571  if(point[1]==maxy_) edges[3].Point=point;
572  edges[3].IntersectsInImage = true;intersectioncount++;
573  edges[3].EpipoleDistance = sqrt(pow(edges[3].Point[1]-Epipole_[1],2) +
574  pow(edges[3].Point[0]-Epipole_[0],2));
575  }
576 
577  // #ifdef BIAS_DEBUG
578 // cout << "unsorted intersections: " << endl;
579 // for (int i=0; i<4; i++){
580 // cout << i<<" intersects:"<< edges[i].IntersectsInImage <<": (" << edges[i].Point[0] << ", "
581 // << edges[i].Point[1] << ", "<< edges[i].Point[2] <<")\t"
582 // << edges[i].EpipoleDistance << endl;
583 // }
584 // #endif
585 
586  // sort Intersections according to epipole distance
587  qsort(&edges, 4, sizeof(struct TIntersect), CompIntersect);
588 
589  // #ifdef BIAS_DEBUG
590 // cout << "sorted intersections: " << endl;
591 // for (int i=0; i<4; i++){
592 // cout << i <<" intersects:"<< edges[i].IntersectsInImage<< " at: (" << edges[i].Point[0] << ", "
593 // << edges[i].Point[1] << ")\t" << edges[i].Point[2] << ")\t"<< edges[i].EpipoleDistance << endl;
594 // }
595 // #endif
596 
597 // if (EpipolePosition_!= Center){
598 
599  FarIntersection_ = edges[0].Point;
600  FarEdge_ = edges[0].Edge;
601  RMaxLine_ = edges[0].EpipoleDistance;
602  switch(intersectioncount){
603  case 1:
604  CloseIntersection_=edges[0].Point;
605  CloseEdge_ = edges[0].Edge;
606  RMinLine_ = edges[0].EpipoleDistance;
607  break;
608  case 2:
609  CloseIntersection_=edges[1].Point;
610  CloseEdge_ = edges[1].Edge;
611  RMinLine_ = edges[1].EpipoleDistance;
612  break;
613  case 3:
614  CloseIntersection_=edges[2].Point;
615  CloseEdge_ = edges[2].Edge;
616  RMinLine_ = edges[2].EpipoleDistance;
617  break;
618  case 4:
619  CloseIntersection_=edges[3].Point;
620  CloseEdge_ = edges[3].Edge;
621  RMinLine_ = edges[3].EpipoleDistance;
622  break;
623  default:
624  result = false;
625 #ifdef BIAS_DEBUG
626  BIASDOUT(D_EL_INT, "invalid intersection count "<<intersectioncount
627  <<" of ep. line: "<<*this<<" with epipole: "<<Epipole_
628  <<"close intersect: "<<GetCloseIntersectionWithImageBorder()
629  <<"far intersection: "<<GetFarIntersectionWithImageBorder()
630  <<"Image borders are minx, miny, maxx, maxy="
631  <<minx_<<" "<< miny_<<" "<< maxx_<<" "<< maxy_
632  << " sorted intersections: ");
633  for (int i=0; i<4; i++){
634  BIASDOUT(D_EL_INT, i <<": (" << edges[i].Point[0] << ", "
635  << edges[i].Point[1] << ")\t" << edges[i].EpipoleDistance);
636  }
637  //BIASASSERT(intersectioncount>=2);
638 #endif
639  break;
640  }
641  return result;
642 }
643 
644 
645 
646 #include <limits> // jw
647 template <class PixelType>
649 {
650  unsigned int start[2], end[2];
651  PixelType color[3];
652  color[0]=PixelType(255);
653  color[1]=PixelType(255);
654  color[2]=PixelType(255);
655 
656 // cerr << "Epipole: "<<Epipole_<<" PInfinity: "<<PInfinity_<<endl;
657 // cerr << "EpipolePos: "<<EpipolePosition_<<" pinfpos: "<<PInfinityPosition_<<endl;
658 // cerr << GetCloseIntersectionWithImageBorder() << " \t\t"
659 // << GetFarIntersectionWithImageBorder() << endl;
661  start[0]=(unsigned int)rint(GetCloseIntersectionWithImageBorder()[0]/
663  start[1]=(unsigned int)rint(GetCloseIntersectionWithImageBorder()[1]/
665  } else {
666  start[0]=(unsigned int)rint(Epipole_[0]/Epipole_[2]);
667  start[1]=(unsigned int)rint(Epipole_[1]/Epipole_[2]);
668  ImageDraw<PixelType>::RectangleCenter(im, start, 5,color);
669  }
670 
672  end[0]=(unsigned int)rint(GetFarIntersectionWithImageBorder()[0]/
674  end[1]=(unsigned int)rint(GetFarIntersectionWithImageBorder()[1]/
676  } else {
677  end[0]=(unsigned int)rint(PInfinity_[0]/PInfinity_[2]);
678  end[1]=(unsigned int)rint(PInfinity_[1]/PInfinity_[2]);
679  ImageDraw<PixelType>::RectangleCenter(im, end, 5,color);
680  }
681  //cerr<<"start"<<start[0]<<" "<<start[1]<<" end: "<<end[0]<<" "<<end[1]<<endl;
682  ImageDraw<PixelType>::Line(im, start, end,color);
683 }
684 
685 template <class PixelType>
687 {
690 
691  if (!im.IsPositionInImage(int(rint( CloseIntersection_[0])),
692  int(rint( CloseIntersection_[1])))) {
693  BIASERR("close intersection not in image: "<<CloseIntersection_);
694  return;
695  }
696  if (!im.IsPositionInImage(int(rint( FarIntersection_[0])),
697  int(rint( FarIntersection_[1])))) {
698  BIASERR("far intersection not in image: "<<FarIntersection_);
699  return;
700  }
701 
702  unsigned int start[2], end[2];
703  start[0] = (unsigned int)rint( CloseIntersection_[0]);
704  start[1] = (unsigned int)rint( CloseIntersection_[1]);
705  end[0] = (unsigned int)rint( FarIntersection_[0]);
706  end[1] = (unsigned int)rint( FarIntersection_[1]);
707  ImageDraw<PixelType>::Line(im, start, end);
708 }
709 
710 template <class PixelType>
711 void EpipolarLine::
712 DrawDistortedLine(const Vector3<double>& epipoleRayOrigImage,
713  const Vector3<double>& infRayOrigImage,
714  Image<PixelType>& image,
715  ProjectionParametersBase* paramsOrig,
716  PixelType* Color,
717  int lineWidth) {
718 
719  unsigned int width(0), height(0);
720  paramsOrig->GetImageSize(width, height);
721 
722  // need 5 cubefaces for cameras which dont have a too large field of view
723  // (<270degrees), will use only one for perspective cams
724  unsigned int numbercubefaces = 6;
725 
726  ProjectionParametersPerspective* paramsPersp =
727  dynamic_cast<ProjectionParametersPerspective* >(paramsOrig);
728  // check if we have a perspective camera, otherwise forward-cube-map
729  // epipolar lines
730 
731  // have to compute cube-map and forward-map cub-faces into image
732  // with ideal KMatrix
734  double cubefacewidth = double(width+height)/2.0;
735  // make slightly more than 90 deg fov
736  K[0][0] = K[1][1] = cubefacewidth / 2.1;
737  K[0][2] = K[1][2] = cubefacewidth / 2.0;
738 
739  // this is only a first workaround
740  // we should really force every projectionparameters to supply
741  // a GetFakeKMatrix method and then just call base->GetFakeK
742  // for now, this is only implmented for spherical cams
744  dynamic_cast<ProjectionParametersSpherical* >(paramsOrig);
745 
746  //double minZLocal = 0.01;
747  if (paramsPersp!=NULL) {
748  // need only front face, much faster !
749  numbercubefaces = 1;
750  if (double(width)>cubefacewidth) cubefacewidth = width;
751  if (double(height)>cubefacewidth) cubefacewidth = height;
752  K = paramsPersp->GetK();
753  if (paramsPersp->IsDistorted()) {
754  BIASWARN("distortion resolution is heuristic, may get aliased epiline !");
755  // make image larger !!!
756  K[0][2] += cubefacewidth;
757  K[1][2] += cubefacewidth;
758  cubefacewidth *= 3.0;
759  }
760  //minZLocal = paramsPersp->GetMinZLocal();
761  } else if (pSphere!=NULL) {
762  K = pSphere->GetFakeKMatrix(cubefacewidth, 1, 45.1 * M_PI / 180.0);
763  }
764  paramsPersp = new ProjectionParametersPerspective;
765  paramsPersp->SetK(K);
766  paramsPersp->SetImageSize((unsigned int)(cubefacewidth),
767  (unsigned int)(cubefacewidth));
768  paramsPersp->SetMinZLocal(0/*minZLocal*/);
769 
770  for (unsigned int cubeface = 0; cubeface<numbercubefaces; cubeface++) {
771  // make cube face rotations +-90 degrees
772  Vector3<double> axis(1,0,0);
773  double angle = 0.0;
774  switch (cubeface) {
775  case 1:axis[0]=1.0; axis[1]=0.0; axis[2]=0.0; angle=M_PI/2.0; break;
776  case 2:axis[0]=1.0; axis[1]=0.0; axis[2]=0.0; angle=-M_PI/2.0; break;
777  case 3:axis[0]=0.0; axis[1]=1.0; axis[2]=0.0; angle=M_PI/2.0; break;
778  case 4:axis[0]=0.0; axis[1]=1.0; axis[2]=0.0; angle=-M_PI/2.0; break;
779  case 5:axis[0]=0.0; axis[1]=1.0; axis[2]=0.0; angle=M_PI; break;
780  }
781  RMatrix RCube(axis,angle);
782  RMatrix RCubeTransposed = RCube.Transpose();
783  paramsPersp->SetR(paramsOrig->GetR()*RCube);
784  paramsPersp->SetC(paramsOrig->GetC());
785 
786  // we have the projection of the cube face, compute geometry of epiline:
787  Vector3<double> epipoleRay = RCubeTransposed * epipoleRayOrigImage;
788  Vector3<double> infRay = RCubeTransposed * infRayOrigImage;
789 
790  HomgPoint2D epipole = paramsPersp->GetK()*epipoleRay;
791  epipole.Homogenize();
792  //HomgPoint2D epipole = paramsPersp->ProjectLocal(epipoleRay);
793  //if (epipole.NormL2()==0.0) {
794  // epipole is behind camera, compute anyway
795  //epipole = paramsPersp->ProjectLocal(-1.0 * epipoleRay);
796  //}
797 
798  HomgPoint2D pinf = paramsPersp->ProjectLocal(infRay);
799  if (pinf.NormL2()==0.0) {
800  pinf = paramsPersp->ProjectLocal(-1.0 * infRay);
801  }
802 
803 
804  EpipolarLine line(epipole.CrossProduct(pinf));
805  if (line.NormL2()<1e-10) {
806  BIASERR("Epipolar line is strange: "<<line<<" with epipole ray "
807  <<epipoleRay<<" ("<<epipole <<") and infray "<< infRay <<"("<<pinf<<")"
808  <<" at current cube side "
809  << *paramsPersp);
810  return;
811  }
812  line.Normalize();
813 
814  // get relation to image
816  epipole.DeterminePosition(int(rint(cubefacewidth)),
817  int(rint(cubefacewidth)));
818  // is line in image ?
819  if (line.Recalc(int(rint(cubefacewidth)), int(rint(cubefacewidth)),
820  epipole, epos)!=0) {
821  BIASWARN("Epipolar line is not in image");
822  continue;
823  }
824  // get start and end point of line in image
825  int start[2], end[2];
826  start[0] =
827  (int)rint(line.GetCloseIntersectionWithImageBorder()[0]);
828  start[1] =
829  (int)rint(line.GetCloseIntersectionWithImageBorder()[1]);
830  end[0] =
831  (int)rint(line.GetFarIntersectionWithImageBorder()[0]);
832  end[1] =
833  (int)rint(line.GetFarIntersectionWithImageBorder()[1]);
834 
835 
836  // paint the pixels using forward mapping
837  int next[2]={start[0],start[1]};
838  Bresenham bres(start, end);
839  bool lastPixelValid = false;
840  int lastPixel[2];
841 
842  PixelType *color = new PixelType [image.GetChannelCount()], *mycolor=NULL;
843  for (unsigned int c=0; c<image.GetChannelCount(); c++)
844  color[c] = PixelType(255);
845 
846  // if no color, draw in white
847  if (Color==NULL)
848  mycolor = color;
849  else mycolor = Color;
850 
851  double linefac = sqrt(line[0]* line[0]+ line[1]*line[1]);
852  if (linefac<1e-8) linefac = 1;
853  else linefac = 1.0/linefac;
854  while (bres.GetNext(next)) {
855  // next grid pixel on cube face
856  HomgPoint2D point(next[0], next[1], 1.0);
857  // compute distance from mathematical epipolar line (discretized grid)
858  double dist = linefac * point.ScalarProduct(line);
859  // project point onto line, get subpixel coordinates
860  point[0] -= dist * linefac * line[0];
861  point[1] -= dist * linefac * line[1];
862 
863  // compute ray in space
864  Vector3<double> pos, ray;
865  paramsPersp->UnProjectToRay(point, pos, ray);
866  // check if this ray is visible in the orig image
867  if (paramsOrig->DoesPointProjectIntoImage(HomgPoint3D(paramsOrig->GetC()
868  + ray), point)) {
869  // it is within the calibrated area
870  int thisPixel[2];
871  thisPixel[0] = (int)(rint(point[0]));
872  thisPixel[1] = (int)(rint(point[1]));
873  // is it also within the image ?
874  if (image.IsPositionInImage(thisPixel[0],thisPixel[1])) {
875  // make just a point or connect from last point (nicer line)
876  if (lastPixelValid) {
877  // connect neigboring pixels
878  ImageDraw<PixelType>::Line(image, lastPixel, thisPixel, mycolor, lineWidth);
879  } else {
880  // last one was invalid, just mark a pixel
881  for (unsigned int c=0; c<image.GetChannelCount(); c++) {
882  image.SetPixel(mycolor[c], thisPixel[0], thisPixel[1], c);
883  }
884  }
885  // remember this pixel for next line
886  lastPixel[0] = thisPixel[0];
887  lastPixel[1] = thisPixel[1];
888  lastPixelValid = true;
889  } else {
890  // cannot draw this one ...
891  lastPixelValid = false;
892  }
893  }
894  else {
895  // it is not within the viewing frustum
896  lastPixelValid = false;
897  }
898  } // end while
899  delete [] color;
900  }
901  delete paramsPersp;
902  paramsPersp = NULL;
903 }
904 
905 
906 template <class PixelType>
908  Image<PixelType> &thisIm,
909  const Vector3<double>& otherCamCenter,
910  const Vector3<double>& RayDir,
911  PixelType* Color,
912  int lineWidth) {
913  ProjectionParametersBase* paramsOrig =
914  const_cast<ProjectionParametersBase*>(thisP.GetParameters());
915 
916  HomgPoint3D PointAtInfinity(RayDir);
917  PointAtInfinity[3] = 0.0;
918  cout<<"EpipolarLine::Point at infinity is "<<PointAtInfinity<<endl;
919 
920  // get end of epipolar line
921  HomgPoint2D infPointOrigImage(0,0,0);
922  if (thisP.DoesPointProjectIntoImage(PointAtInfinity,
923  infPointOrigImage)) {
924  infPointOrigImage.Homogenize();
925  // show point transferred with H_inf
927  int(rint(infPointOrigImage[0])),
928  int(rint(infPointOrigImage[1])),
929  2);
930  } else {
931  cout<<"EpipolarLine::Point at infinity does not project into image 2:"<<endl;
932  }
933  HomgPoint2D infRayOrigImage = paramsOrig->GetExternals()*PointAtInfinity;
934  if (infRayOrigImage.NormL2()<1e-10) {
935  BIASERR("invalid point"<<PointAtInfinity);
936  return;
937  }
938  infRayOrigImage.Normalize();
939 
940  // check if we really have camera translation
941  bool onlyHomography = (otherCamCenter-thisP.GetC()).NormL2()<1e-5;
942 
943 
944  // get start of epipolar line
945  if (!onlyHomography){
946  // compute epipoles in big image
947  HomgPoint2D epipoleOrigImage(0,0,0);
948  if (thisP.DoesPointProjectIntoImage(HomgPoint3D(otherCamCenter),
949  epipoleOrigImage)) {
950  // draw "bold" circle at epipole
951  PixelType Value[3];
952  Value[0] = PixelType(255);
953  Value[1] = PixelType(255);
954  Value[2] = PixelType(255);
956  int(rint(epipoleOrigImage[0])),
957  int(rint(epipoleOrigImage[1])),
958  5, Value);
960  int(rint(epipoleOrigImage[0])),
961  int(rint(epipoleOrigImage[1])),
962  6, Value);
963  }
964  HomgPoint2D epipoleRayOrigImage =
965  paramsOrig->GetExternals() * HomgPoint3D(otherCamCenter);
966  // must be possible, because not same camera center :
967  epipoleRayOrigImage.Normalize();
968 
969  // compute the projection of the epipolar plane for that point
970  EpipolarLine eline = epipoleRayOrigImage.CrossProduct(infRayOrigImage);
971  if (eline.NormL2()>1e-10) {
972  cout<<"Drawing distorted line"<<endl;
973  DrawDistortedLine(epipoleRayOrigImage, infRayOrigImage,
974  thisIm, paramsOrig, Color, lineWidth);
975  } else {
976  cout<<"epipole dir and ray dir coincident !"<<endl;
977  }
978  } else {
979  BIASERR("pure homography. no epiline.");
980  }
981 
982 }
983 
984 #define INSTANCE(type) \
985 template void BIASGeometry_EXPORT EpipolarLine::Draw<type>(Image<type>& im);\
986 template void BIASGeometry_EXPORT EpipolarLine::DrawWhole<type>(Image<type>& im); \
987 template void BIASGeometry_EXPORT EpipolarLine::ProjectEpipolarPlane<type>(const Projection& \
988  thisP, \
989  Image<type> &thisIm, \
990  const Vector3<double>& \
991  otherCamCenter, \
992  const Vector3<double>& \
993  RayDir, type* color, int lineWidth); \
994  template void BIASGeometry_EXPORT EpipolarLine::DrawDistortedLine<type>(const Vector3<double>& epipoleRayOrigImage, const Vector3<double>& infRayOrigImage, Image<type>& image, ProjectionParametersBase* paramsOrig, type* color, int lineWidth);
995 
996 INSTANCE(unsigned char)
997 INSTANCE(float)
998 
999 #ifdef BUILD_IMAGE_CHAR
1000 INSTANCE(char)
1001 #endif
1002 #ifdef BUILD_IMAGE_DOUBLE
1003 INSTANCE(double)
1004 #endif
1005 #ifdef BUILD_IMAGE_UINT
1006 INSTANCE(unsigned int)
1007 #endif
1008 #ifdef BUILD_IMAGE_INT
1009 INSTANCE(int)
1010 #endif
1011 #ifdef BUILD_IMAGE_SHORT
1012 INSTANCE(short)
1013 #endif
1014 #ifdef BUILD_IMAGE_USHORT
1015 INSTANCE(unsigned short)
1016 #endif
1017 
1018 
1019 
virtual BIAS::Vector3< double > GetC() const
Get projection center.
virtual HomgPoint2D ProjectLocal(const Vector3< double > &point, bool IgnoreDistortion=false) const
calculates the projection of a point in the camera coordinate system to a pixel in the image plane of...
double minx_
int Width_; // width of image int Height_; // height of image image borders in xdir, typically 0, width-1
virtual HomgPoint2D & GetFarIntersectionWithImageBorder()
HomgPoint2D FarIntersection_
void Transform(enum TLineType &type, HomgPoint2D &Original, HomgPoint2D &Transformed)
transforms Original according to type in a way that Transformed lies on a line with slope in [0...
HomgPoint2D Epipole_
class HomgPoint2D describes a point with 2 degrees of freedom in projective coordinates.
Definition: HomgPoint2D.hh:67
virtual enum TEdge GetFarEdge() const
HOMGLINE2D_TYPE data_[VECTOR3_SIZE]
Definition: Vector3.hh:514
enum EPosition DeterminePosition(unsigned int width, unsigned int height)
Definition: HomgPoint2D.hh:403
Used in function DetermineStartEnd_.
enum HomgPoint2D::EPosition EpipolePosition_
virtual void SetR(const BIAS::RMatrix &R)
Set orientation from rotation matrix R.
virtual void Init(const double &minx, const double &miny, const double &maxx, const double &maxy, HomgPoint2D &epipole, HomgPoint2D &otherpoint, enum HomgPoint2D::EPosition epos)
camera parameters which define the mapping between rays in the camera coordinate system and pixels in...
bool IsPositionInImage(const int &x, const int &y) const
check if image contains that pixel position
Definition: ImageBase.hh:110
void ScalarProduct(const Vector3< T > &argvec, T &result) const
scalar product (=inner product) of two vectors, storing the result in result
Definition: Vector3.hh:603
virtual BIAS::Matrix3x4< double > GetExternals() const
Return cached 3x4 representation of external matrix [R|C].
virtual void SetImageSize(const unsigned int w, const unsigned int h)
Set image dimensions (in pixels).
HomgPoint2D & Homogenize()
homogenize class data member elements to W==1 by divison by W
Definition: HomgPoint2D.hh:215
double GetDy() const
void SetMinZLocal(const double &minz)
sets minimum z value of unit-ray in local CCS to be accepted as in front of camera (e...
virtual BIAS::KMatrix GetFakeKMatrix(double &imgsize, int resolution=0, const double &maxangle=1.4) const
Returns a fake KMatrix for the fisheye camera.
virtual bool DoesPointProjectIntoImage(const HomgPoint3D &X, HomgPoint2D &x, bool IgnoreDistortion=false) const
Checks if 3D point projects into specified image and returns belonging 2D image point.
HomgPoint2D CloseIntersection_
unsigned int GetWidth() const
Definition: ImageBase.hh:312
virtual void UnProjectToRay(const HomgPoint2D &pos, Vector3< double > &origin, Vector3< double > &direction, bool ignoreDistortion=false) const
Calculates the view ray, which belongs to the given position on the image plane, in global coordinate...
void GetImageBoundaries(double &minx, double &miny, double &maxx, double &maxy) const
double GetAngle() const
angle to abszissa (-pi, pi]
static int CircleCenter(Image< StorageType > &im, unsigned int CenterX, unsigned int CenterY, unsigned int Radius, const StorageType Value[]=NULL)
draws a circular line, either using Value or a good contrast value
Definition: ImageDraw.cpp:977
3D rotation matrix
Definition: RMatrix.hh:49
void InverseTransform(enum TLineType &type, HomgPoint2D &Transformed, HomgPoint2D &Original)
executes the inverse transformation to the above
virtual double GetRMax() const
distance epipole - far intersection with image border
void DrawWhole(Image< PixelType > &im)
draws infinite line in image, not stopping at epipole
double miny_
image borders in xdir, typically 0, height-1
void CrossProduct(const Vector3< T > &argvec, Vector3< T > &destvec) const
cross product of two vectors destvec = this x argvec
Definition: Vector3.hh:594
const ProjectionParametersBase * GetParameters(unsigned int cam=0) const
const parameter access function
Definition: Projection.hh:194
static int Line(Image< StorageType > &im, const unsigned int start[2], const unsigned int end[2], const StorageType value[])
lines
Definition: ImageDraw.cpp:404
This class hides the underlying projection model, like projection matrix, spherical camera...
Definition: Projection.hh:70
HomgPoint2D PInfinity_
void Intersection(const HomgLine2D &line, HomgPoint2D &intersect) const
calculates homogenized intersection of two lines
Definition: HomgLine2D.hh:180
unsigned int GetChannelCount() const
returns the number of Color channels, e.g.
Definition: ImageBase.hh:382
HomgPoint2D Start_
unsigned int GetHeight() const
Definition: ImageBase.hh:319
virtual BIAS::RMatrix GetR() const
Get orientation as rotation matrix R.
bool GetNext(int next[2])
Definition: Bresenham.hh:185
enum TLineType DetermineLineType(double &angle)
EightWaySymmetryHomg Sym_
unsigned int Length_
void Draw(Image< PixelType > &im)
draws (*this) into image (only from Pinf to epipole
virtual enum TEdge GetCloseEdge() const
double GetDx() const
a line l = (a b c)^T is a form of the implicit straight line equation 0 = a*x + b*y + c if homogenize...
Definition: HomgLine2D.hh:48
virtual void GetNextLine(bool clockwise, EpipolarLine &next, double dist=1.0)
returns next line with maximal possible distance without pixel loss
void Homogenize()
aequivalent to homogenize for points the gradient triangle is normed to hypothenuse length of 1 ...
Definition: HomgLine2D.hh:149
camera parameters which define the mapping between rays in the camera coordinate system and pixels in...
class HomgPoint3D describes a point with 3 degrees of freedom in projective coordinates.
Definition: HomgPoint3D.hh:61
virtual double ScanLine_(Image< unsigned char > &source, unsigned int ROffset, unsigned int &length, unsigned char *Destination, bool forward)
std::ostream & operator<<(std::ostream &os, const Array2D< T > &arg)
Definition: Array2D.hh:260
virtual bool DoesPointProjectIntoImage(const BIAS::HomgPoint3D &X, BIAS::HomgPoint2D &x, unsigned int cam=0, bool IgnoreDistortion=false) const
Checks if 3D point projects into specified image and returns belonging 2D image point.
Definition: Projection.cpp:300
void SetPixel(const StorageType &value, const unsigned int &x, const unsigned int &y, const unsigned short int channel=0)
Set the value of a given pixel (x,y) in channel to value.
Definition: Image.hh:171
static int RectangleCenter(Image< StorageType > &im, const int x, const int y, const int size, const StorageType value[])
Draws the rectangle around X, Y with Size and Value[i] in channel i.
Definition: ImageDraw.cpp:284
HomgPoint2D TransformedStart_
virtual int GetImageSize(unsigned int &Width, unsigned int &Height) const
Obtain image dimensions.
virtual HomgPoint2D & GetEpipole()
Definition: EpipolarLine.hh:87
unsigned int ROffset_
Matrix3x3< T > Transpose() const
returns transposed matrix tested 12.06.2002
Definition: Matrix3x3.cpp:167
static void DrawDistortedLine(const Vector3< double > &epipoleRayOrigImage, const Vector3< double > &infRayOrigImage, Image< PixelType > &image, ProjectionParametersBase *paramsOrig, PixelType *Color=NULL, int lineWidth=1)
project the plane given by two local rays and the camera center into the image (ANY projection) using...
virtual double GetRMin() const
distance epipole - close intersection with image border
bool DetermineIntersectionsAndEpipoleDistances_(HomgPoint2D &point)
virtual HomgPoint2D GetCopyOfEpipole() const
Definition: EpipolarLine.hh:90
static void ProjectEpipolarPlane(const Projection &thisP, Image< PixelType > &thisIm, const Vector3< double > &otherCamCenter, const Vector3< double > &RayDir, PixelType *Color=NULL, int lineWidth=1)
visualize the epipolar plane/line as a curve in the image for any Projection
K describes the mapping from world coordinates (wcs) to pixel coordinates (pcs).
Definition: KMatrix.hh:48
Scans a line using Bresenhams integer arithmetic algorithm.
Definition: Bresenham.hh:42
enum HomgPoint2D::EPosition PInfinityPosition_
virtual double ScanLine(Image< unsigned char > &source, HomgPoint2D &epipole, enum HomgPoint2D::EPosition epos, double RMin, double RMax, bool forward, unsigned int &length, unsigned char *Destination)
scans epipolar line using bresenham, midpint alg.
BIAS::HomgPoint2D Point
virtual HomgPoint2D GetCopyOfFarIntersectionWithImageBorder() const
virtual enum HomgPoint2D::EPosition GetEpipolePosition() const
virtual void CalcTransformed_()
HomgPoint2D Current_
virtual EpipolarLine & operator=(const EpipolarLine &line)
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
int Recalc()
assumes Width, Height_, data_ and Epipole_ are set correct before
enum TEdge FarEdge_ CloseEdge_
HOMGLINE2D_TYPEconst * end() const
Iterator pointing to one element after the last vector element.
Definition: Vector3.hh:143
Vector3< double > GetC(unsigned int cam=0) const
return Center of camera with index cam.
Definition: Projection.hh:236
virtual void SetK(const KMatrix &K)
sets the internal parameters from a given KMatrix and updates the cached K and its inverse ...
virtual void SetC(const BIAS::Vector3< double > &C)
Set projection center.
Vector3< T > & Normalize()
normalize this vector to length 1
Definition: Vector3.hh:663
virtual HomgPoint2D & GetCloseIntersectionWithImageBorder()
virtual void Interpolate_(enum TLineType &type, unsigned char **ida, int &x, int &y, double &g, unsigned char &result)
HomgPoint2D TransformedCurrent_
double NormL2() const
the L2 norm sqrt(a^2 + b^2 + c^2)
Definition: Vector3.hh:633
TLineType
direction of line if start is in coordinate origin as given by compass
HomgPoint2D TransformedEnd_
class BIASGeometryBase_EXPORT HomgPoint3D
enum TLineType GetLineType() const
return type, E_NE if 0 &lt; slope &lt; 45 degree NE_N if 45 &lt; slop &lt; 90 ...
Definition: EpipolarLine.hh:96
virtual HomgPoint2D GetCopyOfCloseIntersectionWithImageBorder() const
enum TLineType Type_
A class for representing epipolar lines with useful functions like ScanLine().
Definition: EpipolarLine.hh:69
double BilinearInterpolationGrey(const double x, const double y) const
Bilinear interpolation for grey-value images.
Definition: Image.hh:287