ViSP  2.9.0
vpCalibration.cpp
1 /****************************************************************************
2  *
3  * $Id: vpCalibration.cpp 4663 2014-02-14 10:32:11Z fspindle $
4  *
5  * This file is part of the ViSP software.
6  * Copyright (C) 2005 - 2014 by INRIA. All rights reserved.
7  *
8  * This software is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * ("GPL") version 2 as published by the Free Software Foundation.
11  * See the file LICENSE.txt at the root directory of this source
12  * distribution for additional information about the GNU GPL.
13  *
14  * For using ViSP with software that can not be combined with the GNU
15  * GPL, please contact INRIA about acquiring a ViSP Professional
16  * Edition License.
17  *
18  * See http://www.irisa.fr/lagadic/visp/visp.html for more information.
19  *
20  * This software was developed at:
21  * INRIA Rennes - Bretagne Atlantique
22  * Campus Universitaire de Beaulieu
23  * 35042 Rennes Cedex
24  * France
25  * http://www.irisa.fr/lagadic
26  *
27  * If you have questions regarding the use of this file, please contact
28  * INRIA at visp@inria.fr
29  *
30  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
31  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
32  *
33  *
34  * Description:
35  * Camera calibration.
36  *
37  * Authors:
38  * Eric Marchand
39  * Francois Chaumette
40  * Anthony Saunier
41  *
42  *****************************************************************************/
43 
44 
50 #include <visp/vpCalibration.h>
51 #include <visp/vpDebug.h>
52 #include <visp/vpPose.h>
53 #include <visp/vpPixelMeterConversion.h>
54 
55 double vpCalibration::threshold = 1e-10f;
56 unsigned int vpCalibration::nbIterMax = 4000;
57 double vpCalibration::gain = 0.25;
62 {
63  npt = 0 ;
64 
65  residual = residual_dist = 1000.;
66 
67  LoX.clear() ;
68  LoY.clear() ;
69  LoZ.clear() ;
70  Lip.clear() ;
71 
72  return 0 ;
73 }
74 
79  : cMo(), cMo_dist(), cam(), cam_dist(), rMe(), eMc(), eMc_dist(),
80  npt(0), LoX(), LoY(), LoZ(), Lip(), residual(1000.), residual_dist(1000.)
81 {
82  init() ;
83 }
88  : cMo(), cMo_dist(), cam(), cam_dist(), rMe(), eMc(), eMc_dist(),
89  npt(0), LoX(), LoY(), LoZ(), Lip(), residual(1000.), residual_dist(1000.)
90 {
91  (*this) = c;
92 }
93 
94 
99 {
100  clearPoint() ;
101 }
102 
109 {
110  npt = twinCalibration.npt ;
111  LoX = twinCalibration.LoX ;
112  LoY = twinCalibration.LoY ;
113  LoZ = twinCalibration.LoZ ;
114  Lip = twinCalibration.Lip ;
115 
116  residual = twinCalibration.residual;
117  cMo = twinCalibration.cMo;
118  residual_dist = twinCalibration.residual_dist;
119  cMo_dist = twinCalibration.cMo_dist ;
120 
121  cam = twinCalibration.cam ;
122  cam_dist = twinCalibration.cam_dist ;
123 
124  rMe = twinCalibration.rMe;
125 
126  eMc = twinCalibration.eMc;
127  eMc_dist = twinCalibration.eMc_dist;
128 
129  return (*this);
130 }
131 
132 
137 {
138  LoX.clear() ;
139  LoY.clear() ;
140  LoZ.clear() ;
141  Lip.clear() ;
142  npt = 0 ;
143 
144  return 0 ;
145 }
146 
153 int vpCalibration::addPoint(double X, double Y, double Z, vpImagePoint &ip)
154 {
155  LoX.push_back(X);
156  LoY.push_back(Y);
157  LoZ.push_back(Z);
158 
159  Lip.push_back(ip);
160 
161  npt++ ;
162 
163  return 0 ;
164 }
165 
171 void vpCalibration::computePose(const vpCameraParameters &camera, vpHomogeneousMatrix &cMo_est)
172 {
173  // The vpPose class mainly contents a list of vpPoint (that is (X,Y,Z, x, y) )
174  vpPose pose ;
175  // the list of point is cleared (if that's not done before)
176  pose.clearPoint() ;
177  // we set the 3D points coordinates (in meter !) in the object/world frame
178  std::list<double>::const_iterator it_LoX = LoX.begin();
179  std::list<double>::const_iterator it_LoY = LoY.begin();
180  std::list<double>::const_iterator it_LoZ = LoZ.begin();
181  std::list<vpImagePoint>::const_iterator it_Lip = Lip.begin();
182 
183  for (unsigned int i =0 ; i < npt ; i++)
184  {
185  vpPoint P;
186  P.setWorldCoordinates(*it_LoX, *it_LoY, *it_LoZ);
187  double x=0,y=0 ;
188  vpPixelMeterConversion::convertPoint(camera, *it_Lip, x,y) ;
189  P.set_x(x) ;
190  P.set_y(y) ;
191 
192  pose.addPoint(P);
193  ++it_LoX;
194  ++it_LoY;
195  ++it_LoZ;
196  ++it_Lip;
197  }
198  vpHomogeneousMatrix cMo_dementhon; // computed pose with dementhon
199  vpHomogeneousMatrix cMo_lagrange; // computed pose with dementhon
200 
201  // compute the initial pose using Lagrange method followed by a non linear
202  // minimisation method
203  // Pose by Lagrange it provides an initialization of the pose
204  pose.computePose(vpPose::LAGRANGE, cMo_lagrange) ;
205  double residual_lagrange = pose.computeResidual(cMo_lagrange);
206 
207  // compute the initial pose using Dementhon method followed by a non linear
208  // minimisation method
209  // Pose by Dementhon it provides an initialization of the pose
210  pose.computePose(vpPose::DEMENTHON, cMo_dementhon) ;
211  double residual_dementhon = pose.computeResidual(cMo_dementhon);
212 
213  //we keep the better initialization
214  if (residual_lagrange < residual_dementhon)
215  cMo_est = cMo_lagrange;
216  else
217  cMo_est = cMo_dementhon;
218 
219  // the pose is now refined using the virtual visual servoing approach
220  // Warning: cMo needs to be initialized otherwise it may diverge
221  pose.computePose(vpPose::VIRTUAL_VS, cMo_est) ;
222 }
223 
232  const vpCameraParameters& camera)
233 {
234  double residual_ = 0 ;
235 
236  std::list<double>::const_iterator it_LoX = LoX.begin();
237  std::list<double>::const_iterator it_LoY = LoY.begin();
238  std::list<double>::const_iterator it_LoZ = LoZ.begin();
239  std::list<vpImagePoint>::const_iterator it_Lip = Lip.begin();
240 
241  double u0 = camera.get_u0() ;
242  double v0 = camera.get_v0() ;
243  double px = camera.get_px() ;
244  double py = camera.get_py() ;
245  vpImagePoint ip;
246 
247  for (unsigned int i =0 ; i < npt ; i++)
248  {
249  double oX = *it_LoX;
250  double oY = *it_LoY;
251  double oZ = *it_LoZ;
252 
253  double cX = oX*cMo_est[0][0]+oY*cMo_est[0][1]+oZ*cMo_est[0][2] + cMo_est[0][3];
254  double cY = oX*cMo_est[1][0]+oY*cMo_est[1][1]+oZ*cMo_est[1][2] + cMo_est[1][3];
255  double cZ = oX*cMo_est[2][0]+oY*cMo_est[2][1]+oZ*cMo_est[2][2] + cMo_est[2][3];
256 
257  double x = cX/cZ ;
258  double y = cY/cZ ;
259 
260  ip = *it_Lip;
261  double u = ip.get_u() ;
262  double v = ip.get_v() ;
263 
264  double xp = u0 + x*px;
265  double yp = v0 + y*py;
266 
267  residual_ += (vpMath::sqr(xp-u) + vpMath::sqr(yp-v)) ;
268 
269  ++it_LoX;
270  ++it_LoY;
271  ++it_LoZ;
272  ++it_Lip;
273  }
274  this->residual = residual_ ;
275  return sqrt(residual_/npt) ;
276 }
285  const vpCameraParameters& camera)
286 {
287  double residual_ = 0 ;
288 
289  std::list<double>::const_iterator it_LoX = LoX.begin();
290  std::list<double>::const_iterator it_LoY = LoY.begin();
291  std::list<double>::const_iterator it_LoZ = LoZ.begin();
292  std::list<vpImagePoint>::const_iterator it_Lip = Lip.begin();
293 
294  double u0 = camera.get_u0() ;
295  double v0 = camera.get_v0() ;
296  double px = camera.get_px() ;
297  double py = camera.get_py() ;
298  double kud = camera.get_kud() ;
299  double kdu = camera.get_kdu() ;
300 
301  double inv_px = 1/px;
302  double inv_py = 1/px;
303  vpImagePoint ip;
304 
305  for (unsigned int i =0 ; i < npt ; i++)
306  {
307  double oX = *it_LoX;
308  double oY = *it_LoY;
309  double oZ = *it_LoZ;
310 
311  double cX = oX*cMo_est[0][0]+oY*cMo_est[0][1]+oZ*cMo_est[0][2] + cMo_est[0][3];
312  double cY = oX*cMo_est[1][0]+oY*cMo_est[1][1]+oZ*cMo_est[1][2] + cMo_est[1][3];
313  double cZ = oX*cMo_est[2][0]+oY*cMo_est[2][1]+oZ*cMo_est[2][2] + cMo_est[2][3];
314 
315  double x = cX/cZ ;
316  double y = cY/cZ ;
317 
318  ip = *it_Lip;
319  double u = ip.get_u() ;
320  double v = ip.get_v() ;
321 
322  double r2ud = 1+kud*(vpMath::sqr(x)+vpMath::sqr(y)) ;
323 
324  double xp = u0 + x*px*r2ud;
325  double yp = v0 + y*py*r2ud;
326 
327  residual_ += (vpMath::sqr(xp-u) + vpMath::sqr(yp-v)) ;
328 
329  double r2du = (vpMath::sqr((u-u0)*inv_px)+vpMath::sqr((v-v0)*inv_py)) ;
330 
331  xp = u0 + x*px - kdu*(u-u0)*r2du;
332  yp = v0 + y*py - kdu*(v-v0)*r2du;
333 
334  residual_ += (vpMath::sqr(xp-u) + vpMath::sqr(yp-v)) ;
335  ++it_LoX;
336  ++it_LoY;
337  ++it_LoZ;
338  ++it_Lip;
339  }
340  residual_ /=2;
341 
342  this->residual_dist = residual_;
343  return sqrt(residual_/npt) ;
344 }
345 
352 void
353  vpCalibration::computeStdDeviation(double &deviation,double &deviation_dist)
354 {
355  deviation = computeStdDeviation(cMo,cam);
356  deviation_dist = computeStdDeviation_dist(cMo_dist,cam_dist);
357 }
358 
359 
372  vpHomogeneousMatrix &cMo_est,
373  vpCameraParameters &cam_est,
374  bool verbose)
375 {
376  try{
377  computePose(cam_est,cMo_est);
378  switch (method)
379  {
380  case CALIB_LAGRANGE :
382  {
383  calibLagrange(cam_est, cMo_est);
384  }
385  break;
386  case CALIB_VIRTUAL_VS:
389  default:
390  break;
391  }
392 
393  switch (method)
394  {
395  case CALIB_VIRTUAL_VS:
399  {
400  if (verbose){std::cout << "start calibration without distortion"<< std::endl;}
401  calibVVS(cam_est, cMo_est, verbose);
402  }
403  break ;
404  case CALIB_LAGRANGE:
405  default:
406  break;
407  }
408  this->cMo = cMo_est;
409  this->cMo_dist = cMo_est;
410 
411  //Print camera parameters
412  if(verbose){
413  // std::cout << "Camera parameters without distortion :" << std::endl;
414  cam_est.printParameters();
415  }
416 
417  this->cam = cam_est;
418 
419  switch (method)
420  {
423  {
424  if (verbose){std::cout << "start calibration with distortion"<< std::endl;}
425  calibVVSWithDistortion(cam_est, cMo_est, verbose);
426  }
427  break ;
428  case CALIB_LAGRANGE:
429  case CALIB_VIRTUAL_VS:
431  default:
432  break;
433  }
434  //Print camera parameters
435  if(verbose){
436  // std::cout << "Camera parameters without distortion :" << std::endl;
437  this->cam.printParameters();
438  // std::cout << "Camera parameters with distortion :" << std::endl;
439  cam_est.printParameters();
440  }
441 
442  this->cam_dist = cam_est ;
443 
444  this->cMo_dist = cMo_est;
445  return 0 ;
446  }
447  catch(...){
448  throw;
449  }
450 }
451 
465  std::vector<vpCalibration> &table_cal,
466  vpCameraParameters& cam_est,
467  double &globalReprojectionError,
468  bool verbose)
469 {
470  try{
471  unsigned int nbPose = (unsigned int) table_cal.size();
472  for(unsigned int i=0;i<nbPose;i++){
473  if(table_cal[i].get_npt()>3)
474  table_cal[i].computePose(cam_est,table_cal[i].cMo);
475  }
476  switch (method) {
477  case CALIB_LAGRANGE :
478  if(nbPose > 1){
479  std::cout << "this calibration method is not available in" << std::endl
480  << "vpCalibration::computeCalibrationMulti()" << std::endl;
481  return -1 ;
482  }
483  else {
484  table_cal[0].calibLagrange(cam_est,table_cal[0].cMo);
485  table_cal[0].cam = cam_est ;
486  table_cal[0].cam_dist = cam_est ;
487  table_cal[0].cMo_dist = table_cal[0].cMo ;
488  }
489  break;
492  if(nbPose > 1){
493  std::cout << "this calibration method is not available in" << std::endl
494  << "vpCalibration::computeCalibrationMulti()" << std::endl
495  << "with several images." << std::endl;
496  return -1 ;
497  }
498  else {
499  table_cal[0].calibLagrange(cam_est,table_cal[0].cMo);
500  table_cal[0].cam = cam_est ;
501  table_cal[0].cam_dist = cam_est ;
502  table_cal[0].cMo_dist = table_cal[0].cMo ;
503  }
504  case CALIB_VIRTUAL_VS:
506  {
507  calibVVSMulti(table_cal, cam_est, globalReprojectionError, verbose);
508  }
509  break ;
510  }
511  //Print camera parameters
512  if(verbose){
513  // std::cout << "Camera parameters without distortion :" << std::endl;
514  cam_est.printParameters();
515  }
516 
517  switch (method)
518  {
519  case CALIB_LAGRANGE :
521  case CALIB_VIRTUAL_VS:
522  verbose = false ;
523  break;
526  {
527  if(verbose)
528  std::cout << "Compute camera parameters with distortion"<<std::endl;
529 
530  calibVVSWithDistortionMulti(table_cal, cam_est, globalReprojectionError, verbose);
531  }
532  break ;
533  }
534  //Print camera parameters
535  if(verbose){
536  // std::cout << "Camera parameters without distortion :" << std::endl;
537  table_cal[0].cam.printParameters();
538  // std::cout << "Camera parameters with distortion:" << std::endl;
539  cam_est.printParameters();
540  std::cout<<std::endl;
541  }
542  return 0 ;
543  }
544  catch(...){ throw; }
545 }
546 
562 int vpCalibration::computeCalibrationTsai(std::vector<vpCalibration> &table_cal,
563  vpHomogeneousMatrix& eMc,
564  vpHomogeneousMatrix& eMc_dist)
565 {
566  try{
567  unsigned int nbPose = (unsigned int)table_cal.size();
568  if (nbPose > 2){
569  std::vector<vpHomogeneousMatrix> table_cMo(nbPose);
570  std::vector<vpHomogeneousMatrix> table_cMo_dist(nbPose);
571  std::vector<vpHomogeneousMatrix> table_rMe(nbPose);
572 
573  for(unsigned int i=0;i<nbPose;i++){
574  table_cMo[i] = table_cal[i].cMo;
575  table_cMo_dist[i] = table_cal[i].cMo_dist;
576  table_rMe[i] = table_cal[i].rMe;
577  }
578  calibrationTsai(table_cMo, table_rMe, eMc);
579  calibrationTsai(table_cMo_dist, table_rMe, eMc_dist);
580 
581  return 0;
582  }
583  else{
584  vpERROR_TRACE("Three images are needed to compute Tsai calibration !\n");
585  return -1;
586  }
587  }
588  catch(...){
589  throw;
590  }
591 }
592 
593 
601 int vpCalibration::writeData(const char *filename)
602 {
603  std::ofstream f(filename) ;
604  vpImagePoint ip;
605 
606  std::list<double>::const_iterator it_LoX = LoX.begin();
607  std::list<double>::const_iterator it_LoY = LoY.begin();
608  std::list<double>::const_iterator it_LoZ = LoZ.begin();
609  std::list<vpImagePoint>::const_iterator it_Lip = Lip.begin();
610 
611  f.precision(10);
612  f.setf(std::ios::fixed,std::ios::floatfield);
613  f << LoX.size() << std::endl ;
614 
615  for (unsigned int i =0 ; i < LoX.size() ; i++)
616  {
617 
618  double oX = *it_LoX;
619  double oY = *it_LoY;
620  double oZ = *it_LoZ;
621 
622  ip = *it_Lip;
623  double u = ip.get_u() ;
624  double v = ip.get_v() ;
625 
626  f << oX <<" " << oY << " " << oZ << " " << u << " " << v <<std::endl ;
627 
628  ++it_LoX;
629  ++it_LoY;
630  ++it_LoZ;
631  ++it_Lip;
632 
633  }
634 
635  f.close() ;
636  return 0 ;
637 }
638 
645 int vpCalibration::readData(const char* filename)
646 {
647  vpImagePoint ip;
648  std::ifstream f;
649  f.open(filename);
650  if (! f.fail()){
651  unsigned int n ;
652  f >> n ;
653  std::cout << "There are "<< n <<" point on the calibration grid " << std::endl ;
654 
655  clearPoint() ;
656 
657  if (n > 100000)
658  throw(vpException(vpException::badValue, "Bad number of point in the calibration grid"));
659 
660  for (unsigned int i=0 ; i < n ; i++)
661  {
662  double x, y, z, u, v ;
663  f >> x >> y >> z >> u >> v ;
664  std::cout << x <<" "<<y <<" "<<z<<" "<<u<<" "<<v <<std::endl ;
665  ip.set_u( u );
666  ip.set_v( v );
667  addPoint(x, y, z, ip) ;
668  }
669 
670  f.close() ;
671  return 0 ;
672  }
673  else{
674  return -1;
675  }
676 }
693 int vpCalibration::readGrid(const char* filename, unsigned int &n,
694  std::list<double> &oX, std::list<double> &oY, std::list<double> &oZ, bool verbose)
695 {
696  try{
697  std::ifstream f;
698  f.open(filename);
699  if (! f.fail()){
700 
701  f >> n ;
702  if(verbose)
703  std::cout << "There are "<< n <<" points on the calibration grid " << std::endl ;
704  int no_pt;
705  double x,y,z;
706 
707  // clear the list
708  oX.clear();
709  oY.clear();
710  oZ.clear();
711 
712  if (n > 100000)
713  throw(vpException(vpException::badValue, "Bad number of point in the calibration grid"));
714 
715  for (unsigned int i=0 ; i < n ; i++)
716  {
717  f >> no_pt >> x >> y >> z ;
718  if(verbose){
719  std::cout << no_pt <<std::endl ;
720  std::cout << x <<" "<< y <<" "<< z <<std::endl ;
721  }
722  oX.push_back(x) ;
723  oY.push_back(y) ;
724  oZ.push_back(z) ;
725  }
726 
727  f.close() ;
728  }
729  else{
730  return -1;
731  }
732  }
733  catch(...){return -1;}
734  return 0 ;
735 }
736 
745  unsigned int thickness)
746 {
747 
748  for (std::list<vpImagePoint>::const_iterator it = Lip.begin(); it != Lip.end(); ++ it) {
749  vpDisplay::displayCross(I, *it, 12, color, thickness) ;
750  }
751  return 0 ;
752 }
753 
762  unsigned int thickness)
763 {
764  double u0_dist = cam_dist.get_u0() ;
765  double v0_dist = cam_dist.get_v0() ;
766  double px_dist = cam_dist.get_px() ;
767  double py_dist = cam_dist.get_py() ;
768  double kud_dist = cam_dist.get_kud() ;
769  // double kdu_dist = cam_dist.get_kdu() ;
770 
771  // double u0 = cam.get_u0() ;
772  // double v0 = cam.get_v0() ;
773  // double px = cam.get_px() ;
774  // double py = cam.get_py() ;
775 
776  std::list<double>::const_iterator it_LoX = LoX.begin();
777  std::list<double>::const_iterator it_LoY = LoY.begin();
778  std::list<double>::const_iterator it_LoZ = LoZ.begin();
779 
780  for (unsigned int i =0 ; i < npt ; i++)
781  {
782  double oX = *it_LoX;
783  double oY = *it_LoY;
784  double oZ = *it_LoZ;
785 
786  double cX = oX*cMo[0][0]+oY*cMo[0][1]+oZ*cMo[0][2] + cMo[0][3];
787  double cY = oX*cMo[1][0]+oY*cMo[1][1]+oZ*cMo[1][2] + cMo[1][3];
788  double cZ = oX*cMo[2][0]+oY*cMo[2][1]+oZ*cMo[2][2] + cMo[2][3];
789 
790  double x = cX/cZ ;
791  double y = cY/cZ ;
792 
793  // double xp = u0 + x*px ;
794  // double yp = v0 + y*py ;
795 
796  // vpDisplay::displayCross(I,(int)vpMath::round(yp), (int)vpMath::round(xp),
797  // 5,col) ;
798 
799  cX = oX*cMo_dist[0][0]+oY*cMo_dist[0][1]+oZ*cMo_dist[0][2]+cMo_dist[0][3];
800  cY = oX*cMo_dist[1][0]+oY*cMo_dist[1][1]+oZ*cMo_dist[1][2]+cMo_dist[1][3];
801  cZ = oX*cMo_dist[2][0]+oY*cMo_dist[2][1]+oZ*cMo_dist[2][2]+cMo_dist[2][3];
802 
803  x = cX/cZ ;
804  y = cY/cZ ;
805 
806  double r2 = 1+kud_dist*(vpMath::sqr(x)+vpMath::sqr(y)) ;
807 
808  vpImagePoint ip;
809  ip.set_u( u0_dist + x*px_dist*r2 );
810  ip.set_v( v0_dist + y*py_dist*r2 );
811 
812  vpDisplay::displayCross(I, ip, 6, color, thickness) ;
814 
815  // std::cout << oX << " " << oY << " " <<oZ << std::endl ;
816  // I.getClick() ;
817  ++it_LoX;
818  ++it_LoY;
819  ++it_LoZ;
820  }
821  return 0;
822 }
823 
824 #ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
825 
842  unsigned int nbPose,
843  vpCalibration table_cal[],
844  vpCameraParameters& cam_est,
845  bool verbose)
846 {
847  try{
848  for(unsigned int i=0;i<nbPose;i++){
849  if(table_cal[i].get_npt()>3)
850  table_cal[i].computePose(cam_est,table_cal[i].cMo);
851  }
852  switch (method) {
853  case CALIB_LAGRANGE :
854  if(nbPose > 1){
855  std::cout << "this calibration method is not available in" << std::endl
856  << "vpCalibration::computeCalibrationMulti()" << std::endl;
857  return -1 ;
858  }
859  else {
860  table_cal[0].calibLagrange(cam_est,table_cal[0].cMo);
861  table_cal[0].cam = cam_est ;
862  table_cal[0].cam_dist = cam_est ;
863  table_cal[0].cMo_dist = table_cal[0].cMo ;
864  }
865  break;
868  if(nbPose > 1){
869  std::cout << "this calibration method is not available in" << std::endl
870  << "vpCalibration::computeCalibrationMulti()" << std::endl
871  << "with several images." << std::endl;
872  return -1 ;
873  }
874  else {
875  table_cal[0].calibLagrange(cam_est,table_cal[0].cMo);
876  table_cal[0].cam = cam_est ;
877  table_cal[0].cam_dist = cam_est ;
878  table_cal[0].cMo_dist = table_cal[0].cMo ;
879  }
880  case CALIB_VIRTUAL_VS:
882  {
883  calibVVSMulti(nbPose, table_cal, cam_est, verbose);
884  }
885  break ;
886  }
887  //Print camera parameters
888  if(verbose){
889  // std::cout << "Camera parameters without distortion :" << std::endl;
890  cam_est.printParameters();
891  }
892 
893  switch (method)
894  {
895  case CALIB_LAGRANGE :
897  case CALIB_VIRTUAL_VS:
898  verbose = false ;
899  break;
902  {
903  if(verbose)
904  std::cout << "Compute camera parameters with distortion"<<std::endl;
905 
906  calibVVSWithDistortionMulti(nbPose, table_cal, cam_est, verbose);
907  }
908  break ;
909  }
910  //Print camera parameters
911  if(verbose){
912  // std::cout << "Camera parameters without distortion :" << std::endl;
913  table_cal[0].cam.printParameters();
914  // std::cout << "Camera parameters with distortion:" << std::endl;
915  cam_est.printParameters();
916  std::cout<<std::endl;
917  }
918  return 0 ;
919  }
920  catch(...){ throw; }
921 }
922 
943  vpCalibration table_cal[],
944  vpHomogeneousMatrix& eMc,
945  vpHomogeneousMatrix& eMc_dist)
946 {
947  try{
948  if (nbPose > 2){
949  vpHomogeneousMatrix* table_cMo = new vpHomogeneousMatrix[nbPose];
950  vpHomogeneousMatrix* table_cMo_dist = new vpHomogeneousMatrix[nbPose];
951  vpHomogeneousMatrix* table_rMe = new vpHomogeneousMatrix[nbPose];
952 
953  for(unsigned int i=0;i<nbPose;i++){
954  table_cMo[i] = table_cal[i].cMo;
955  table_cMo_dist[i] = table_cal[i].cMo_dist;
956  table_rMe[i] = table_cal[i].rMe;
957  }
958  calibrationTsai(nbPose,table_cMo,table_rMe,eMc);
959  calibrationTsai(nbPose,table_cMo_dist,table_rMe,eMc_dist);
960 
961  delete [] table_cMo;
962  delete [] table_cMo_dist;
963  delete [] table_rMe;
964 
965  return 0;
966  }
967  else{
968  vpERROR_TRACE("Three images are needed to compute Tsai calibration !\n");
969  return -1;
970  }
971  }
972  catch(...){
973  throw;
974  }
975 }
976 
996 int vpCalibration::readGrid(const char* filename,unsigned int &n,
997  vpList<double> &oX,vpList<double> &oY,vpList<double> &oZ, bool verbose)
998 {
999  try{
1000  std::ifstream f;
1001  f.open(filename);
1002  if (! f.fail()){
1003 
1004  f >> n ;
1005  if(verbose)
1006  std::cout << "There are "<< n <<" points on the calibration grid " << std::endl ;
1007  int no_pt;
1008  double x,y,z;
1009 
1010  oX.front();
1011  oY.front();
1012  oZ.front();
1013 
1014  if (n > 100000)
1015  throw(vpException(vpException::badValue, "Bad number of point in the calibration grid"));
1016 
1017  for (unsigned int i=0 ; i < n ; i++)
1018  {
1019  f >> no_pt >> x >> y >> z ;
1020  if(verbose){
1021  std::cout << no_pt <<std::endl ;
1022  std::cout << x <<" "<< y <<" "<< z <<std::endl ;
1023  }
1024  oX.addRight(x) ;
1025  oY.addRight(y) ;
1026  oZ.addRight(z) ;
1027  }
1028 
1029  f.close() ;
1030  }
1031  else{
1032  return -1;
1033  }
1034  }
1035  catch(...){return -1;}
1036  return 0 ;
1037 }
1038 
1039 #endif // VISP_BUILD_DEPRECATED_FUNCTIONS
double get_v() const
Definition: vpImagePoint.h:263
double get_u0() const
int displayGrid(vpImage< unsigned char > &I, vpColor color=vpColor::yellow, unsigned int thickness=1)
int computeCalibration(vpCalibrationMethodType method, vpHomogeneousMatrix &cMo_est, vpCameraParameters &cam_est, bool verbose=false)
The class provides a data structure for the homogeneous matrices as well as a set of operations on th...
#define vpERROR_TRACE
Definition: vpDebug.h:395
Provide simple list management.
Definition: vpList.h:113
int readData(const char *filename)
Class to define colors available for display functionnalities.
Definition: vpColor.h:125
double get_u() const
Definition: vpImagePoint.h:252
error that can be emited by ViSP classes.
Definition: vpException.h:76
int addPoint(double X, double Y, double Z, vpImagePoint &ip)
void set_x(const double x)
Set the point x coordinate in the image plane.
Definition: vpPoint.h:194
static void convertPoint(const vpCameraParameters &cam, const double &u, const double &v, double &x, double &y)
Point coordinates conversion from pixel coordinates to normalized coordinates in meter...
double get_py() const
Tools for perspective camera calibration.
Definition: vpCalibration.h:78
virtual ~vpCalibration()
vpHomogeneousMatrix cMo
(as a 3x4 matrix [R T])
Definition: vpCalibration.h:92
Class that defines what is a point.
Definition: vpPoint.h:65
vpCalibration & operator=(const vpCalibration &twinCalibration)
int displayData(vpImage< unsigned char > &I, vpColor color=vpColor::red, unsigned int thickness=1)
int clearPoint()
Suppress all the point in the array of point.
double get_v0() const
void set_u(const double u)
Definition: vpImagePoint.h:216
static double sqr(double x)
Definition: vpMath.h:106
void front(void)
Position the current element on the first element of the list.
Definition: vpList.h:384
vpHomogeneousMatrix cMo_dist
Definition: vpCalibration.h:94
virtual void displayCross(const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness=1)=0
void set_v(const double v)
Definition: vpImagePoint.h:227
Class used for pose computation from N points (pose from point only).
Definition: vpPose.h:78
Generic class defining intrinsic camera parameters.
void addRight(const type &el)
add a new element in the list, at the right of the current one
Definition: vpList.h:478
vpHomogeneousMatrix eMc_dist
void set_y(const double y)
Set the point y coordinate in the image plane.
Definition: vpPoint.h:196
unsigned int get_npt() const
get the number of points
double get_px() const
vpHomogeneousMatrix rMe
reference coordinates (manipulator base coordinates)
double computeStdDeviation_dist(const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam)
static void calibrationTsai(std::vector< vpHomogeneousMatrix > &cMo, std::vector< vpHomogeneousMatrix > &rMe, vpHomogeneousMatrix &eMc)
calibration method of effector-camera from R. Tsai and R. Lorenz .
double get_kud() const
vpCameraParameters cam_dist
projection model with distortion
Definition: vpCalibration.h:99
double get_kdu() const
int writeData(const char *filename)
vpHomogeneousMatrix eMc
position of the camera in relation to the effector
void computePose(vpPoseMethodType methode, vpHomogeneousMatrix &cMo)
compute the pose for a given method
Definition: vpPose.cpp:386
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:92
static int computeCalibrationTsai(std::vector< vpCalibration > &table_cal, vpHomogeneousMatrix &eMc, vpHomogeneousMatrix &eMc_dist)
Compute the multi-image calibration of effector-camera from R. Tsai and R. Lenz . ...
void computeStdDeviation(double &deviation, double &deviation_dist)
vpCameraParameters cam
projection model without distortion
Definition: vpCalibration.h:97
static int computeCalibrationMulti(vpCalibrationMethodType method, std::vector< vpCalibration > &table_cal, vpCameraParameters &cam, double &globalReprojectionError, bool verbose=false)
void addPoint(const vpPoint &P)
Add a new point in this array.
Definition: vpPose.cpp:155
double computeResidual(const vpHomogeneousMatrix &cMo) const
Compute and return the residual expressed in meter for the pose matrix 'cMo'.
Definition: vpPose.cpp:344
static int readGrid(const char *filename, unsigned int &n, std::list< double > &oX, std::list< double > &oY, std::list< double > &oZ, bool verbose=false)
void setWorldCoordinates(const double ox, const double oy, const double oz)
Set the point world coordinates. We mean here the coordinates of the point in the object frame...
Definition: vpPoint.cpp:74
void clearPoint()
suppress all the point in the array of point
Definition: vpPose.cpp:133