Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
biascalibratecamera.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 <bias_config.h>
27 #ifndef BIAS_HAVE_OPENCV
28 # error You need to enable OPENCV to compile this file. Please reconfigure MIP with USE_OPENCV (jw)
29 #endif
30 
31 #include <Base/Common/W32Compat.hh>
32 #include <math.h>
33 
34 #include <cv.h>
35 #include <highgui.h>
36 
37 #ifndef CV_CALIB_ZERO_TANGENT_DIST
38 # error Your OpenCV version is probably too old because CV_CALIB_ZERO_TANGENT_DIST seems to be unsupported. Try again with OpenCV version >=beta5a
39 #endif
40 
41 #define DRAW_IDEAL_OVERLAY
42 #define DRAW_POINT_LABEL
43 #define DRAW_AXES
44 
45 // write VRML model of P matrices using BIAS::ThreeDOut?
46 #define WRITE_VRML
47 
48 // output formatting
49 #define DIGW 12
50 #define DIGPREC 5
51 
52 #include <string>
53 #include <iostream>
54 #include <fstream>
55 #include <iomanip>
56 #include <sstream>
57 
58 #ifdef WRITE_VRML
59 # include "Utils/ThreeDOut.hh"
60 #endif // WRITE_VRML
61 
62 // BIAS
63 #include <Base/Debug/Error.hh>
64 #include <Base/Common/FileHandling.hh>
65 #include <Base/Math/Vector3.hh>
66 #include <Base/Image/ImageIO.hh>
67 #include <Base/Image/ImageConvert.hh>
68 #include <Geometry/RMatrix.hh>
69 #include <Geometry/PMatrix.hh>
70 #include <Geometry/Pose.hh>
71 #include <Utils/Param.hh>
72 
73 using namespace BIAS;
74 using namespace std;
75 
76 /**
77  @file
78  @ingroup g_tools
79  @brief The program reads the images from disk,detects chessboard of given
80  known dimension, and computes internal calibration parameters (and extrinsics
81  for this purpose, too), see biascalibratecamera.cpp
82  @author Jan Woetzel, University of Kiel, 03/2005, 09/2005
83  additional features by grest
84 */
85 
86 /*
87  Usage:
88  calibrateCamera <chessboard_corners_per_row> <chessboard_corners_per_column>
89  <chessboard_images> ...
90  The program reads the images from disk,
91  detects chessboard of given known dimension,
92  and computes internal calibration parameters (and extrinsics for this
93  purpose, too).
94 
95  Then undistorts and writes the results:
96  - the distortion coefficient following the Bouguet model,
97  - the camera calibration "K",
98  - the camera image overlayed with the corners found,
99  - the corners backprojected using their 3D scene corrdinates,
100  - the extrinsic parameters R, C for each image
101  - the backprojected corners in undistorted images.
102 
103  Based on OpenCV implementation of Bouguet calib toolbox and some sample code
104  from Stanford University "cs223b" course notes.
105 
106  You may find "grabGui" and its "FindChessboard" mode useful for live
107  capturing only images where the complete chessboard was clearly detected.
108 
109  Please note the different notation for extrinsics between Cv and BIAS:
110  R_bias = R_cv.transposed
111  C_bias = -1 * R_cv.transpose * C_cv
112 */
113 
114 BIAS::Param params;
115 
116 /* Backprojection from world to image coordinates
117  @todo change to BIAS::PMatrix multiplication JW */
118 CvPoint2D32f * ConvertWorldToPixel(CvPoint3D32f *pts3d,
119  int numImages, int *numPts,
120  CvMatr32f cam, CvVect32f t, CvMatr32f r,
121  int xCorners, int yCorners)
122 {
123  int i=0, j=0, k=0;
124  CvPoint2D32f *pts2d = new CvPoint2D32f[numImages * xCorners * yCorners];
125 
126  CvMat *C = cvCreateMat(3, 3, CV_32FC1);
127  CvMat *point3D = cvCreateMat(3, 1, CV_32FC1);
128  CvMat *R = cvCreateMat(3, 3, CV_32FC1);
129  CvMat *T = cvCreateMat(3, 1, CV_32FC1);
130 
131  CvPoint3D32f *pts3dCur = pts3d;
132  CvPoint2D32f *pts2dCur = pts2d;
133 
134  for (i = 0; i < 3; i++) {
135  for (j = 0; j < 3; j++) {
136  CV_MAT_ELEM(*C, float, i, j) = cam[3 * i + j];
137  }
138  }
139 
140  for (k = 0; k < numImages; k++) {
141  for (j = 0; j < 9; j++) {
142  if (j < 3) CV_MAT_ELEM(*T, float, j, 0) = t[k*3 + j];
143  CV_MAT_ELEM(*R, float, j / 3, j%3) = r[k*9 + j];
144  }
145  for (i = 0; i < numPts[k]; i++) {
146  CV_MAT_ELEM(*point3D, float, 0, 0) = pts3dCur[i].x;
147  CV_MAT_ELEM(*point3D, float, 1, 0) = pts3dCur[i].y;
148  CV_MAT_ELEM(*point3D, float, 2, 0) = pts3dCur[i].z;
149 
150  cvMatMulAdd(R, point3D, T, point3D); //rotate and translate
151  cvMatMul(C, point3D, point3D); //camera
152 
153  pts2dCur[i].x = CV_MAT_ELEM(*point3D, float, 0, 0) /
154  CV_MAT_ELEM(*point3D, float, 2, 0);
155  pts2dCur[i].y = CV_MAT_ELEM(*point3D, float, 1, 0) /
156  CV_MAT_ELEM(*point3D, float, 2, 0);
157  }
158  pts3dCur += numPts[k];
159  pts2dCur += numPts[k];
160  }
161 
162  cvReleaseMat(&point3D);
163  cvReleaseMat(&T);
164  cvReleaseMat(&R);
165 
166  return pts2d;
167 }
168 
169 
170 /* DrawPoints takes number of corners on x axis and y axis,
171  and number of images to builds an array of corners.
172  Assumes all corners on z = 0 plane.
173  @todo Move to BIAS/FeatureDetector/CheckerboardDetector JW
174 */
175 void DrawPoints(CvArr *img, CvPoint2D32f *ptArray, int numPts,
176  const int xCorners, const int yCorners)
177 {
178  CvPoint pt;
179  CvPoint ptOld;
180 #ifdef DRAW_POINT_LABEL
181  CvFont font;
182  cvInitFont(&font, CV_FONT_HERSHEY_PLAIN, 1.0f, 1.0f);
183 #endif //DRAW_POINT_LABEL
184 
185  // init old as first
186  if (numPts > 0) {
187  ptOld.x = (int)ptArray[0].x;
188  ptOld.y = (int)ptArray[0].y;
189  }
190  for (int i = 0; i < numPts; i++) {
191  int clr = (int)((float)i / numPts * 255.0);
192  pt.x = (int)ptArray[i].x;
193  pt.y = (int)ptArray[i].y;
194  cvCircle(img, pt, 3, CV_RGB(255-clr,0,clr), CV_FILLED);
195 
196 #ifdef DRAW_POINT_LABEL
197  // label the point
198  stringstream ssID;
199  ssID << i;
200  cvPutText(img, ssID.str().c_str(), pt, &font, CV_RGB(0,0,255));
201 #endif //DRAW_POINT_LABEL
202  // next
203  ptOld=pt;
204  }
205 
206 #ifdef DRAW_IDEAL_OVERLAY
207  // mark ideal pattern
208  // horizontal lines
209  for (int xx = 0; xx < xCorners*yCorners; xx+=xCorners) {
210  cvLine(img, cvPointFrom32f(ptArray[xx]),
211  cvPointFrom32f(ptArray[xx+xCorners-1]),
212  CV_RGB(0,0,255), 1, CV_AA);
213  }
214  // vertical lines
215  for (int yy = 0; yy < xCorners; yy+=1) {
216  cvLine(img, cvPointFrom32f(ptArray[yy]),
217  cvPointFrom32f(ptArray[yy+xCorners*(yCorners-1)]),
218  CV_RGB(0,0,255), 1, CV_AA);
219  }
220 #endif
221 
222 #ifdef DRAW_AXES
223  CvFont fontBig;
224  cvInitFont(&fontBig, CV_FONT_HERSHEY_PLAIN, 5.0f, 5.0f, 0, 2, CV_AA);
225  cvPutText(img, "0", cvPointFrom32f(ptArray[0]), &fontBig, CV_RGB(0,0,255));
226  cvLine(img, cvPointFrom32f(ptArray[0]), cvPointFrom32f(ptArray[xCorners-1]),
227  CV_RGB(255,0,0), 1, CV_AA);
228  cvPutText(img, "X", cvPointFrom32f(ptArray[xCorners-1]),
229  &fontBig, CV_RGB(255,0,0));
230  cvLine(img, cvPointFrom32f(ptArray[0]),
231  cvPointFrom32f(ptArray[xCorners*(yCorners-1)]),
232  CV_RGB(0,255,0), 1, CV_AA);
233  cvPutText(img, "Y", cvPointFrom32f(ptArray[xCorners*(yCorners-1)]),
234  &fontBig, CV_RGB(0,255,0));
235 #endif //DRAW_AXES
236 }
237 
238 /* InitCorners3d
239  Takes number of corners on x axis and y axis + number of images
240  Builds a regular checkerboard array of corners.
241  Assumes all corners on z = 0 plane.
242 */
243 void InitCorners3d(CvPoint3D32f *corners3d, int xCorners,
244  int yCorners, int numImages)
245 {
246  int n=0, x=0, y=0;
247  int nStride = xCorners * yCorners;
248  for (n = 0; n < numImages; n++) {
249  for (x = 0; x < xCorners; x++) {
250  for (y = 0; y < yCorners; y++) {
251  corners3d[n*nStride + x +xCorners*y].x = (float)x;
252  corners3d[n*nStride + x +xCorners*y].y = (float)y;
253  corners3d[n*nStride + x +xCorners*y].z = 0.0f;
254  }
255  }
256  }
257 }
258 
259 /* InitCorners3dMatrix
260  Takes number of corners on x axis and y axis + number of images
261  Builds a regular checkerboard matrix of corners.
262  Assumes all corners on z = 0 plane.
263 */
264 void InitCorners3dMatrix(CvMat *corners3dMat,
265  int xCorners, int yCorners, int numImages)
266 {
267  int n=0, x=0, y=0;
268  int offset=xCorners * yCorners;
269  for (n = 0; n < numImages; n++) {
270  for (x = 0; x < xCorners; x++) {
271  for (y = 0; y < yCorners; y++) {
272  CV_MAT_ELEM(*corners3dMat,float,n*offset+x+ y*xCorners, 0) = (float)x;
273  CV_MAT_ELEM(*corners3dMat,float,n*offset+x+ y*xCorners, 1) = (float)y;
274  CV_MAT_ELEM(*corners3dMat,float,n*offset+x+ y*xCorners, 2) = 0.0f;
275  }
276  }
277  }
278 }
279 
280 
281 void InitCorners2dPointMatrix(CvMat *points2dMat,CvPoint2D32f *cornersArray,
282  CvMat *pointCounts, int* cornersFound,
283  int numImages)
284 {
285  int n=0, x=0, row=0;
286  for (n = 0; n < numImages; n++) {
287  int corners=cornersFound[n];
288  CV_MAT_ELEM(*pointCounts,int,n,0)=corners;
289  for (x = 0; x < corners; x++) {
290  CV_MAT_ELEM(*points2dMat,float,row+x,0) = cornersArray[row+x].x;
291  CV_MAT_ELEM(*points2dMat,float,row+x,1) = cornersArray[row+x].y;
292  }
293  row+=corners;
294  }
295 }
296 
297 /* return BIAS::Vector3 structure from float array */
298 BIAS::Vector3<double> GetCfromArr(const unsigned int camIndex,
299  const float * translation_vectors,
300  const unsigned int numImages)
301 {
302  BIASASSERT(translation_vectors!=NULL);
303  BIASASSERT(camIndex<numImages);
305  for (unsigned int k=0; k<3; k++)
306  C.GetData()[k] = translation_vectors[camIndex*3 +k];
307  return C;
308 }
309 
310 /* return BIAS::RMatrix structure from float array */
311 BIAS::RMatrix GetRfromArr(const unsigned int camIndex,
312  const float * rotation_matrices,
313  const unsigned int numImages)
314 {
315  BIASASSERT(rotation_matrices!=NULL);
316  BIASASSERT(camIndex<numImages);
317  BIAS::RMatrix R;
318  for (unsigned int k=0; k<9; k++)
319  R.GetData()[k] = rotation_matrices[camIndex*9 +k];
320  return R;
321 }
322 
323 /* return BIAS::KMatrix structure from float array */
324 BIAS::KMatrix GetKfromArr(const float * camera_matrix)
325 {
326  BIASASSERT(camera_matrix!=NULL);
327  BIAS::KMatrix K;
328  for (unsigned int i=0; i<9; i++)
329  K.GetData()[i] = camera_matrix[i];
330  return K;
331 }
332 
333 /* return BIAS::PMatrix structure from float array */
334 BIAS::PMatrix GetPfromArr(const unsigned int camIndex,
335  const float * rotation_matrices,
336  const float * translation_vectors,
337  const unsigned int numImages)
338 {
339  BIAS::PMatrix P;
340  P.SetIdentity();
341  BIASASSERT(rotation_matrices!=NULL);
342  BIASASSERT(translation_vectors!=NULL);
343  BIASASSERT(camIndex<numImages);
344  return P;
345 }
346 
347 /* formatted output of intrinsics */
348 void PrintIntrinsics(CvVect32f distortion,
349  CvMatr32f camera_matrix,
350  std::ostream & os)
351 {
352  BIASASSERT(distortion!=NULL);
353  os << "Distortion coefficients:" << endl
354  << "[0] radial "
355  << setw(DIGW)<<setprecision(DIGPREC)<<distortion[0]<<endl
356  << "[1] radial "
357  << setw(DIGW)<<setprecision(DIGPREC)<<distortion[1]<<endl
358  << "[2] tangential "
359  << setw(DIGW)<<setprecision(DIGPREC)<<distortion[2]<<endl
360  << "[3] tangential "
361  << setw(DIGW)<<setprecision(DIGPREC)<<distortion[3]<<endl;
362 
363  BIASASSERT(camera_matrix != NULL);
364  os << "Camera matrix K:" << endl;
365  //PrintMatrix(camera_matrix, 3, 3, os);
366  os << " " << GetKfromArr(camera_matrix) << endl;
367 }
368 
369 /* BIAS::Vector4 compatible output for undistortion call */
370 void PrintDistortionVec4(CvVect32f distortion,
371  std::ostream & os)
372 {
373  BIASASSERT(distortion!=NULL);
374  os << "4" << endl
375  << setw(DIGW)<<setprecision(DIGPREC)<<distortion[0]<<endl
376  << setw(DIGW)<<setprecision(DIGPREC)<<distortion[1]<<endl
377  << setw(DIGW)<<setprecision(DIGPREC)<<distortion[2]<<endl
378  << setw(DIGW)<<setprecision(DIGPREC)<<distortion[3]<<endl;
379 }
380 
381 /* convert rotation matrix from OpenCV notation to BIAS notation JW */
382 BIAS::RMatrix R_cv2bias(const BIAS::RMatrix & Rcv)
383 {
384  BIAS::RMatrix Rbias = Rcv.Transpose();
385  return Rbias;
386 }
387 
388 /* convert translation vector from OpenCV notation to BIAS notation JW */
389 BIAS::Vector3<double> C_cv2bias(const BIAS::Vector3<double> & Ccv,
390  const BIAS::RMatrix & Rcv )
391 {
392  BIAS::Vector3<double> Cbias = -1.0 * (Rcv.Transpose() * Ccv);
393  return Cbias;
394 }
395 
396 /* print formatted extrinsic parameters JW */
397 void PrintExtrinsics(const float * translation_vectors,
398  const float * rotation_matrices,
399  const unsigned int numImages,
400  std::ostream & os)
401 {
402  BIASASSERT(translation_vectors != NULL);
403  BIASASSERT(rotation_matrices != NULL);
404 
405  BIAS::RMatrix tmpRcv, Rbias;
406  BIAS::Vector3<double> tmpCcv, Cbias;
407  for (unsigned int i = 0; i < numImages; i++) {
408  tmpRcv = GetRfromArr(i, rotation_matrices, numImages);
409  tmpCcv = GetCfromArr(i, translation_vectors, numImages);
410  Rbias = R_cv2bias(tmpRcv);
411  Cbias = C_cv2bias(tmpCcv, tmpRcv);
412  os << "[" << i << "] R = " << Rbias << "\tC = " << Cbias << endl;
413  }
414 }
415 
416 /* print usage information for application */
417 void usage(int argc, char** argv)
418 {
419  cout<<"Usage: calibrateCamera <inner_chessboard_corners_X> "
420  <<"<inner_chessboard_cornersY> [all-image-filenames]"<<endl
421  <<" with at least 2 inner chessboard corners and "
422  <<"*non-symmetric* chessboard pattern. "<<endl
423  <<" In particular 8x8 is *NOT* OK while 8x7 is good."<<endl
424  <<endl
425  <<"Sample usage:"<<endl
426  <<" calibrateCamera 7 4 a.jpg b.jpg c.jpg d.jpg e.jpg "<<endl
427  <<"or special dart test modus:"<<endl
428  <<" calibrateCamera --darttest [0|1] a.jpg b.jpg c.jpg d.jpg e.jpg ..."<<endl
429  <<endl
430  <<"(c) MIP University of Kiel"<<endl
431  <<"Jan Woetzel (www.mip.informatik.uni-kiel.de/~jw)"<<endl
432  <<"feel free to ask me fo details."<<endl;
433  params.Usage();
434 }
435 
436 
437 /* MAIN APPLICATION */
438 int main(int argc, char** argv)
439 {
440  if (argc > 0) {
441  cout<<"Started "<<argv[0]<<"\n(c) MIP University of Kiel, Jan Woetzel"<<endl;
442  }
443  IplImage *image = NULL;
444  IplImage *undistort = NULL;
445  IplImage *gray = NULL;
446  CvPoint2D32f *cornersArray = NULL;
447  int numImages=0;
448  CvPoint3D32f *corners3d = NULL;
449  CvVect32f translation_vectors = NULL;
450  CvMatr32f rotation_matrices = NULL;
451 
452  bool usegui=true;
453 
454 
455  params.DisableDestructorWarning();
456  params.AddParamBool("fixedAspect","focal length is euqal in both directions",
457  false,'a');
458  params.AddParamBool("fixedPrincipal",
459  "principal point is fixed in image center",
460  false,'p');
461  params.AddParamBool("fixedAll","only calibrate extrinsic parameters, "
462  "KMatrix must be given, distortion is optional",
463  false,'f');
464  params.AddParamString("kmatrix","file name of K-matrix with inital values,"
465  " which are unchanged if fixedAll","",'K');
466  params.AddParamString("distortion","file name of vector with distortion "
467  " values (radial k1, k2, tangential p1,p2)",
468  "",'D');
469  params.AddParamString("darttest","perform dart test");
470  params.SetEnhancedFlag("darttest",true);
471  //params.SetHiddenFlag("darttest",true);
472  int nextParam=params.ParseCommandLine(argc,argv);
473  BIASASSERT(nextParam >= 0);
474 
475  BIASASSERT(params.GetParamString("darttest") != NULL);
476  if ((argc-nextParam<3) && (params.GetParamString("darttest")->size()==0)) {
477  usage(argc, argv);
478  return -1;
479  }
480 
481  BIAS::Vector4<float> distortion;
482  distortion.SetZero();
483  BIAS::Matrix3x3<float> camera_matrix;
484  camera_matrix.SetIdentity();
485  int flags = 0;
486  flags |= CV_CALIB_ZERO_TANGENT_DIST; // no tangential distortion
487 
488  if (params.GetParamString("kmatrix")->length() > 0) {
489  ifstream in(params.GetParamString("kmatrix")->c_str());
490  if (!in) {
491  cerr << "Error opening KMatrix file "
492  << *params.GetParamString("kmatrix") << endl;
493  return -1;
494  }
495  in >> camera_matrix;
496  flags |= CV_CALIB_USE_INTRINSIC_GUESS;
497  }
498  if (*params.GetParamBool("fixedAspect"))
499  flags |= CV_CALIB_FIX_ASPECT_RATIO;
500  if (*params.GetParamBool("fixedPrincipal"))
501  flags |= CV_CALIB_FIX_PRINCIPAL_POINT;
502 
503  BIAS::Vector4<float> biasDistortion(0, 0, 0, 0);
504  if (params.GetParamString("distortion")->length() > 0) {
505  ifstream in(params.GetParamString("distortion")->c_str());
506  if (!in) {
507  cerr << "Error opening distortion file "
508  << *params.GetParamString("distortion") << endl;
509  return -1;
510  }
511  in >> biasDistortion;
512  cout << "User given distortion values:" << biasDistortion << endl;
513  }
514 
515  int xCorners = 0;
516  int yCorners = 0;
517  int iImg = 0;
518  int width = 0;
519  int height = 0;
520 
521  // HACK Dart Testing (JW)
522  bool darttest = false;
523  if (argc >= 2) {
524  if (strcmp(argv[1],"--darttest") == 0) {
525  std::cout << "Started dart test for " << argv[0] << std::endl;
526  xCorners = 7; // HACK fixed size for darttest
527  yCorners = 4;
528  darttest = true;
529  if (argv[2][0] == '1') {
530  usegui = true;
531  } else {
532  usegui = false;
533  }
534  //nextParam=0;
535  } else {
536  // parse cmd line
537  xCorners = atoi(argv[nextParam]);
538  nextParam++;
539  if (xCorners < 1)
540  cout<<"[ERROR] xCorners = "<<xCorners<<" is invalid!"<<endl;
541  yCorners = atoi(argv[nextParam]);
542  nextParam++;
543  if (yCorners<1)
544  cout<<"[ERROR] yCorners = "<<yCorners<<" is invalid!"<<endl;
545  }
546  }
547 
548  // atoi return 0 on error, non numeric.
549  if ((xCorners<=2) || (yCorners<=2)) {
550  usage(argc, argv);
551  return -2;
552  }
553 
554  // the rest are the input images
555  numImages = argc - nextParam;
556 
557  // allocate:
558  cornersArray = new CvPoint2D32f[xCorners*yCorners*numImages];
559  corners3d = new CvPoint3D32f[xCorners*yCorners*numImages];
560  int *cornersFound = new int[numImages];
561  translation_vectors = new float[3*numImages];
562  rotation_matrices = new float[9*numImages];
563  InitCorners3d(corners3d, xCorners, yCorners, numImages);
564 
565  // grest stuff
566  CvMat *corners3dMat = cvCreateMat(xCorners*yCorners*numImages,3, CV_32FC1);
567  InitCorners3dMatrix(corners3dMat, xCorners, yCorners, numImages);
568 
569  if (usegui) {
570  cvNamedWindow("Image", CV_WINDOW_AUTOSIZE);
571  cvMoveWindow("Image", 0,0);
572  }
573  CvPoint2D32f *nextCornersArray = cornersArray;
574  string imgFilename;
575  string outFilename;
576  string outFilenameVRML("out_allP.wrl");
577 
578 #ifdef WRITE_VRML
579  ThreeDOutParameters threeDOutParams;
580  ThreeDOut CameraVRML(threeDOutParams);
581 #endif // WRITE_VRML
582 
584  for (iImg = 0; iImg < numImages; iImg++) {
585  BIASASSERT((iImg+nextParam)<argc);
586  imgFilename = argv[iImg+nextParam];
587  // Load all the new images into their data structures
588  cout << "Loading " << imgFilename << endl;
589  if (ImageIO::Load( imgFilename.c_str(), biasImg)!=0) {
590  BIASERR("BIAS::ImageIO failed to load image " << imgFilename
591  << ". Now trying OpenCV routines...");
592  image = cvLoadImage(imgFilename.c_str());
593  if (image == NULL){
594  BIASERR("OpenCV failed to load " << imgFilename << " either. Aborting!");
595  BIASBREAK;
596  BIASABORT;
597  }
598  } else {
599 #ifdef BIAS_HAVE_OPENCV
600  // conversion required fromBIAS to cv image
601  ImageConvert::BIAS2ipl(biasImg, image);
602 #else
603  BIASERR("case not implemented.");
604 #endif
605  }
606  BIASASSERT(image!=NULL); // loaded?
607  width = image->width;
608  height = image->height;
609 
610  if (image->depth != IPL_DEPTH_8U) {
611  cerr << "[ERROR] Depth is not IPL_DEPTH_8U for image "
612  << imgFilename <<"!" << endl;
613  return -2;
614  }
615 
616  // Convert image to grayscale if it is not already
617  if (image->nChannels == 1 && image->depth == IPL_DEPTH_8U) {
618  gray = cvCloneImage(image);
619  } else {
620  gray = cvCreateImage(cvSize(image->width, image->height),
621  IPL_DEPTH_8U, 1);
622  BIASASSERT(gray!=NULL);
623  cvConvertImage(image, gray);
624  }
625 
626  // Feedback of images loaded for sanity
627  if (usegui)
628  cvShowImage("Image", image);
629 
630  // Start calibration of points
631  cornersFound[iImg] = xCorners * yCorners;
632 
633  // nextCornersArray is a pointer into cornersArray to the last slot open
634  // this will overflow if cvchessboard ever gives us more corners then expected
635 
636 /*
637  // deprecated call
638  IplImage *threshold = cvCreateImage(cvSize(image->width, image->height),
639  IPL_DEPTH_8U, 1);
640  BIASASSERT(threshold != NULL);
641  int res = cvFindChessBoardCornerGuesses(gray, threshold, NULL,
642  cvSize(xCorners, yCorners),
643  nextCornersArray,
644  &cornersFound[iImg]);
645  cvReleaseImage(&threshold);
646 */
647 
648  int res = cvFindChessboardCorners(gray, cvSize(xCorners, yCorners),
649  nextCornersArray,
650  &cornersFound[iImg],
651  CV_CALIB_CB_ADAPTIVE_THRESH);
652  //CV_CALIB_CB_NORMALIZE_IMAGE);
653  //CV_CALIB_CB_FILTER_QUADS);
654 
655  cvFindCornerSubPix(gray, nextCornersArray,
656  cornersFound[iImg], cvSize(5,5), cvSize(-1,-1),
657  cvTermCriteria(CV_TERMCRIT_ITER, 100, 0.1));
658 
659  // more visual feedback to confirm correctness
660  DrawPoints(image, nextCornersArray, cornersFound[iImg], xCorners, yCorners);
661  if (usegui) {
662  cvShowImage("Image", image);
663  cvWaitKey(1);
664  }
665 
666  // save debug image
667  outFilename = FileHandling::Basename(imgFilename) +"_findChessBoardCornerGuesses.jpg";
668  cvSaveImage(outFilename.c_str(), image);
669 
670  if (!res) {
671  cerr<<"[ERROR] Could not find all "<<xCorners<<"x"<<yCorners
672  <<" inner corners of checkerboard in image "<<imgFilename << endl
673  <<" but actually checkerboard has to be detectable"
674  <<" in *all* images!"<<endl<<" Please remove image "
675  <<imgFilename<<" and try again!"<<endl;
676  cerr<<"Press any key in GUI window."<<endl;
677  cvWaitKey(0);
678  return -3;
679  }
680  // update so that nextCornersArray points to the next open slot in cornersArray
681  nextCornersArray += cornersFound[iImg];
682 
683  // required to update display:
684  cvWaitKey(1);
685 
686  cvReleaseImage(&image);
687  cvReleaseImage(&gray);
688  }
689  if (usegui) cvDestroyWindow("Image");
690 
691  cout<<"Solving calibration... "<<flush;
692 
693 /*
694  // run calibration routine on pre-detecteed coordinates
695  cvCalibrateCamera(numImages,
696  cornersFound, //point count
697  cvSize(width, height), // image size
698  cornersArray, // image points
699  corners3d, // object points
700  distortion.GetData(), // coefficients
701  camera_matrix.GetData(),
702  translation_vectors,
703  rotation_matrices,
704  FLAGS);
705 */
706 
707  int totalpoints = 0;
708  for (int i = 0;i < numImages; i++) {
709  totalpoints += cornersFound[i];
710  }
711  CvMat *points2dMat = cvCreateMat(totalpoints, 2, CV_32FC1);
712  CvMat *pointCountMat = cvCreateMat(numImages, 1, CV_32SC1);
713  InitCorners2dPointMatrix(points2dMat, cornersArray, pointCountMat,
714  cornersFound, numImages);
715  CvMat *camMatrix = cvCreateMat(3,3,CV_32FC1);
716  if (params.GetParamString("kmatrix")->length() > 0) {
717  cvInitMatHeader(camMatrix,3,3,CV_32FC1, camera_matrix.GetData());
718  } else {
719  cvmSetZero(camMatrix);
720  CV_MAT_ELEM(*camMatrix,float,0,0) = 600.;
721  CV_MAT_ELEM(*camMatrix,float,1,1) = 600.;
722  CV_MAT_ELEM(*camMatrix,float,0,2) = float(width/2.);
723  CV_MAT_ELEM(*camMatrix,float,1,2) = float(height/2.);
724  CV_MAT_ELEM(*camMatrix,float,2,2) = 1.;
725  }
726 
727  CvMat *distortMatrix = cvCreateMat(4,1,CV_32FC1);
728  if (params.GetParamString("distortion")->length() > 0) {
729  cvInitMatHeader(distortMatrix,4,1,CV_32FC1, biasDistortion.GetData());
730  } else {
731  cvmSetZero(distortMatrix);
732  }
733 
734  CvMat *rotVectors = cvCreateMat(numImages,3,CV_32FC1);
735  CvMat *transVectors = cvCreateMat(numImages,3,CV_32FC1);
736 
737  if (*params.GetParamBool("fixedAll")) {
738  CvMat *rotVector = cvCreateMat(1,3,CV_32FC1);
739  CvMat *transVector = cvCreateMat(1,3,CV_32FC1);
740  int nextPoint=0;
741  for (int n=0; n<numImages; n++) {
742  // build up temporary 3d and 2d points
743  int nrPoints = CV_MAT_ELEM(*pointCountMat,int,n,0);
744  CvMat *points3DSingleView = cvCreateMat(nrPoints,3,CV_32FC1);
745  CvMat *points2DSingleView = cvCreateMat(nrPoints,2,CV_32FC1);
746  for (int p=0; p < nrPoints; p++) {
747  int r;
748  for (r=0; r < 2; r++) {
749  CV_MAT_ELEM(*points2DSingleView,float,p,r) =
750  CV_MAT_ELEM(*points2dMat,float,nextPoint+p,r);
751  }
752  for (r=0; r < 3; r++) {
753  CV_MAT_ELEM(*points3DSingleView,float,p,r) =
754  CV_MAT_ELEM(*corners3dMat,float,nextPoint+p,r);
755  }
756  }
757  nextPoint+=nrPoints;
758  cvFindExtrinsicCameraParams2(//corners3dMat, points2dMat,
759  points3DSingleView, points2DSingleView,
760  camMatrix, distortMatrix,
761  rotVector, transVector);
762  for (int r=0; r < 3; r++) {
763  CV_MAT_ELEM(*rotVectors,float,n,r) =
764  CV_MAT_ELEM(*rotVector,float,0,r);
765  CV_MAT_ELEM(*transVectors,float,n,r) =
766  CV_MAT_ELEM(*transVector,float,0,r);
767  }
768  }
769  } else {
770  cvCalibrateCamera2(corners3dMat, points2dMat,
771  pointCountMat, cvSize(width, height),
772  camMatrix, distortMatrix,
773  rotVectors, transVectors, flags);
774  }
775 
776  for (unsigned int i=0;i<3;i++) {
777  for (unsigned int j=0;j<3;j++) {
778  camera_matrix[i][j]= CV_MAT_ELEM(*camMatrix,float,i,j);
779  }
780  }
781  memcpy(distortion.GetData(),distortMatrix->data.fl,sizeof(float)*4);
782  CvMat *dummyRot= cvCreateMat(1,3,CV_32FC1);
783  CvMat *dummyRes= cvCreateMat(3,3,CV_32FC1);
784  for (int i=0; i<numImages; i++) {
785  dummyRot->data.fl= &(rotVectors->data.fl[i*3]);
786  cvRodrigues2( dummyRot, dummyRes);
787  memcpy(&rotation_matrices[i*9],dummyRes->data.fl,sizeof(float)*9);
788  translation_vectors= transVectors->data.fl;
789  }
790  cout<<" done."<<endl;
791 
792  // output result
793  PrintExtrinsics(translation_vectors, rotation_matrices, numImages,std::cout);
794  {
795  ofstream ofs("out_extrinsics.txt");
796  PrintExtrinsics(translation_vectors, rotation_matrices, numImages, ofs);
797  cout<<"Wrote result to file out_extrinsics.txt"<<endl;
798  ofs.close();
799  }
800  PrintIntrinsics(distortion.GetData(),
801  camera_matrix.GetData(),
802  std::cout);
803  {
804  ofstream ofs("out_intrinsics.txt");
805  PrintIntrinsics(distortion.GetData(),
806  camera_matrix.GetData(),
807  ofs);
808  cout<<"Wrote result to file out_intrinsics.txt"<<endl;
809  ofs.close();
810  }
811  {
812  // save in BIAS Vector4 format, too.
813  ofstream ofs("out_distortion.txt");
814  PrintDistortionVec4(distortion.GetData(), ofs);
815  cout<<"Wrote result to file out_intrinsics.txt"<<endl;
816  ofs.close();
817  }
818 
819 
820  // display indivisual resulta to disk (same notation for intrinsics betwene CV,BIAS
821  BIAS::KMatrix Kbi;
822  Kbi = GetKfromArr(camera_matrix.GetData());
823  Kbi.Save("out_Kmat.K");
824 
825  BIAS::RMatrix Rbi;
826  BIAS::PMatrix Pbi;
828  BIAS::Vector3<double> lastC;
829  lastC.SetZero();
830  ofstream ofs;
831  for (iImg = 0; iImg < numImages; iImg++) {
832  Rbi = R_cv2bias(GetRfromArr(iImg,rotation_matrices, numImages));
833  Cbi = C_cv2bias(GetCfromArr(iImg, translation_vectors, numImages),
834  GetRfromArr(iImg,rotation_matrices, numImages));
835 
836  // write R for each image
837  imgFilename = string("out_")+FileHandling::Basename(string(argv[iImg+nextParam]))+
838  string(".Rmat");
839  ofs.open(imgFilename.c_str());
840  ofs << Rbi;
841  ofs.close();
842 
843  // write C for each image
844  imgFilename = string("out_")+FileHandling::Basename(string(argv[iImg+nextParam]))+
845  string(".Cmat");
846  ofs.open(imgFilename.c_str());
847  ofs<<Cbi;
848  ofs.close();
849 
850  // compose P from K,R,C and write it for each image.
851  imgFilename = string("out_")+FileHandling::Basename(string(argv[iImg+nextParam]))+
852  string(".P");
853  ofs.open(imgFilename.c_str());
854  Pbi=BIAS::PMatrix( Kbi, Rbi, Cbi );
855  ofs<<Pbi;
856  ofs.close();
857 
858 #ifdef WRITE_VRML
859  if (iImg==0) {
860  // first camera
861  CameraVRML.AddPMatrix(Pbi, width, height, RGBAuc(0,0,255,0));
862  // mark coordinate system:
863  CameraVRML.AddLine(lastC, Cbi, RGBAuc(255,255,0,0));
864  } else {
865  // other cams
866  CameraVRML.AddPMatrix(Pbi, width, height, RGBAuc(0,255,0,0));
867  CameraVRML.AddLine(lastC, Cbi, RGBAuc(255,0,0,0));
868  }
869 #endif // WRITE_VRML
870 
871  // next:
872  lastC=Cbi;
873  }
874  cout<<"Wrote results to out_*.Rmat, out_*.Cmat and out_*.P"<<endl;
875 
876 #ifdef WRITE_VRML
877  const double scale=1.0;
878  // mark coordinate system:
879  CameraVRML.AddLine(Vector3<double>(0,0,0),
880  scale*Vector3<double>(1,0,0), RGBAuc(255,0,0,0));
881  CameraVRML.AddLine(Vector3<double>(0,0,0),
882  scale*Vector3<double>(0,1,0), RGBAuc(0,255,0,0));
883  CameraVRML.AddLine(Vector3<double>(0,0,0),
884  scale*Vector3<double>(0,0,1), RGBAuc(0,0,255,0));
885 
886  // save to disk:
887  CameraVRML.VRMLOut(outFilenameVRML);
888  cout<<"wrote vrml \""<<outFilenameVRML<<"\""<<endl;
889 #endif // WRITE_VRML
890 
891  CvPoint2D32f *backprojPts2d =
892  ConvertWorldToPixel(corners3d, numImages, cornersFound,
893  camera_matrix.GetData(), translation_vectors,
894  rotation_matrices, xCorners, yCorners);
895  // display undistortion result:
896  if (usegui) {
897  cvNamedWindow("Undistorted", CV_WINDOW_AUTOSIZE);
898  cvMoveWindow("Undistorted", 0,0);
899  cout<<"Opened GUI"<<endl;
900  }
901 
902  for (iImg = 0; iImg < numImages; iImg++) {
903  // Load all the input images again for undistortion
904  imgFilename = argv[iImg+nextParam];
905  if (ImageIO::Load(imgFilename.c_str(), biasImg) == 0) {
906 #ifdef BIAS_HAVE_OPENCV
907  ImageConvert::BIAS2ipl(biasImg, image);
908 #else
909  BIASERR("No support to convert image loaded by BIAS into OpenCV format!");
910 #endif
911  } else {
912  BIASERR("Failed to load image with BIAS! Trying OpenCV routines, now...");
913  image = cvLoadImage(imgFilename.c_str());
914  if (image == NULL){
915  BIASERR("Failed to load image " << imgFilename
916  << "with OpenCV either! Aborting.");
917  BIASBREAK;
918  BIASABORT;
919  }
920  }
921  cout << "Loaded and converted image " << imgFilename.c_str() << "." << endl;
922 
923  // Create undistorted image (grayscale for grayscale input images)
924  undistort = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U,
925  image->nChannels);
926  cvUndistort2(image, undistort, camMatrix, distortMatrix);
927 
928  DrawPoints(image, &backprojPts2d[iImg*cornersFound[iImg]],
929  cornersFound[iImg], xCorners,yCorners);
930  if (usegui) {
931  cvShowImage("Image", image);
932  cvWaitKey(1);
933  }
934  DrawPoints(undistort, &backprojPts2d[iImg*cornersFound[iImg]],
935  cornersFound[iImg], xCorners,yCorners);
936  if (usegui) {
937  cvShowImage("Undistorted", undistort);
938  cvWaitKey(1);
939  }
940  cout << "Drawed checkerboard corners into image" << endl;
941  outFilename = FileHandling::Basename(imgFilename) +"_backproject.jpg";
942  cvSaveImage(outFilename.c_str(), image);
943 
944  outFilename = FileHandling::Basename(imgFilename) +"_backproject_undistorted.jpg";
945  cvSaveImage(outFilename.c_str(), undistort);
946 
947  cout << "Wrote images to files" << endl;
948  cvReleaseImage(&image);
949  cvReleaseImage(&undistort);
950  }
951  cout << "Wrote backprojected images to files" << endl;
952 
953  if (darttest) {
954  // attach Dart client XML data for submission to dart server (JW):
955  cout<<endl
956  <<"<DartMeasurementFile name=\"chess7x4_003_"
957  <<"findChessBoardCornerGuesses.jpg\" type=\"image/jpeg\">"
958  <<"chess7x4_003_findChessBoardCornerGuesses.jpg"
959  <<"</DartMeasurementFile>"<<endl
960  <<"<DartMeasurementFile name=\"chess7x4_003_backproject_"
961  <<"undistorted.jpg\" type=\"image/jpeg\">chess7x4_003_backproject_"
962  <<"undistorted.jpg</DartMeasurementFile>"<<endl;
963  }
964 
965  //// setup xmls camera file (grest)
966  ofstream outXML("out_cameraParam.xml");
967  outXML<<"<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>"<<endl;
968  outXML<<"<!-- File created from MIP/calibrateIntrinsics with K-Matrix"<<endl;
969  for (unsigned int i=0;i<3; i++) {
970  for (unsigned int j=0;j<3; j++) {
971  outXML<<setw(DIGW)<<setprecision(DIGPREC)<<Kbi[i][j]<<" ";
972  }
973  outXML<<endl;
974  }
975  outXML<<"-->"<<endl;
976  outXML<<" <camera version=\"2.0\">"<<endl;
977  outXML<<"<!--\"Model\" is an arbitrary camera name. "<<endl;
978  outXML<<" \"SerialID\" is i.e. the camera firewire-bus ID."<<endl;
979  outXML<<" \"ImageWidth\" and \"ImageHeight\" are in pixel."<<endl;
980  outXML<<" \"CellSizeX\" is the size of one CCD-cell in meter."<<endl;
981  outXML<<" \"AspectRatio\" is CellsizeX/CellSizeY "
982  <<"(same as FocalLengthY/FocalLengthX).-->"<<endl;
983  outXML<<" <Sensor AspectRatio=\""
984  <<setprecision(10)<<Kbi[1][1]/Kbi[0][0]<<"\""<<endl;
985  outXML<<" CellSizeX=\"1\" Model=\""<<FileHandling::Basename(imgFilename)
986  <<"\" "<<endl;
987  outXML<<" ImageHeight=\""<<height<<"\" ImageWidth=\""<<width<<"\""<<endl;
988  outXML<<" SerialID=\"666\" />"<<endl;
989  outXML<<" <!--\"Model\" is an arbitrary name. \"Type\" can be either "
990  <<"\"Spherical\" or \"Perspective\"--> "<<endl;
991  outXML<<" <Lens Model=\"not specified\" Type=\"Perspective\" > "<<endl;
992  outXML<<" <PerspectiveCalib>"<<endl;
993  outXML<<" <!--\"FocalLength\" is FocalLengthX in meters, "
994  <<"if you want to give it in pixel set \"CellSizeX\"=1."<<endl;
995  outXML<<" k1 and k2 are radial distortion; p1, p2 are "
996  <<" tangential distortion. -->"<<endl;
997  outXML<<" <Default p1=\"0\" p2=\"0\" k1=\""
998  <<setprecision(10)<<distortion[0]<<"\" k2=\""<< setprecision(10)
999  <<distortion[1]<<"\" FocalLength=\""<<Kbi[0][0]<<"\" />"<<endl;
1000  outXML<<" </PerspectiveCalib>"<<endl;
1001  outXML<<" <VignetteCalib>"<<endl;
1002  outXML<<" <!--The measurements for vignette calibration relate the "
1003  <<"distance of a pixel from the image principal point to an absorbtion "
1004  <<"factor for the corresponding image pixels.--> "<<endl;
1005  outXML<<" </VignetteCalib>"<<endl;
1006  outXML<<" </Lens>"<<endl;
1007  outXML<<" <!--The \"PrincipalPoint\" is given as a fraction of "
1008  <<"\"ImageWidth\"/\"ImageHeight\" with (0.5,0.5) is the image center.-->"
1009  <<endl;
1010  outXML<<" <PrincipalPoint X=\""
1011  <<setprecision(10)<<Kbi[0][2]/(double)(width-1)<<"\" "<<endl;
1012  outXML<<" Y=\""
1013  <<setprecision(10)<<Kbi[1][2]/(double)(height-1)<<"\" />"<<endl;
1014  outXML<<" </camera>"<<endl;
1015  outXML.close();
1016 
1017  cout<<"MIP camera parameter file written to out_cameraParam.xml" << endl;
1018 
1019  //create and write projection xml-file
1020  BIAS::Projection proj;
1021  BIAS::Pose pose;
1022  Quaternion<double> quat;
1023  Rbi.GetQuaternion(quat);
1024  pose.Set(quat,Cbi);
1025  std::vector<double> distortionDouble(4,0.0);
1026  distortionDouble[0] = distortion[0];
1027  distortionDouble[1] = distortion[1];
1028  distortionDouble[2] = distortion[2];
1029  distortionDouble[3] = distortion[3];
1031  proj.CreatePerspective(pose,Kbi,width,height,radDistType,distortionDouble);
1032 
1033  // Create tree and base node for XML-file...
1034 #ifdef BIAS_HAVE_XML2
1035  XMLIO tree;
1036  xmlNodePtr root = tree.create("Projection");
1037  tree.addAttribute(root, "Version", 0.1);
1038 
1039  // ...write data to XML-tree...
1040  proj.XMLOut(root,tree);
1041 
1042  // ...if XML-file has been written...
1043  if (tree.write("out_projParam.xml") == 0){
1044  cout << "MIP projection parameter file written to out_projParam.xml" << endl;
1045  // ...clear tree
1046  tree.clear();
1047  } else {
1048  cout << "Failed to write MIP projection parameter file to "
1049  << "out_projParam.xml!" << endl;
1050  }
1051 #endif
1052 
1053  if (usegui) cvDestroyAllWindows();
1054  delete cornersArray;
1055  delete corners3d;
1056  delete cornersFound;
1057  return 0;
1058 }
void addAttribute(const xmlNodePtr Node, const std::string &AttributeName, bool AttributeValue)
Add an attribute to a node.
Definition: XMLIO.cpp:156
const T * GetData() const
get the data pointer the member function itself is const (before {..}) because it doesn&#39;t change the ...
Definition: Vector3.hh:202
int write(const std::string &Filename, bool AutoAddCompressionSuffix=true) const
Write the whole tree that was constructed in memory to disk.
Definition: XMLIO.cpp:379
int Set(const PoseParametrization &pose)
Set pose from pose parametrization.
Definition: Pose.cpp:140
void SetZero()
set all values to 0
Definition: Vector4.hh:702
Unified output of 3D entities via OpenGL or VRML.
Definition: ThreeDOut.hh:349
void DisableDestructorWarning()
Uses this just before end of your program to avoid error from destructor.
Definition: Param.hh:513
xmlNodePtr create(const std::string &RootNodeName)
Create the base of a new XML-Tree in memory, already with a one and only root node.
Definition: XMLIO.cpp:88
void SetZero()
set all values to 0
Definition: Vector3.hh:559
bool * AddParamBool(const std::string &name, const std::string &help, bool deflt=false, char cmdshort=0, int Group=GRP_NOSHOW)
Definition: Param.cpp:305
configuration struct for drawing styles of various 3d objects
Definition: ThreeDOut.hh:309
int ParseCommandLine(int &argc, char *argv[])
scan command line arguments for valid parameters
Definition: Param.cpp:1028
bool * GetParamBool(const std::string &name) const
Definition: Param.cpp:633
3D rotation matrix
Definition: RMatrix.hh:49
bool Save(const std::string &fname) const
Definition: Matrix3x3.cpp:563
void Usage(std::ostream &os=std::cout)
print Help-Information to stdout
Definition: Param.cpp:176
Represents 3d pose transformations, parametrized as Euclidean translation and unit quaternion orienta...
Definition: Pose.hh:73
Wrapper class for reading and writing XML files based on the XML library libxml2. ...
Definition: XMLIO.hh:72
static std::string Basename(const std::string &fullname)
Get file base name without path from given path and filename.
This class hides the underlying projection model, like projection matrix, spherical camera...
Definition: Projection.hh:70
std::string * GetParamString(const std::string &name) const
Definition: Param.cpp:649
void SetIdentity()
set the elements of this matrix to the matrix 1 0 0 0 0 1 0 0 0 0 1 0 which is no strict identity (!)...
Definition: Matrix3x4.hh:240
BIAS::Vector4< unsigned char > RGBAuc
Definition: RGBA.hh:47
class BIASGeometry_EXPORT PMatrix
is a &#39;fixed size&#39; quadratic matrix of dim.
Definition: Matrix.hh:54
virtual int XMLOut(const xmlNodePtr Node, XMLIO &XMLObject) const
specialization of XML write function for BIAS::Projection.
Definition: Projection.cpp:468
This class Param provides generic support for parameters.
Definition: Param.hh:231
Matrix3x3< T > Transpose() const
returns transposed matrix tested 12.06.2002
Definition: Matrix3x3.cpp:167
const T * GetData() const
get the data pointer the member function itself is const (before {..}) because it doesn&#39;t change the...
Definition: Vector4.hh:177
void clear()
Definition: XMLIO.cpp:74
static int Load(const std::string &FileName, ImageBase &img)
first tries a call to Read MIP image and if that fails, tries to Import Image with all other availabl...
Definition: ImageIO.cpp:141
static int BIAS2ipl(const Image< StorageType > &source, IplImage *&dest)
Returns a new, separate IplImage for use with OpenCV created rom the source BIAS Image.
K describes the mapping from world coordinates (wcs) to pixel coordinates (pcs).
Definition: KMatrix.hh:48
void CreatePerspective(const BIAS::Pose &pose, const BIAS::KMatrix &K, int width, int height, BIAS_ProjParaPersp_DISTORTION_TYPE radDistType=DISTYPE_DEF, const std::vector< double > &UndistortionCoefficients=std::vector< double >(4, 0.0))
Create a perspective camera and add to projection.
Definition: Projection.cpp:133
int SetEnhancedFlag(const std::string &name, bool enhanced)
if a parametr is marked as enhanced, it is hidden from the naive user
Definition: Param.cpp:957
describes a projective 3D -&gt; 2D mapping in homogenous coordinates
Definition: PMatrix.hh:88
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
void SetIdentity()
set the elements of this matrix to the identity matrix (possibly overriding the inherited method) ...
Definition: Matrix3x3.hh:429