Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
biasrectify.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 <iostream>
26 #include <Base/Image/ImageIO.hh>
27 #include <Image/Camera.hh>
28 #include <Image/PlanarRectification.hh>
29 #include <Image/CylindricalRectification.hh>
30 #include <Image/SphericalRectification.hh>
31 #include <Image/RectificationBase.hh>
32 #include <Utils/Param.hh>
33 #include <Utils/ThreeDOut.hh>
34 #include <Base/Image/ImageConvert.hh>
35 
36 using namespace std;
37 using namespace BIAS;
38 
39 //#define OutStorageType float
40 #define OutStorageType unsigned char
41 
42 /**
43  @file
44  @ingroup g_tools
45  @brief Tool for rectifying images, see biasrectify.cpp
46  @author bartczak
47 */
48 
49 int findLargestOverlappingRegion(const ProjectionParametersBase *camAproj,
50  const ProjectionParametersBase *camBproj,
51  const ProjectionParametersBase *rectAproj,
52  const ProjectionParametersBase *rectBproj, ROI &roi);
53 
54 int
55 findLargestOverlappingRegion(ProjectionParametersBase* camAproj,
56  ProjectionParametersBase* camBproj,
59  const double* zeroParallaxZ, ROI& roiA, ROI& roiB,
60  bool verbose = false);
61 
62 int findLargestRectangularRegion(const ProjectionParametersBase *camProj,
63  const ProjectionParametersBase *rectProj, ROI& roi);
64 
65 double CalculateRescaleFactor(int targetWidth, int targetHeight, int roiWidth,
66  int roiHeight);
67 
68 void CentralCropRoi(int targetWidth, int targetHeight, ROI& roi);
69 
70 
71 int main(int argc, char* argv[]) {
72  Param params(true);
73 
74  //GROUP Misc.
75  int groupID = params.GetFreeGroupID();
76  bool* help = params.AddParamBool("help", "", false, 'h', groupID);
77  params.SetGroupName(groupID, "Misc.");
78 
79  //GROUP 3D visualisation
80  groupID = params.GetFreeGroupID();
81  bool* vrml = params.AddParamBool("writeVrml",
82  "write out vrml with rect geometry", false, 0, groupID);
83  bool* pointsonly = params.AddParamBool("pointsonly",
84  "dont use texture,but colored vertices", false, 0, groupID);
85  params.SetGroupName(groupID, "3D Visualisation");
86 
87  //GROUP Main Settings
88  groupID = params.GetFreeGroupID();
89  enum {
90  cylindrical = 0, spherical, planar, planarKeepAspect
91  }; // rectTypeID;
92  vector<string> rectificationTypes;
93  rectificationTypes.push_back("cylindrical");//0
94  rectificationTypes.push_back("spherical"); //1
95  rectificationTypes.push_back("planar"); //2
96  rectificationTypes.push_back("planarKeepAspect"); //3
97  int* rectType = params.AddParamEnum("type",
98  "what kind of rectification shall be performed?:"
99  " [cylindrical], spherical, planar, planarKeepAspect",
100  rectificationTypes, 0, NULL, 0, groupID);
101 
102  enum {
103  Trilinear = 0, Bilinear
104  };
105  vector<string> interpolationType;
106  interpolationType.push_back("Trilinear");//0
107  interpolationType.push_back("Bilinear");//1
108  int* interType = params.AddParamEnum("interpolation",
109  "what kind of interpolation shall be performed?:"
110  " [Trilinear], Bilinear", interpolationType, 0, NULL, 0,
111  groupID);
112 
113  double* rescale = params.AddParamDouble("rescale",
114  "scales the resolution of rectified images", 0.8, 0.001, DBL_MAX,
115  0, groupID);
116 
117  bool* useLUT = params.AddParamBool("useLUT",
118  "turn off the use of look up tables", false, 0, groupID);
119 
120  params.SetGroupName(groupID, "Main Settings");
121 
122  //GROUP Cropping
123  groupID = params.GetFreeGroupID();
124 
125  // int* destHeight =
126  // params.AddParamInt("destHeight",
127  // "height of overlapping view from both cameras, if set, resolution is calculated.",
128  // -1, -1, 10000, 0, groupID);
129 
130  // int* destWidth =
131  // params.AddParamInt("destWidth",
132  // "width of overlapping view from both cameras, if set, resolution is calculated.",
133  // -1, -1, 10000, 0, groupID);
134 
136  * targetResolution =
137  params.AddParamVecInt(
138  "targetResolution",
139  "Give the resolution of the fully filled rectangle in the rectified images, "
140  "that shall be possible to crop."
141  " If both components are negative, this feature is disabled, using the rescale parameter."
142  " If one component is above 0 the parameter rescale is not used.",
143  "-1 -1", 0, groupID);
144 
145  bool* cropImages = params.AddParamBool("crop",
146  "if target resolution is given, crop resulting images to these values. "
147  "Delivers the cropped results as output.", false, 0, groupID);
148 
149  double
150  * zeroParallaxZ =
151  params.AddParamDouble(
152  "zeroParallaxZ",
153  "give the zero parallax z-distance in rectified space. "
154  "From this the cropping and rescale parameters can be adapted. "
155  "A value below zero indicates infinity! Only works with planar rectification.",
156  -1, -1, DBL_MAX, 0, groupID);
157 
158  string
159  * cropInformationFile =
160  params.AddParamString(
161  "cropInfo",
162  "writes the information to be used for cropping after rectification into this text file.",
163  "", 0, groupID);
164 
165  bool
166  * writeOutCropParams =
167  params.AddParamBool(
168  "writeCroppedCamParams",
169  "If this is active no cropping is performed. "
170  "Only the camera parameters fitting the cropped, rectified images are written out.",
171  false, 0, groupID);
172 
173  params.SetGroupName(groupID, "Cropping");
174 
175  //GROUP Cropping
176  groupID = params.GetFreeGroupID();
177 
178  string* leftList = params.AddParamString("leftList", "leftImagesList", "",
179  0, groupID);
180  string* rightList = params.AddParamString("rightList", "leftImagesList",
181  "", 0, groupID);
182 
183  string* leftCamParams = params.AddParamString("leftCamParams",
184  "left camera Params", "", 0, groupID);
185 
186  string* rightCamParams = params.AddParamString("rightCamParams",
187  "left camera Params", "", 0, groupID);
188 
189  string* outdir = params.AddParamString("outputDir", "output directory",
190  ".", 0, groupID);
191 
192  bool* keepType = params.AddParamBool("keepType", "keep filetype of image",
193  false, 0, groupID);
194 
195  string* newType = params.AddParamString("newType", "new image type", "png",
196  0, groupID);
197 
198  bool* writeRectParams = params.AddParamBool("writeRectParams",
199  "write out rectified camera parameters", false, 0, groupID);
200 
201  int* bordercolor2 = params.AddParamInt("borderSecond",
202  "color of border in second view", 255, 0, 255, 0, groupID);
203 
204  string* rectSetupName = params.AddParamString("rectSetup",
205  "file that contains or shall contain the rect setup", "", 0,
206  groupID);
207 
208  bool* forceModulo4size = params.AddParamBool("forceModulo4size",
209  "Result images are extended "
210  "at the lower and/or right edges to fit into modulo 4 size."
211  "!) Camera parameters are adapted accordingly."
212  "!) Feature is disabled if crop is true.", false, 0, groupID);
213 
214  params.SetGroupName(groupID, "I/O");
215 
216  int fup = params.ParseCommandLine(argc, argv);
217 
218  if (*help) {
219  cout << "\nusage:\n";
220  cout << argv[0] << " [options] <origImgA> <origImgB>\n";
221  params.Usage();
222  return 0;
223  }
224 
225  if (*cropImages && *writeOutCropParams) {
226  cout << "crop and writeCroppedCamParams are both active!\n";
227  cout << "writeCroppedCamParams is ambiguouse when crop is active!\n";
228  cout << "Turn one option off!\n";
229  return -1;
230  }
231 
232  Camera<unsigned char> RGBcamA, camA, RGBcamB, camB;
233 
234  // if(leftList->empty() && rightList->empty() ) {
235 
236  // if(ImageIO::Load(argv[fup], camA)!=0) {
237  // cerr<<"unable to load first camera\n";
238  // return -1;
239  // }
240 
241  // if(ImageIO::Load(argv[fup+1], camB)!=0) {
242  // cerr<<"unable to second first camera\n";
243  // return -1;
244  // }
245  // }
246 
247  Camera<float> rectSetup;
248  bool useSetup = false;
249  bool generateSetup = false;
250  if (rectSetupName->size() > 0) {
251  useSetup = true;
252  if (ImageIO::Load(*rectSetupName, rectSetup) < 0) {
253  cerr << "could not open rectified setup file " << *rectSetupName
254  << endl;
255  cerr << "will create it from given params .\n";
256  generateSetup = true;
257  }
258  }
259  // camA.ParseMetaData();
260  // camB.ParseMetaData();
261 
264  * rectifierPM = NULL;
265 
266  //choose different rectification at this point
267  switch (*rectType) {
268  case cylindrical:
269  rectifier = rectifierPM = new CylindricalRectification<unsigned char,
270  OutStorageType> (1.3);
271  break;
272  case spherical:
273  rectifier = rectifierPM = new SphericalRectification<unsigned char,
274  OutStorageType> ();
275  break;
276  case planar:
277  rectifier = rectifierPM = new PlanarRectification<unsigned char,
278  OutStorageType> ();
279  break;
280  case planarKeepAspect: {
281  cout << "Using planar rectification with preserved aspectratio" << endl;
283  rectifier = rectifierPM = rectifierPlanar = new PlanarRectification<
284  unsigned char, OutStorageType> ();
285  rectifierPlanar->RetainOriginalApectRatio();
286  }
287  break;
288  default:
289  cerr << " unknown rectification type : "
290  << rectificationTypes[*rectType] << endl;
291  return -1;
292  break;
293  }
294 
295  switch (*interType) {
296  case Trilinear:
297  rectifierPM->SetInterpolationMethod(MapTrilinear);
298  break;
299  case Bilinear:
300  rectifierPM->SetInterpolationMethod(MapBilinear);
301  break;
302  }
303 
304  int destWidth = (*targetResolution)[0];
305  int destHeight = (*targetResolution)[1];
306 
307  if (destHeight > 0 || destWidth > 0) {
308  *rescale = 1.0f;
309  } else {
310  if (*cropImages) {
311  cout
312  << "cropping requested but no destination image dimensions set. disabling crop"
313  << endl;
314  *cropImages = false;
315  }
316  }
317 
318  rectifierPM->UseLookUpTables(*useLUT);
319  rectifierPM->SetScale(*rescale);
320  rectifierPM->SetSecondFill((unsigned char)(*bordercolor2));
321 
322  unsigned int imageNum;
323  vector<string> leftImageNames;
324  vector<string> rightImageNames;
325  if (leftList->empty() && rightList->empty()) {
326  imageNum = 1;
327  if (fup + 1 >= argc) {
328  cout << "You must specify image list files with --leftList and --rightList " << endl
329  << "or two image file names as parameters!" << endl;
330  return 0;
331  }
332  leftImageNames.push_back(argv[fup]);
333  rightImageNames.push_back(argv[fup + 1]);
334  } else {
335  if (Param::ParseListFile(*leftList, leftImageNames) != 0) {
336  BIASERR("error parsing left list");
337  return -1;
338  }
339  if (Param::ParseListFile(*rightList, rightImageNames) != 0) {
340  BIASERR("error parsing right list");
341  return -1;
342  }
343  imageNum = leftImageNames.size();
344  BIASASSERT(imageNum == rightImageNames.size());
345  }
346 
347  Projection camAproj, camBproj;
348  if (!leftCamParams->empty()) {
349  if (camAproj.Load(*leftCamParams) != 0) {
350  BIASERR("error reading left camera parameters");
351  }
352  }
353  if (!rightCamParams->empty()) {
354  if (camBproj.Load(*rightCamParams) != 0) {
355  BIASERR("error reading right camera parameters");
356  }
357  }
358 
359  ProjectionParametersBase* rectPPA = NULL;
360  ProjectionParametersBase* rectPPB = NULL;
361 
362  // roi for max overlapping view
363  ROI roi;
364 
365  for (unsigned int i = 0; i < imageNum; i++) {
366 
367  //load image data
368  if (ImageIO::Load(leftImageNames[i], camA) != 0) {
369  cerr << "unable to load first camera '" << leftImageNames[i] << "'"
370  << endl;
371  return -1;
372  }
373 
374  if (ImageIO::Load(rightImageNames[i], camB) != 0) {
375  cerr << "unable to load second camera '" << rightImageNames[i] << "'"
376  << endl;
377  return -1;
378  }
379 
380  //set the parameters ?
381  if (leftCamParams->empty() && i == 0) {
382  camA.ParseMetaData();
383  if (!camA.IsProjValid()) {
384  BIASERR("right camera projection not specified in image!");
385  return -1;
386  }
387  camAproj = camA.GetProj();
388 
389  }
390  if (rightCamParams->empty() && i == 0) {
391  camB.ParseMetaData();
392  if (!camB.IsProjValid()) {
393  BIASERR("right camera projection not specified in image!");
394  return -1;
395  }
396  camBproj = camB.GetProj();
397  }
398 
399  if (rectifier->SetCameraA(camA, camAproj.GetParameters()) < 0) {
400  cerr << "invalid camera type for camera A!\n";
401  delete rectifier;
402  return -1;
403  }
404 
405  if (rectifier->SetCameraB(camB, camBproj.GetParameters()) < 0) {
406  cerr << "invalid camera type for camera B!\n";
407  delete rectifier;
408  return -1;
409  }
410 
411  if (useSetup && i == 0) {
412  if (generateSetup) {
413  if (rectifierPM->GetRectificationSetup(rectSetup) < 0) {
414  cerr << "rectification setup could not be created!\n";
415  return -1;
416  }
417  //if (ImageIO::Write(*rectSetupName, rectSetup) < 0) {
418  if (ImageIO::Save(*rectSetupName, rectSetup) < 0) {
419  cerr << "error writing rectification setup into "
420  << *rectSetupName << endl;
421  return -1;
422  }
423  } else {
424  if (rectifierPM->SetRectificationSetup(rectSetup) < 0) {
425  cerr << "rectification setup could not be loaded!\n";
426  return -1;
427  }
428  }
429  }
430 
431  if (i == 0) {
432 
433  if (rectifierPM->GetClonesOfRectificationParameters(rectPPA,
434  rectPPB) != 0) {
435  cerr << "rectification parameters could not be retrieved!\n";
436  delete rectifier;
437  return -1;
438  }
439 
440  /* cout<<"Initial rectification parameters : \n";
441  cout<<"CamA :\n";
442  cout<<*rectPPA<<endl;
443  cout<<"CamB :\n";
444  cout<<*rectPPB<<endl;*/
445 
446  if ((destHeight > 0 || destWidth > 0)) {
447  if ((*rectType != planar && *rectType != planarKeepAspect)) {
448  BIASERR(
449  "cropping is only valid for planarily rectified images!");
450  return -1;
451  }
452  // falko's reference code:
453  //
454  // findLargestOverlappingRegion(camAproj.GetParameters(), camBproj.GetParameters(), rectPPA, rectPPB, roi);
455  // double scaleH = 0;
456  // double scaleW = 0;
457  // int roiheight = roi.GetCornerLowerRightY() - roi.GetCornerUpperLeftY();
458  // int roiwidth = roi.GetCornerLowerRightX() - roi.GetCornerUpperLeftX();
459  // if (destHeight > 0)
460  // scaleH = float(destHeight) / roiheight;
461  // if (destWidth > 0 )
462  // scaleW = float(destWidth) / roiwidth;
463  // double scale = (scaleW > scaleH) ? scaleW : scaleH;
464  // rectifierPM->SetScale(scale);
465  // rectifierPM->GetClonesOfRectificationParameters(rectPPA, rectPPB);
466  // findLargestOverlappingRegion(camAproj.GetParameters(), camBproj.GetParameters(), rectPPA, rectPPB, roi);
467  // roiheight = roi.GetCornerLowerRightY() - roi.GetCornerUpperLeftY();
468  // roiwidth = roi.GetCornerLowerRightX() - roi.GetCornerUpperLeftX();
469  // // adapt parameters to cut roi
470  // if (*cropImages) {
471  // double x,y;
472  // rectPPA->GetPrincipal(x,y);
473  // int xoffset = 0, yoffset = 0;
474  // if (roiwidth > destWidth) {
475  // xoffset = (roiwidth - destWidth) / 2;
476  // }
477  // if (roiheight > destHeight) {
478  // yoffset = (roiheight - destHeight) / 2;
479  // }
480  // rectPPA->SetPrincipal(x+roi.GetCornerUpperLeftX()+xoffset,y+roi.GetCornerUpperLeftY()+yoffset);
481  // rectPPA->SetImageSize(roiwidth-2*xoffset,roiheight-2*yoffset);
482  // rectPPB->GetPrincipal(x,y);
483  // rectPPB->SetPrincipal(x+roi.GetCornerUpperLeftX()+xoffset,y+roi.GetCornerUpperLeftY()+yoffset);
484  // rectPPB->SetImageSize(roiwidth-2*xoffset,roiheight-2*yoffset);
485  // roi.SetCorners(
486  // roi.GetCornerUpperLeftX()+xoffset,
487  // roi.GetCornerUpperLeftY()+yoffset,
488  // roi.GetCornerLowerRightX()-xoffset,
489  // roi.GetCornerLowerRightY()-yoffset
490  // );
491  // }
492 
493  //try to get it going with zero parallax
494  ROI roiA, roiB;
495  // cout<<"find inital rect area:\n";
496  findLargestOverlappingRegion(camAproj.GetParameters(),
497  camBproj.GetParameters(),
500  zeroParallaxZ, roiA, roiB);
501  //roiA and roiB have same width and same height
502  int roiHeight = roiA.GetCornerLowerRightY()
503  - roiA.GetCornerUpperLeftY();
504  int roiWidth = roiA.GetCornerLowerRightX()
505  - roiA.GetCornerUpperLeftX();
506 
507  double adaptedScale = CalculateRescaleFactor(destWidth,
508  destHeight, roiWidth, roiHeight);
509  cout << "rescale for cropping : " << adaptedScale << endl;
510  rectifierPM->SetScale(adaptedScale);
511 
512  rectifierPM->GetClonesOfRectificationParameters(rectPPA,
513  rectPPB);
514  // cout<<"find rect area after scale:\n";
515  findLargestOverlappingRegion(camAproj.GetParameters(),
516  camBproj.GetParameters(),
519  zeroParallaxZ, roiA, roiB, true);
520  //unsigned int adaptedWidth, adaptedHeight;
521  // rectPPB->GetImageSize(adaptedWidth, adaptedHeight);
522  // roiA.Resize(adaptedWidth, adaptedHeight);
523  // roiB.Resize(adaptedWidth, adaptedHeight);
524  // //adapt rois
525  // roiA.SetCorners(rint(adaptedScale*roiA.GetCornerUpperLeftX()),
526  // rint(adaptedScale*roiA.GetCornerUpperLeftY()),
527  // rint(adaptedScale*roiA.GetCornerLowerRightX()),
528  // rint(adaptedScale*roiA.GetCornerLowerRightY()));
529 
530  // roiB.SetCorners(rint(adaptedScale*roiB.GetCornerUpperLeftX()),
531  // rint(adaptedScale*roiB.GetCornerUpperLeftY()),
532  // rint(adaptedScale*roiB.GetCornerLowerRightX()),
533  // rint(adaptedScale*roiB.GetCornerLowerRightY()));
534 
535  /* cout<<"roiA before central crop: "<<roiA<<endl;
536  cout<<"roiB before central crop: "<<roiB<<endl;*/
537 
538  //now determine the where to crop
539  CentralCropRoi(destWidth, destHeight, roiA);
540  CentralCropRoi(destWidth, destHeight, roiB);
541 
542  /*cout<<"roiA after central crop: "<<roiA<<endl;
543  cout<<"roiB after central crop: "<<roiB<<endl;*/
544 
545  if (cropInformationFile->size() > 0) {
546  string outfileName = *outdir + "/" + *cropInformationFile;
547  //now write out the crop parameters
548  ofstream ofs(outfileName.c_str());
549  ofs << "** BIASrectify **\n"
550  << "** crop information for rectified images **\n\n";
551 
552  ofs << "---> zero parallax = " << *zeroParallaxZ
553  << " <---\n\n";
554 
555  ofs << "---> left images <---\n"
556  << "crop rect upper left ["
557  << roiA.GetCornerUpperLeftX() << ", "
558  << roiA.GetCornerUpperLeftY() << "] (included)\n"
559  << "crop rect lower right ["
560  << roiA.GetCornerLowerRightX() << ", "
561  << roiA.GetCornerLowerRightY() << "] (excluded)\n";
562  ofs << "\n\n";
563  ofs << "---> right images <---\n"
564  << "crop rect upper left ["
565  << roiB.GetCornerUpperLeftX() << ", "
566  << roiB.GetCornerUpperLeftY() << "] (included)\n"
567  << "crop rect lower right ["
568  << roiB.GetCornerLowerRightX() << ", "
569  << roiB.GetCornerLowerRightY() << "] (excluded)\n";
570 
571  ofs
572  << "\n\nATTENTION: Don't forget to adapt disaprity values if you are cropping disparity maps! \n";
573  ofs
574  << "The disparity values have to be changed by an amount of "
575  << abs(
576  static_cast<int> (roiB.GetCornerUpperLeftX())
577  - static_cast<int> (roiA.GetCornerUpperLeftX()))
578  << " disparities.\n";
579  ofs
580  << "Whether to decrease or increase disparity values, depends on the definition of disparity and on the view of the cropped disparity map!\n";
581  ofs.close();
582  }
583 
584  if (*cropImages || *writeOutCropParams) {
585  ProjectionParametersBase* rectPPATmp;
586  ProjectionParametersBase* rectPPBTmp;
587 
588  rectifierPM->GetClonesOfRectificationParameters(rectPPATmp,
589  rectPPBTmp);
590  double x, y;
591  rectPPATmp->GetPrincipal(x, y);
592  rectPPATmp->SetPrincipal(x - roiA.GetCornerUpperLeftX(), y
593  - roiA.GetCornerUpperLeftY());
594  rectPPATmp->SetImageSize(destWidth, destHeight);
595  rectPPBTmp->GetPrincipal(x, y);
596  rectPPBTmp->SetPrincipal(x - roiB.GetCornerUpperLeftX(), y
597  - roiB.GetCornerUpperLeftY());
598  rectPPBTmp->SetImageSize(destWidth, destHeight);
599 
600  if (*writeOutCropParams) {
601 #ifdef BIAS_HAVE_XML2
602  Projection(*rectPPATmp).XMLWrite(*outdir+"/camLeftRectified_cropped.xml");
603  Projection(*rectPPBTmp).XMLWrite(*outdir+"/camRightRectified_cropped.xml");
604  //cout<<"written out cropped parameters terminating. \n";
605 #else
606  BIASWARN(
607  "requested writing of camera parameters, but xml2 not enabled in BIAS");
608 #endif
609  //return 0;
610  delete rectPPATmp;
611  delete rectPPBTmp;
612  } else {
613 
615  * rectifierPlanar =
616  dynamic_cast<PlanarRectification<
617  unsigned char, OutStorageType>*> (rectifierPM);
618  rectifierPlanar->FixateIntrinsics(
619  *(ProjectionParametersPerspective*) rectPPATmp,
620  *(ProjectionParametersPerspective*) rectPPBTmp);
621  rectifierPlanar->SetScale(1.0);
622  delete rectPPA;
623  delete rectPPB;
624  rectPPA = rectPPATmp;
625  rectPPB = rectPPBTmp;
626  }
627  } // crop or write out cropped params end
628 
629  }
630 
631  cerr << "Found rectification parameters! \n ";
632  if (*forceModulo4size && !*cropImages) {
633  unsigned int width, height;
634  rectPPA->GetImageSize(width, height);
635  int missingW = width % 4;
636  int missingH = height % 4;
637  if (missingW != 0) {
638  width = width + (4 - missingW);
639  }
640  if (missingH != 0) {
641  height = height + (4 - missingH);
642  }
643  rectPPA->SetImageSize(width, height);
644  rectPPB->GetImageSize(width, height);
645  missingW = width % 4;
646  missingH = height % 4;
647  if (missingW != 0) {
648  width = width + (4 - missingW);
649  }
650  if (missingH != 0) {
651  height = height + (4 - missingH);
652  }
653  rectPPB->SetImageSize(width, height);
654  }
655  cerr << "camera A rectification state:\n" << *rectPPA << endl
656  << endl;
657  cerr << "camera B rectification state:\n" << *rectPPB << endl
658  << endl;
659  cerr << "rectifying ... " << endl;
660 
661  }//if i == 0
662  // cerr<<"."<<flush;
663 
664 
665  if (rectifier->Rectify() != 0) {
666  cerr << " failed \n";
667  delete rectifier;
668  delete rectPPA;
669  delete rectPPB;
670  return -1;
671  }
672 
673  Camera<OutStorageType> rectA, rectB, RGBrectA, RGBrectB;
674 
675  rectifier->GetRectifiedImageA(rectA);
676  // // cut to roi
677  // if (*cropImages) {
678  // rectA.SetROI(roi);
679  // rectA.Cut2ROI();
680  // } //is now integrated into the
681  if (*forceModulo4size != 0 && !*cropImages) {
682  unsigned int width, height;
683  rectPPA->GetImageSize(width, height);
684  /*int missingW = width%4;
685  int missingH = height%4;*/
686  //rectPPA->SetImageSize(width+missingW, height+missingH);
687  rectA.Pad(width, height, 0);
688  }
689  rectA.SetProj(Projection(*rectPPA));
690  rectA.UpdateMetaData();
691 
692  rectifier->GetRectifiedImageB(rectB);
693  // // cut to roi
694  // if (*cropImages) {
695  // rectB.SetROI(roi);
696  // rectB.Cut2ROI();
697  // }
698  if (*forceModulo4size != 0 && !*cropImages) {
699  unsigned int width, height;
700  rectPPB->GetImageSize(width, height);
701  /* int missingW = width%4;
702  int missingH = height%4;*/
703  // rectPPB->SetImageSize(width+missingW, height+missingH);
704  rectB.Pad(width, height, *bordercolor2);
705  }
706  rectB.SetProj(Projection(*rectPPB));
707  rectB.UpdateMetaData();
708 
709  if (*writeRectParams) {
710 #ifdef BIAS_HAVE_XML2
711  Projection(*rectPPA).XMLWrite(*outdir+"/camLeftRectified.xml");
712  Projection(*rectPPB).XMLWrite(*outdir+"/camRightRectified.xml");
713 #else
714  BIASWARN(
715  "requested writing of camera parameters, but xml2 not enabled in BIAS");
716 #endif
717  }
718 
719  string path1, basename1, suffix1;
720  string path2, basename2, suffix2;
721  FileHandling::SplitName(leftImageNames[i], path1, basename1, suffix1);
722  FileHandling::SplitName(rightImageNames[i], path2, basename2, suffix2);
723 
724  string firstName = *outdir + "/" + basename1 + "_rect";//+suffix1;
725  string secondName = *outdir + "/" + basename2 + "_rect";//+suffix2;
726 
727  if(*cropImages) {
728  firstName += "_cropped";
729  secondName += "_cropped";
730  }
731 
732  if (*keepType) {
733  if (ImageIO::Save(firstName + suffix1, rectA) != 0) {
734  cerr << "writing first rectified image failed!\n";
735  }
736  if (ImageIO::Save(secondName + suffix2, rectB) != 0) {
737  cerr << "writing first rectified image failed!\n";
738  }
739  } else {
740  if (newType->compare("") != 0) {
741  if (ImageIO::Save(firstName + "." + *newType, rectA) != 0) {
742  cerr << "writing first rectified image failed!\n";
743  }
744  if (ImageIO::Save(secondName + "." + *newType, rectB) != 0) {
745  cerr << "writing first rectified image failed!\n";
746  }
747  } else {
748  if (ImageIO::Save(firstName, rectA, ImageIO::FF_mip) != 0) {
749  cerr << "writing first rectified image failed!\n";
750  }
751  if (ImageIO::Save(secondName, rectB, ImageIO::FF_mip) != 0) {
752  cerr << "writing first rectified image failed!\n";
753  }
754  }
755  }
756 
757  if (*vrml) {
758  ThreeDOut tdo;
759  tdo.AddProjection(camA.GetProj(), RGBAuc(0, 255, 0, 255));
760  tdo.AddProjection(camB.GetProj(), RGBAuc(0, 255, 0, 255));
761 
762  // tdo.AddProjection(Projection(*rectPPA), RGBAuc(255, 0, 0, 255));
763  // tdo.AddProjection(Projection(*rectPPB), RGBAuc(255, 0, 0, 255));
764  cerr << "generating vrmls with rectification data : \n";
765  cerr << "1. vrml containing only coordinate systems ... " << flush;
766  tdo.AddLine(rectPPA->GetC(), rectPPB->GetC());
767  bool good = false;
768  if (tdo.VRMLOut("rectCoordinates.wrl") != 0) {
769  good = false;
770  } else {
771  good = true;
772  }
773  if (good) {
774  cerr << "finished";
775  } else {
776  cerr << "failure";
777  }
778  cerr << endl;
779 
780  cerr << "2. generating vrml containing projected images ... "
781  << flush;
782  unsigned int width = 0, height = 0;
783  rectPPA->GetImageSize(width, height);
784  Image<float> depthmap(width, height, 1);
785  depthmap.SetZero();
786 
787  double scale = 3.0;
788  if (*pointsonly) {
789  for (unsigned int y = 0; y < height; y++) {
790  for (unsigned int x = 0; x < width; x++) {
791  HomgPoint2D p2(x, y);
792  HomgPoint3D p3 = rectPPA->UnProjectToImagePlane(p2,
793  scale * 0.99);
794  if (p3.NormL2() < 0.1)
795  continue;
796  OutStorageType color = rectA.GetImageDataArray()[y][x];
797  RGBAuc theColor((unsigned char) color,
798  (unsigned char) color, (unsigned char) color,
799  255);
800  tdo.AddPoint(p3, theColor);
801  }
802  }
803  } else {
804  RGBrectA.Init(rectA.GetWidth(), rectA.GetHeight(), 3);
805  ImageConvert::ToRGB(rectA, RGBrectA);
806  TriangleMesh T;
808  ImageConvert::ConvertST(RGBrectA, tmp,
809  ImageBase::ST_unsignedchar);
810  T.GenerateTexturedCamera(rectPPA, tmp, scale * 0.99);
811  tdo.AddTriangleMesh(T, "textureA.png", "textureA.png");
812  }
813 
814  if (*pointsonly) {
815  rectPPB->GetImageSize(width, height);
816  for (unsigned int y = 0; y < height; y++) {
817  for (unsigned int x = 0; x < width; x++) {
818  HomgPoint2D p2(x, y);
819  HomgPoint3D p3 = rectPPB->UnProjectToImagePlane(p2,
820  scale * 1.01);
821  if (p3.NormL2() < 0.1)
822  continue;
823  unsigned char color = (unsigned char) rint(
824  rectB.GetImageDataArray()[y][x]);
825  RGBAuc theColor(color, color, color, 255);
826  tdo.AddPoint(p3, theColor);
827  }
828  }
829  } else {
830  RGBrectB.Init(rectB.GetWidth(), rectB.GetHeight(), 3);
831  ImageConvert::ToRGB(rectB, RGBrectB);
832  TriangleMesh T;
834  ImageConvert::ConvertST(RGBrectB, tmp,
835  ImageBase::ST_unsignedchar);
836  T.GenerateTexturedCamera(rectPPB, tmp, scale * 1.01);
837  tdo.AddTriangleMesh(T, "textureB.png", "textureB.png");
838  }
839  Vector3<double> c = rectPPA->GetC() - rectPPB->GetC();
840 
841  cerr << " writing ..." << endl << flush;
842  tdo.VRMLOut("rectCoordinates_image.wrl");
843  cerr << "writing mipview3d-animfile cylindersweep.anim" << endl;
844  ofstream myanimfile("cylindersweep.anim");
845  myanimfile << "[0] :43 0 0 0 0 1 0 0 0" << endl << "[0] :43 1000 "
846  << c[0] << " " << c[1] << " " << c[2] << " 1 0 0 0" << endl;
847  cerr << "3. generating wrl with orig cameras" << endl << flush;
848  ThreeDOut tdo2;
849 
850  RGBcamA.Init(camA.GetWidth(), camA.GetHeight(), 3);
851  ImageConvert::ToRGB(camA, RGBcamA);
852  RGBcamB.Init(camB.GetWidth(), camB.GetHeight(), 3);
853  ImageConvert::ToRGB(camB, RGBcamB);
854 
855  TriangleMesh T1, T2;
856  T1.GenerateTexturedCamera(camA.GetProj().GetParameters(), RGBcamA,
857  scale);
858  T2.GenerateTexturedCamera(camB.GetProj().GetParameters(), RGBcamB,
859  scale);
860  tdo2.AddTriangleMesh(T1, "textureAorig.png", "textureAorig.png");
861  tdo2.AddTriangleMesh(T2, "textureBorig.png", "textureBorig.png");
862  cerr << " writing ..." << endl << flush;
863  tdo2.AddProjection(camA.GetProj(), RGBAuc(0, 255, 0, 255), scale
864  * 0.1, scale);
865  tdo2.AddProjection(camB.GetProj(), RGBAuc(0, 255, 0, 255), scale
866  * 0.1, scale);
867  tdo2.VRMLOut("orig.wrl");
868  }
869  } //for each image pair
870 
871  delete rectPPA;
872  delete rectPPB;
873  delete rectifier;
874 
875  cout << " done!\n";
876  return 0;
877 }
878 
879 int findLargestRectangularRegion(ProjectionParametersBase* origProj,
880  ProjectionParametersBase* rectProj, ROI& roi) {
881 
882  PixelIterator it;
883  unsigned int w, h;
884  rectProj->GetImageSize(w, h);
885  roi.Resize(w, h);
886  // Image<unsigned char> testIm(w,h, 1);
887  // unsigned char **ida = testIm.GetImageDataArray();
888  unsigned int xmin = 0, xmax = w, ymin = 0, ymax = h;
889  // mid point
890  unsigned int mx, my;
891  origProj->GetImageSize(mx, my);
892  HomgPoint2D midPoint(mx / 2, my / 2, 1);
893  Vector3<double> midRay, pos;
894  origProj->UnProjectToRay(midPoint, pos, midRay);
895  HomgPoint3D ray3D;
896  ray3D[0] = midRay[0];
897  ray3D[1] = midRay[1];
898  ray3D[2] = midRay[2];
899  ray3D[3] = 0;
900  midPoint = rectProj->Project(ray3D);
901  origProj->GetFirstBorderPixel(it);
902  HomgPoint2D edgepoint(0, 0, 0);
903  do {
904  HomgPoint2D sourcepoint(it.x, it.y, 1);
905  HomgPoint2D oldPoint = edgepoint;
906  Vector3<double> globalray;
907  origProj->UnProjectToRay(sourcepoint, pos, globalray);
908  ray3D[0] = globalray[0];
909  ray3D[1] = globalray[1];
910  ray3D[2] = globalray[2];
911  ray3D[3] = 0;
912  edgepoint = rectProj->Project(ray3D);
913  // get distance vector to midpoint
914  HomgPoint2D dist = edgepoint - midPoint;
915  HomgPoint2D grad = edgepoint - oldPoint;
916 
917  // going right (or left)
918  if (abs(grad[0]) > abs(grad[1])) {
919  if (dist[1] < 0) {
920  if (edgepoint[1] > ymin) {
921  ymin = (unsigned)rint(edgepoint[1]);
922  }
923  } else {
924  if (edgepoint[1] < ymax) {
925  ymax = (unsigned)rint(edgepoint[1]);
926  }
927  }
928  } // going up (or down)
929  else {
930  if (dist[0] < 0) {
931  if (edgepoint[0] > xmin) {
932  xmin = (unsigned)rint(edgepoint[0]);
933  }
934  } else {
935  if (edgepoint[0] < xmax) {
936  xmax = (unsigned)rint(edgepoint[0]);
937  }
938  }
939  }
940 
941  // discard points not in image
942  // if (edgepoint[0] >= 0 && edgepoint[0] < w && edgepoint[1] >= 0 && edgepoint[1] < h) {
943  // ida[ (int)edgepoint[1] ][ (int)edgepoint[0] ] = 100;
944  // }
945  } while (origProj->GetNextBorderPixel(it));
946 
947  roi.SetCorners(xmin, ymin, xmax, ymax);
948  //cout<<"roi "<<roi<<endl;
949  return 0;
950 
951 }
952 
953 int findLargestOverlappingRegion(const ProjectionParametersBase *camAproj,
954  const ProjectionParametersBase *camBproj,
955  const ProjectionParametersBase *rectAproj,
956  const ProjectionParametersBase *rectBproj, ROI &roi) {
957 
958  vector<ProjectionParametersBase *> source;
959  vector<ProjectionParametersBase *> dest;
960  source.resize(2);
961  dest.resize(2);
962  source[0] = (ProjectionParametersBase*) camAproj;
963  source[1] = (ProjectionParametersBase*) camBproj;
964  dest[0] = (ProjectionParametersBase*) rectAproj;
965  dest[1] = (ProjectionParametersBase*) rectBproj;
966  PixelIterator it;
967  unsigned int w, h;
968  rectAproj->GetImageSize(w, h);
969  // Image<unsigned char> testIm(w,h, 1);
970  // unsigned char **ida = testIm.GetImageDataArray();
971  unsigned int xmin = 0, xmax = w, ymin = 0, ymax = h;
972  for (unsigned int i = 0; i < source.size(); i++) {
973  // mid point
974  unsigned int mx, my;
975  source[i]->GetImageSize(mx, my);
976  HomgPoint2D midPoint(mx / 2, my / 2, 1);
977  Vector3<double> midRay, pos;
978  source[i]->UnProjectToRay(midPoint, pos, midRay);
979  HomgPoint3D ray3D;
980  ray3D[0] = midRay[0];
981  ray3D[1] = midRay[1];
982  ray3D[2] = midRay[2];
983  ray3D[3] = 0;
984  midPoint = dest[i]->Project(ray3D);
985  source[i]->GetFirstBorderPixel(it);
986  HomgPoint2D edgepoint(0, 0, 0);
987  do {
988  HomgPoint2D sourcepoint(it.x, it.y, 1);
989  HomgPoint2D oldPoint = edgepoint;
990  Vector3<double> globalray;
991  source[i]->UnProjectToRay(sourcepoint, pos, globalray);
992  ray3D[0] = globalray[0];
993  ray3D[1] = globalray[1];
994  ray3D[2] = globalray[2];
995  ray3D[3] = 0;
996  edgepoint = dest[i]->Project(ray3D);
997  // get distance vector to midpoint
998  HomgPoint2D dist = edgepoint - midPoint;
999  HomgPoint2D grad = edgepoint - oldPoint;
1000 
1001  // going right (or left)
1002  if (abs(grad[0]) > abs(grad[1])) {
1003  if (dist[1] < 0) {
1004  if (edgepoint[1] > ymin) {
1005  ymin = (unsigned)rint(edgepoint[1]);
1006  }
1007  } else {
1008  if (edgepoint[1] < ymax) {
1009  ymax = (unsigned)rint(edgepoint[1]);
1010  }
1011  }
1012  } // going up (or down)
1013  else {
1014  if (dist[0] < 0) {
1015  if (edgepoint[0] > xmin) {
1016  xmin = (unsigned)rint(edgepoint[0]);
1017  }
1018  } else {
1019  if (edgepoint[0] < xmax) {
1020  xmax = (unsigned)rint(edgepoint[0]);
1021  }
1022  }
1023  }
1024 
1025  // discard points not in image
1026  // if (edgepoint[0] >= 0 && edgepoint[0] < w && edgepoint[1] >= 0 && edgepoint[1] < h) {
1027  // ida[ (int)edgepoint[1] ][ (int)edgepoint[0] ] = 100;
1028  // }
1029  } while (source[i]->GetNextBorderPixel(it));
1030  }
1031  // ida [ ymin ] [ xmin ] = 255;
1032  // ida [ ymin ] [ xmax ] = 255;
1033  // ida [ ymax ] [ xmin ] = 255;
1034  // ida [ ymax ] [ xmax ] = 255;
1035  roi.SetCorners(xmin, ymin, xmax, ymax);
1036  // ImageIO::Save("test.mip", testIm);
1037  return 0;
1038 }
1039 
1040 /** it is assumed that the roi was calculated with a rescale factor of 1. **/
1041 double CalculateRescaleFactor(int targetWidth, int targetHeight, int roiWidth,
1042  int roiHeight) {
1043 
1044  BIASASSERT(targetHeight > 0 || targetWidth > 0);
1045  float scaleW = 0;
1046  float scaleH = 0;
1047  if (targetHeight > 0)
1048  scaleH = float(targetHeight) / float(roiHeight);
1049  if (targetWidth > 0)
1050  scaleW = float(targetWidth) / float(roiWidth);
1051 
1052  float scale = (scaleW > scaleH) ? scaleW : scaleH;
1053 
1054  return scale;
1055 }
1056 
1057 /** Will only work for planarily rectified images. **/
1058 int findLargestOverlappingRegion(ProjectionParametersBase* camAproj,
1059  ProjectionParametersBase* camBproj,
1062  const double* zeroParallaxZ, ROI& roiA, ROI& roiB, bool verbose) {
1063  // cout<<"finding roiA:\n";
1064  findLargestRectangularRegion(camAproj, rectAproj, roiA);
1065  // cout<<"finding roiB:\n";
1066  findLargestRectangularRegion(camBproj, rectBproj, roiB);
1067 
1068  //determine the zero parallax
1069  Vector3<double> B = rectBproj->GetC() - rectAproj->GetC();
1070  double baseline = B.NormL2();
1071  double f;
1072  rectAproj->GetFocalLength(f);
1073  double parallaxDispTmp = f * (baseline / *zeroParallaxZ);
1074 
1075  int dispZP = 0;
1076  if (*zeroParallaxZ >= 0)
1077  dispZP = static_cast<int> (rint(parallaxDispTmp));
1078  BIASASSERT(dispZP >= 0);
1079 
1080  if (verbose)
1081  cout << "disparity of Zero Parallax " << dispZP << endl;
1082 
1083  int rightUL[2];
1084  int rightLR[2];
1085  int leftUL[2];
1086  int leftLR[2];
1087 
1088  int commonUL[2];
1089  int commonLR[2];
1090 
1091  //now determine overlap in common coordinate frame:
1092  //shift right image for that
1093  if (B[0] > 0) {// cam B is the right
1094  rightUL[0] = roiB.GetCornerUpperLeftX() + dispZP;
1095  rightLR[0] = roiB.GetCornerLowerRightX() + dispZP;
1096  rightUL[1] = roiB.GetCornerUpperLeftY();
1097  rightLR[1] = roiB.GetCornerLowerRightY();
1098 
1099  leftUL[0] = roiA.GetCornerUpperLeftX();
1100  leftLR[0] = roiA.GetCornerLowerRightX();
1101  leftUL[1] = roiA.GetCornerUpperLeftY();
1102  leftLR[1] = roiA.GetCornerLowerRightY();
1103 
1104  } else {// cam A is the right
1105  rightUL[0] = roiA.GetCornerUpperLeftX() + dispZP;
1106  rightLR[0] = roiA.GetCornerLowerRightX() + dispZP;
1107  rightUL[1] = roiA.GetCornerUpperLeftY();
1108  rightLR[1] = roiA.GetCornerLowerRightY();
1109 
1110  leftUL[0] = roiB.GetCornerUpperLeftX();
1111  leftLR[0] = roiB.GetCornerLowerRightX();
1112  leftUL[1] = roiB.GetCornerUpperLeftY();
1113  leftLR[1] = roiB.GetCornerLowerRightY();
1114 
1115  }
1116  //now determine the overlap
1117 
1118  commonUL[0] = max(rightUL[0], leftUL[0]);
1119  commonUL[1] = max(rightUL[1], leftUL[1]);
1120  commonLR[0] = min(rightLR[0], leftLR[0]);
1121  commonLR[1] = min(rightLR[1], leftLR[1]);
1122 
1123  if (verbose) {
1124  cout << "identified left region : ";
1125  cout << "(" << leftUL[0] << "," << leftUL[1] << ")" << "<-->("
1126  << leftLR[0] << "," << leftLR[1] << ")\n";
1127  cout << "identified right region : ";
1128  cout << "(" << rightUL[0] << "," << rightUL[1] << ")" << "<-->("
1129  << rightLR[0] << "," << rightLR[1] << ")\n";
1130 
1131  cout << "identified common region : ";
1132  cout << "(" << commonUL[0] << "," << commonUL[1] << ")" << "<-->("
1133  << commonLR[0] << "," << commonLR[1] << ")\n";
1134  }
1135 
1136  // return the overlap into the left and right image's coordinate frame.
1137  if (B[0] > 0) {// cam B is the right
1138 
1139  roiB.SetCorners(commonUL[0] - dispZP, commonUL[1],
1140  commonLR[0] - dispZP, commonLR[1]);
1141 
1142  roiA.SetCorners(commonUL[0], commonUL[1], commonLR[0], commonLR[1]);
1143 
1144  } else {// cam A is the right
1145  roiA.SetCorners(commonUL[0] - dispZP, commonUL[1],
1146  commonLR[0] - dispZP, commonLR[1]);
1147 
1148  roiB.SetCorners(commonUL[0], commonUL[1], commonLR[0], commonLR[1]);
1149 
1150  }
1151 
1152  return 0;
1153 }
1154 
1155 void CentralCropRoi(int targetWidth, int targetHeight, ROI& roi) {
1156  //central crop to much roi
1157  int roiHeight = roi.GetCornerLowerRightY() - roi.GetCornerUpperLeftY();
1158  int roiWidth = roi.GetCornerLowerRightX() - roi.GetCornerUpperLeftX();
1159 
1160  int ul[2];
1161  int lr[2];
1162  int offsetWidth = 0;
1163  if (roiWidth > targetWidth) {
1164  offsetWidth = (roiWidth - targetWidth) / 2;
1165  }
1166  ul[0] = roi.GetCornerUpperLeftX() + offsetWidth;
1167  lr[0] = ul[0] + targetWidth;
1168 
1169  int offsetHeight = 0;
1170  if (roiHeight > targetHeight) {
1171  offsetHeight = (roiHeight - targetHeight) / 2;
1172  }
1173  ul[1] = roi.GetCornerUpperLeftY() + offsetHeight;
1174  lr[1] = ul[1] + targetHeight;
1175 
1176  roi.SetCorners(ul[0], ul[1], lr[0], lr[1]);
1177 }
virtual BIAS::Vector3< double > GetC() const
Get projection center.
void RetainOriginalApectRatio(bool retain=true)
If this is set to true, the rectification will use the mean of the input pixel aspect ratios for the ...
virtual void SetPrincipal(const double x, const double y)
Set principal point (in pixels relative to top left corner).
class for handling different region of interest (ROI) representations...
Definition: ROI.hh:118
unsigned int AddTriangleMesh(const TriangleMesh &mesh, const std::string &name="", const std::string &textureOutputName="", bool writeOutTexture=true, bool calcNormals=false)
Adds triangle mesh as IndexedFaceSet to ThreeDOut mem.
Definition: ThreeDOut.cpp:1104
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...
int VRMLOut(const std::string &sFilename)
flush all 3d objects to a vrml file with name sFilename, this is the function most users would call ...
Definition: ThreeDOut.cpp:3670
virtual int Load(const std::string &filename)
convenience wrapper which tries to read different formats
Definition: Projection.cpp:62
void GenerateTexturedCamera(const ProjectionParametersBase *PPB, Image< unsigned char > &rgbtexture, const double &scale=1.0, const double &opacity=1.0, const double &resolution=1.0)
generates the sensor plane / cylinder / sphere in 3D space
int SetCorners(unsigned UpperLeftX, unsigned UpperLeftY, unsigned LowerRightX, unsigned LowerRightY)
Sets a rectangular region of interest.
Definition: ROI.cpp:287
void Resize(unsigned width, unsigned height)
Resizes parent image.
Definition: ROI.cpp:227
void GetRectifiedImageA(Image< OutputStorageType > &rectImg)
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 RGBAuc is asynonym for a Vector4 of corerct type
virtual void SetImageSize(const unsigned int w, const unsigned int h)
Set image dimensions (in pixels).
Unified output of 3D entities via OpenGL or VRML.
Definition: ThreeDOut.hh:349
bool * AddParamBool(const std::string &name, const std::string &help, bool deflt=false, char cmdshort=0, int Group=GRP_NOSHOW)
Definition: Param.cpp:305
double * AddParamDouble(const std::string &name, const std::string &help, double deflt=0.0, double min=-DBL_MAX, double max=DBL_MAX, char cmdshort=0, int Group=GRP_NOSHOW)
Definition: Param.cpp:351
base class for rectification implementations and wrappers
virtual int GetClonesOfRectificationParameters(ProjectionParametersBase *&rectPPA, ProjectionParametersBase *&rectPPB)
Tries to calculate the rectification parameters and returns clones of internal members.
int SetRectificationSetup(Camera< float > &rectSetup)
Loads rectification setup from Camera data.
int * AddParamEnum(const std::string &name, const std::string &help, const std::vector< std::string > &enums, const int deflt=0, const std::vector< int > *IDs=NULL, const char cmdshort=0, const int Group=GRP_NOSHOW)
Definition: Param.cpp:468
Class implements rectification by image projection onto a cylinder.
void SetScale(const double &scale)
Scale factor for isotropically scaling the rectified images (and rectified intrinsic parameters)...
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...
int ParseCommandLine(int &argc, char *argv[])
scan command line arguments for valid parameters
Definition: Param.cpp:1028
double NormL2() const
Return the L2 norm: sqrt(a^2 + b^2 + c^2 + d^2)
Definition: Vector4.hh:510
virtual HomgPoint2D Project(const HomgPoint3D &X, bool IgnoreDistortion=false) const
calculates the projection of a point in the world coordinate system to a pixel in the image plane of ...
unsigned int AddProjection(const Projection &p, const RGBAuc &colorSelection=RGBAuc_WHITE_OPAQUE, const double radius=0.1, const double scale=1.0, const std::string &identifier="", const int camera_type=-1)
Add a projection object to ThreeDOut mem.
Definition: ThreeDOut.cpp:1308
virtual void GetFirstBorderPixel(PixelIterator &it)
call this to start a run at the outer boundary of an image.
int GetRectificationSetup(Camera< float > &rectSetup)
Method returns the current rectification setup.
void Usage(std::ostream &os=std::cout)
print Help-Information to stdout
Definition: Param.cpp:176
const ProjectionParametersBase * GetParameters(unsigned int cam=0) const
const parameter access function
Definition: Projection.hh:194
int Pad(BIAS::ImageBase &dest, const unsigned int &newwidth, const unsigned int &newheight, const int &padVal=0) const
Definition: ImageBase.cpp:1207
This class hides the underlying projection model, like projection matrix, spherical camera...
Definition: Projection.hh:70
BIAS::Vector< int > * AddParamVecInt(const std::string &name, const std::string &help, const BIAS::Vector< int > &deflt, char cmdshort=0, int Group=GRP_NOSHOW)
Add a parameter that expects a string on command line like &quot;&lt;value0&gt; &lt;value1&gt; &lt;value2&gt; ...
Definition: Param.cpp:423
void SetInterpolationMethod(InterpolationMethod interpolationType)
Determines the type of interpolation used when rectifying.
int XMLWrite(const std::string &Filename, int CompressionLevel=0, bool AutoAddCompressionSuffix=true, std::string encoding="UTF-8") const
call this to add the class to a new xml tree and write it to the file Filename.
Definition: XMLBase.cpp:40
Create and represent a 3D triangle mesh.
Definition: TriangleMesh.hh:84
int SetProj(const Projection &Proj)
Definition: Camera.hh:106
void GetFocalLength(double &f) const
Get the current camera focal length.
unsigned int GetHeight() const
Definition: ImageBase.hh:319
void FixateIntrinsics(const ProjectionParametersPerspective &ppp)
int GetFreeGroupID()
returns unused group id
Definition: Param.cpp:1421
Class implements rectification by image projection onto a sphere.
void UseLookUpTables(bool use)
Method allows to turn on or off the use of look up tables.
Rectification via perspective cameras, removes distortions.
unsigned int AddLine(const BIAS::Vector3< double > &Start, const BIAS::Vector3< double > &End, const BIAS::RGBAuc &Color=RGBAuc_WHITE_OPAQUE)
Definition: ThreeDOut.cpp:756
void SetSecondFill(OutputStorageType d)
fill color for second image (first is black)
virtual int SetCameraB(BIAS::Camera< InputStorageType > &cam)
class HomgPoint3D describes a point with 3 degrees of freedom in projective coordinates.
Definition: HomgPoint3D.hh:61
virtual int Rectify()=0
Fundamental method which contains the rectification implementation.
Can be used to run along the image border.
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
double x
If using BorderPixel methods these are the coordinates of the pixel.
int UpdateMetaData()
copy P_ and co.
Definition: Camera.cpp:446
This class Param provides generic support for parameters.
Definition: Param.hh:231
int SetGroupName(const int group_id, const std::string &name)
sets the name for a group
Definition: Param.cpp:1448
void GetRectifiedImageB(Image< OutputStorageType > &rectImg)
bool IsProjValid() const
Definition: Camera.hh:221
int * AddParamInt(const std::string &name, const std::string &help, int deflt=0, int min=std::numeric_limits< int >::min(), int max=std::numeric_limits< int >::max(), char cmdshort=0, int Group=GRP_NOSHOW)
For all adding routines:
Definition: Param.cpp:276
virtual int SetCameraA(BIAS::Camera< InputStorageType > &cam)
unsigned int AddPoint(const BIAS::Vector3< double > &v, const BIAS::RGBAuc &Color=RGBAuc_WHITE_OPAQUE)
Definition: ThreeDOut.cpp:719
unsigned GetCornerLowerRightY() const
fetch individual ROI corner coordinate
Definition: ROI.hh:207
Camera parameters which define the mapping between rays in the camera coordinate system and pixels in...
const BIAS::Projection & GetProj() const
Definition: Camera.hh:109
std::string * AddParamString(const std::string &name, const std::string &help, std::string deflt="", char cmdshort=0, int Group=GRP_NOSHOW)
Definition: Param.cpp:327
int ParseMetaData(bool bUse2x64bitTS=true)
After ImageIO::Load() operated on AppData_, this method fills P_, Timestamp, DC_*, ...
Definition: Camera.cpp:154
unsigned GetCornerUpperLeftY() const
fetch individual ROI corner coordinate
Definition: ROI.hh:195
unsigned GetCornerLowerRightX() const
fetch individual ROI corner coordinate
Definition: ROI.hh:201
double NormL2() const
the L2 norm sqrt(a^2 + b^2 + c^2)
Definition: Vector3.hh:633
virtual HomgPoint3D UnProjectToImagePlane(const HomgPoint2D &pos, const double &depth=1.0, bool IgnoreDistortion=false) const =0
map points from image onto unit diameter image plane in 3D.
virtual bool GetNextBorderPixel(PixelIterator &it)
call this iteratively to run at the outer boundary of an image.
const StorageType ** GetImageDataArray() const
overloaded GetImageDataArray() from ImageBase
Definition: Image.hh:153
unsigned GetCornerUpperLeftX() const
fetch individual ROI corner coordinate
Definition: ROI.hh:189