Visual Servoing Platform  version 3.0.0
vpXmlParserCamera.cpp
1 /****************************************************************************
2  *
3  * This file is part of the ViSP software.
4  * Copyright (C) 2005 - 2015 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * ("GPL") version 2 as published by the Free Software Foundation.
9  * See the file LICENSE.txt at the root directory of this source
10  * distribution for additional information about the GNU GPL.
11  *
12  * For using ViSP with software that can not be combined with the GNU
13  * GPL, please contact Inria about acquiring a ViSP Professional
14  * Edition License.
15  *
16  * See http://visp.inria.fr for more information.
17  *
18  * This software was developed at:
19  * Inria Rennes - Bretagne Atlantique
20  * Campus Universitaire de Beaulieu
21  * 35042 Rennes Cedex
22  * France
23  *
24  * If you have questions regarding the use of this file, please contact
25  * Inria at visp@inria.fr
26  *
27  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29  *
30  * Description:
31  * XML parser to load and save camera intrinsic parameters.
32  *
33  * Authors:
34  * Anthony Saunier
35  *
36  *****************************************************************************/
37 
38 
45 #include <visp3/core/vpXmlParserCamera.h>
46 #ifdef VISP_HAVE_XML2
47 
48 #include <stdlib.h>
49 #include <string.h>
50 
51 #include <visp3/core/vpDebug.h>
52 /* -------------------------------------------------------------------------- */
53 /* --- LABEL XML ------------------------------------------------------------ */
54 /* -------------------------------------------------------------------------- */
55 
56 #define LABEL_XML_ROOT "root"
57 #define LABEL_XML_CAMERA "camera"
58 #define LABEL_XML_CAMERA_NAME "name"
59 #define LABEL_XML_WIDTH "image_width"
60 #define LABEL_XML_HEIGHT "image_height"
61 #define LABEL_XML_SUBSAMPLING_WIDTH "subsampling_width"
62 #define LABEL_XML_SUBSAMPLING_HEIGHT "subsampling_height"
63 #define LABEL_XML_FULL_WIDTH "full_width"
64 #define LABEL_XML_FULL_HEIGHT "full_height"
65 #define LABEL_XML_MODEL "model"
66 #define LABEL_XML_MODEL_TYPE "type"
67 #define LABEL_XML_U0 "u0"
68 #define LABEL_XML_V0 "v0"
69 #define LABEL_XML_PX "px"
70 #define LABEL_XML_PY "py"
71 #define LABEL_XML_KUD "kud"
72 #define LABEL_XML_KDU "kdu"
73 
74 #define LABEL_XML_MODEL_WITHOUT_DISTORTION "perspectiveProjWithoutDistortion"
75 #define LABEL_XML_MODEL_WITH_DISTORTION "perspectiveProjWithDistortion"
76 
80  : vpXmlParser(),
81  camera(), camera_name(), image_width(0), image_height(0),
82  subsampling_width(0), subsampling_height(0), full_width(0), full_height(0)
83 {
84 }
90  : vpXmlParser(twinParser),
91  camera(), camera_name(), image_width(0), image_height(0),
92  subsampling_width(0), subsampling_height(0), full_width(0), full_height(0)
93 
94 {
95  this->camera = twinParser.camera;
96  this->camera_name = twinParser.camera_name;
97  this->image_width = twinParser.image_width;
98  this->image_height = twinParser.image_height;
99  this->subsampling_width = twinParser.subsampling_width;
100  this->subsampling_height = twinParser.subsampling_height;
101  this->full_width = twinParser.full_width;
102  this->full_height = twinParser.full_height;
103 }
104 
112  this->camera = twinParser.camera;
113  this->camera_name = twinParser.camera_name;
114  this->image_width = twinParser.image_width;
115  this->image_height = twinParser.image_height;
116  this->subsampling_width = twinParser.subsampling_width;
117  this->subsampling_height = twinParser.subsampling_height;
118  this->full_width = twinParser.full_width;
119  this->full_height = twinParser.full_height;
120  return *this ;
121 }
122 
137 int
138 vpXmlParserCamera::parse(vpCameraParameters &cam, const std::string &filename,
139  const std::string& cam_name,
141  const unsigned int im_width,
142  const unsigned int im_height)
143 {
144  xmlDocPtr doc;
145  xmlNodePtr node;
146 
147  doc = xmlParseFile(filename.c_str());
148  if (doc == NULL)
149  {
150  return SEQUENCE_ERROR;
151  }
152 
153  node = xmlDocGetRootElement(doc);
154  if (node == NULL)
155  {
156  xmlFreeDoc(doc);
157  return SEQUENCE_ERROR;
158  }
159 
160  int ret = this ->read (doc, node, cam_name, projModel, im_width, im_height);
161 
162  cam = camera ;
163 
164  xmlFreeDoc(doc);
165 
166  return ret;
167 }
168 
182 int
183 vpXmlParserCamera::save(const vpCameraParameters &cam, const std::string &filename,
184  const std::string& cam_name,
185  const unsigned int im_width,
186  const unsigned int im_height)
187 {
188  xmlDocPtr doc;
189  xmlNodePtr node;
190  xmlNodePtr nodeCamera = NULL;
191 
192  doc = xmlReadFile(filename.c_str(), NULL, XML_PARSE_NOWARNING + XML_PARSE_NOERROR
193  + XML_PARSE_NOBLANKS);
194  if (doc == NULL){
195  doc = xmlNewDoc ((xmlChar*)"1.0");
196  node = xmlNewNode(NULL,(xmlChar*)LABEL_XML_ROOT);
197  xmlDocSetRootElement(doc,node);
198  xmlNodePtr node_tmp = xmlNewComment((xmlChar*)
199  "This file stores intrinsic camera parameters used\n"
200  " in the vpCameraParameters Class of ViSP available\n"
201  " at http://www.irisa.fr/lagadic/visp/visp.html .\n"
202  " It can be read with the parse method of\n"
203  " the vpXmlParserCamera class.");
204  xmlAddChild(node,node_tmp);
205  }
206 
207  node = xmlDocGetRootElement(doc);
208  if (node == NULL)
209  {
210  xmlFreeDoc(doc);
211  return SEQUENCE_ERROR;
212  }
213 
214  this->camera = cam;
215 
216  int nbCamera = count(doc, node, cam_name,cam.get_projModel(),
217  im_width, im_height);
218  if( nbCamera > 0){
219 // vpCERROR << nbCamera
220 // << " set(s) of camera parameters is(are) already "<< std::endl
221 // << "available in the file with your specifications : "<< std::endl
222 // << "precise the grabber parameters or delete manually"<< std::endl
223 // << "the previous one."<<std::endl;
224  xmlFreeDoc(doc);
225  return SEQUENCE_ERROR;
226  }
227 
228  nodeCamera = find_camera(doc, node, cam_name, im_width, im_height);
229  if(nodeCamera == NULL){
230  write(node, cam_name, im_width, im_height);
231  }
232  else{
233  write_camera(nodeCamera);
234  }
235 
236  xmlSaveFormatFile(filename.c_str(), doc, 1);
237  xmlFreeDoc(doc);
238 
239  return SEQUENCE_OK;
240 }
241 
242 
243 
262 int
263 vpXmlParserCamera::read (xmlDocPtr doc, xmlNodePtr node,
264  const std::string& cam_name,
266  const unsigned int im_width,
267  const unsigned int im_height,
268  const unsigned int subsampl_width,
269  const unsigned int subsampl_height)
270 {
271  // char * val_char;
272  vpXmlCodeType prop;
273 
275  unsigned int nbCamera = 0;
276 
277  for (node = node->xmlChildrenNode; node != NULL; node = node->next)
278  {
279  if (node->type != XML_ELEMENT_NODE) continue;
280  if (SEQUENCE_OK != str2xmlcode ((char*)(node ->name), prop))
281  {
282  prop = CODE_XML_OTHER;
283  back = SEQUENCE_ERROR;
284  }
285  /*
286  switch (prop)
287  {
288  case CODE_XML_CAMERA:
289  if (SEQUENCE_OK == this->read_camera (doc, node, camera_name, projModel,
290  image_width, image_height, subsampling_width, subsampling_height)){
291  nbCamera++;
292  }
293  break;
294  default:
295  back = SEQUENCE_ERROR;
296  break;
297  }
298  */
299  if (prop == CODE_XML_CAMERA){
300  if (SEQUENCE_OK == this->read_camera (doc, node, cam_name, projModel,
301  im_width, im_height, subsampl_width, subsampl_height))
302  nbCamera++;
303  }
304  else back = SEQUENCE_ERROR;
305  }
306 
307  if (nbCamera == 0){
308  back = SEQUENCE_ERROR;
309  vpCERROR << "No camera parameters is available" << std::endl
310  << "with your specifications" << std::endl;
311  }
312  else if(nbCamera > 1){
313  back = SEQUENCE_ERROR;
314  vpCERROR << nbCamera << " sets of camera parameters are available" << std::endl
315  << "with your specifications : " << std::endl
316  << "precise your choice..." << std::endl;
317  }
318 
319  return back;
320 }
340 int
341 vpXmlParserCamera::count (xmlDocPtr doc, xmlNodePtr node,
342  const std::string& cam_name,
344  const unsigned int im_width,
345  const unsigned int im_height,
346  const unsigned int subsampl_width,
347  const unsigned int subsampl_height)
348 {
349  // char * val_char;
350  vpXmlCodeType prop;
351  int nbCamera = 0;
352 
353  for (node = node->xmlChildrenNode; node != NULL; node = node->next)
354  {
355  if (node->type != XML_ELEMENT_NODE) continue;
356  if (SEQUENCE_OK != str2xmlcode ((char*)(node ->name), prop))
357  {
358  prop = CODE_XML_OTHER;
359  }
360  /*
361  switch (prop)
362  {
363  case CODE_XML_CAMERA:
364  if (SEQUENCE_OK == this->read_camera (doc, node, camera_name, projModel,
365  image_width, image_height,
366  subsampling_width, subsampling_height)){
367  nbCamera++;
368  }
369  break;
370  default:
371  break;
372  }
373  */
374  if (prop== CODE_XML_CAMERA) {
375  if (SEQUENCE_OK == this->read_camera (doc, node, cam_name, projModel,
376  im_width, im_height,
377  subsampl_width, subsampl_height))
378  nbCamera++;
379  }
380  }
381 
382  return nbCamera;
383 }
403 xmlNodePtr
404 vpXmlParserCamera::find_camera (xmlDocPtr doc, xmlNodePtr node,
405  const std::string& cam_name,
406  const unsigned int im_width,
407  const unsigned int im_height,
408  const unsigned int subsampl_width,
409  const unsigned int subsampl_height)
410 {
411  // char * val_char;
412  vpXmlCodeType prop;
413 
414  for (node = node->xmlChildrenNode; node != NULL; node = node->next)
415  {
416  if (node->type != XML_ELEMENT_NODE) continue;
417  if (SEQUENCE_OK != str2xmlcode ((char*)(node ->name), prop))
418  {
419  prop = CODE_XML_OTHER;
420  }
421  /*
422  switch (prop)
423  {
424  case CODE_XML_CAMERA:
425  if (SEQUENCE_OK == this->read_camera_header(doc, node, camera_name,
426  image_width, image_height,
427  subsampling_width, subsampling_height)){
428  return node;
429  }
430  break;
431  default:
432  break;
433  }
434  */
435  if(prop == CODE_XML_CAMERA){
436  if (SEQUENCE_OK == this->read_camera_header(doc, node, cam_name,
437  im_width, im_height,
438  subsampl_width, subsampl_height))
439  return node;
440  }
441  }
442  return NULL;
443 }
444 
464 int
465 vpXmlParserCamera::read_camera (xmlDocPtr doc, xmlNodePtr node,
466  const std::string& cam_name,
468  const unsigned int im_width,
469  const unsigned int im_height,
470  const unsigned int subsampl_width,
471  const unsigned int subsampl_height)
472 {
473  vpXmlCodeType prop;
474  /* read value in the XML file. */
475  std::string camera_name_tmp = "";
476  unsigned int image_height_tmp = 0 ;
477  unsigned int image_width_tmp = 0 ;
478  unsigned int subsampling_width_tmp = 0;
479  unsigned int subsampling_height_tmp = 0;
480  // unsigned int full_width_tmp = 0;
481  // unsigned int full_height_tmp = 0;
482  vpCameraParameters cam_tmp;
483  vpCameraParameters cam_tmp_model;
484  bool projModelFound = false;
486 
487  for (node = node->xmlChildrenNode; node != NULL; node = node->next)
488  {
489  // vpDEBUG_TRACE (15, "Carac : %s.", node ->name);
490  if (node->type != XML_ELEMENT_NODE) continue;
491  if (SEQUENCE_OK != str2xmlcode ((char*)(node ->name), prop))
492  {
493  prop = CODE_XML_OTHER;
494  back = SEQUENCE_ERROR;
495  }
496 
497 
498  switch (prop)
499  {
500  case CODE_XML_CAMERA_NAME: {
501  char * val_char = xmlReadCharChild(doc, node);
502  camera_name_tmp = val_char;
503  std::cout << "Found camera with name: \"" << camera_name_tmp << "\"" << std::endl;
504  xmlFree(val_char);
505  break;
506  }
507  case CODE_XML_WIDTH:
508  image_width_tmp = xmlReadUnsignedIntChild(doc, node);
509  break;
510 
511  case CODE_XML_HEIGHT:
512  image_height_tmp = xmlReadUnsignedIntChild(doc, node);
513  break;
515  subsampling_width_tmp = xmlReadUnsignedIntChild(doc, node);
516  break;
518  subsampling_height_tmp = xmlReadUnsignedIntChild(doc, node);
519  break;
520  // case CODE_XML_FULL_WIDTH:
521  // full_width_tmp = xmlReadUnsignedIntChild(doc, node);
522  // break;
523 
524  // case CODE_XML_FULL_HEIGHT:
525  // full_height_tmp = xmlReadUnsignedIntChild(doc, node);
526  // break;
527 
528  case CODE_XML_MODEL:
529  back = read_camera_model(doc, node, cam_tmp_model);
530  if(cam_tmp_model.get_projModel() == projModel){
531  cam_tmp = cam_tmp_model;
532  projModelFound = true;
533  }
534  break;
535 
536  case CODE_XML_BAD:
537  case CODE_XML_OTHER:
538  case CODE_XML_CAMERA:
540  case CODE_XML_FULL_WIDTH:
541  case CODE_XML_MODEL_TYPE:
542  case CODE_XML_U0:
543  case CODE_XML_V0:
544  case CODE_XML_PX:
545  case CODE_XML_PY:
546  case CODE_XML_KUD:
547  case CODE_XML_KDU:
548  default:
549  back = SEQUENCE_ERROR;
550  break;
551  }
552 
553  }
554  // Create a specific test for subsampling_width and subsampling_height to ensure that division by zero is not possible in the next test
555  bool test_subsampling_width = true;
556  bool test_subsampling_height = true;
557 
558  if (subsampling_width) {
559  test_subsampling_width = (abs((int)subsampl_width - (int)subsampling_width_tmp) < (allowedPixelDiffOnImageSize * (int)(subsampling_width_tmp / subsampling_width)));
560  }
561  if (subsampling_height) {
562  test_subsampling_height = (abs((int)subsampl_height - (int)subsampling_height_tmp) < (allowedPixelDiffOnImageSize * (int)(subsampling_height_tmp / subsampling_height)));
563  }
564  if( !((projModelFound == true) && (cam_name == camera_name_tmp) &&
565  (abs((int)im_width - (int)image_width_tmp) < allowedPixelDiffOnImageSize || im_width == 0) &&
566  (abs((int)im_height - (int)image_height_tmp) < allowedPixelDiffOnImageSize || im_height == 0) &&
567  (test_subsampling_width)&&
568  (test_subsampling_height))){
569  back = SEQUENCE_ERROR;
570  }
571  else{
572  this->camera = cam_tmp;
573  this->camera_name = camera_name_tmp;
574  this->image_width = image_width_tmp;
575  this->image_height = image_height_tmp;
576  this->subsampling_width = subsampling_width_tmp;
577  this->subsampling_height = subsampling_height_tmp;
578  this->full_width = subsampling_width_tmp * image_width_tmp;
579  this->full_height = subsampling_height_tmp * image_height_tmp;
580  }
581  return back;
582 }
602 int
603 vpXmlParserCamera::
604 read_camera_header (xmlDocPtr doc, xmlNodePtr node,
605  const std::string& cam_name,
606  const unsigned int im_width,
607  const unsigned int im_height,
608  const unsigned int subsampl_width,
609  const unsigned int subsampl_height)
610 {
611  vpXmlCodeType prop;
612  /* read value in the XML file. */
613  std::string camera_name_tmp = "";
614  unsigned int image_height_tmp = 0 ;
615  unsigned int image_width_tmp = 0 ;
616  unsigned int subsampling_width_tmp = 0;
617  unsigned int subsampling_height_tmp = 0;
618  // unsigned int full_width_tmp = 0;
619  // unsigned int full_height_tmp = 0;
621 
622  for (node = node->xmlChildrenNode; node != NULL; node = node->next)
623  {
624  // vpDEBUG_TRACE (15, "Carac : %s.", node ->name);
625  if (node->type != XML_ELEMENT_NODE) continue;
626  if (SEQUENCE_OK != str2xmlcode ((char*)(node ->name), prop))
627  {
628  prop = CODE_XML_OTHER;
629  back = SEQUENCE_ERROR;
630  }
631 
632 
633  switch (prop)
634  {
635  case CODE_XML_CAMERA_NAME:{
636  char * val_char = xmlReadCharChild(doc, node);
637  camera_name_tmp = val_char;
638  xmlFree(val_char);
639  }break;
640 
641  case CODE_XML_WIDTH:
642  image_width_tmp = xmlReadUnsignedIntChild(doc, node);
643  break;
644 
645  case CODE_XML_HEIGHT:
646  image_height_tmp = xmlReadUnsignedIntChild(doc, node);
647  break;
649  subsampling_width_tmp = xmlReadUnsignedIntChild(doc, node);
650  break;
652  subsampling_height_tmp = xmlReadUnsignedIntChild(doc, node);
653  break;
654  // case CODE_XML_FULL_WIDTH:
655  // full_width_tmp = xmlReadUnsignedIntChild(doc, node);
656  // break;
657 
658  // case CODE_XML_FULL_HEIGHT:
659  // full_height_tmp = xmlReadUnsignedIntChild(doc, node);
660  // break;
661 
662  case CODE_XML_MODEL:
663  break;
664 
665  case CODE_XML_BAD:
666  case CODE_XML_OTHER:
667  case CODE_XML_CAMERA:
669  case CODE_XML_FULL_WIDTH:
670  case CODE_XML_MODEL_TYPE:
671  case CODE_XML_U0:
672  case CODE_XML_V0:
673  case CODE_XML_PX:
674  case CODE_XML_PY:
675  case CODE_XML_KUD:
676  case CODE_XML_KDU:
677  default:
678  back = SEQUENCE_ERROR;
679  break;
680  }
681  }
682  if( !((cam_name == camera_name_tmp) &&
683  (im_width == image_width_tmp || im_width == 0) &&
684  (im_height == image_height_tmp || im_height == 0) &&
685  (subsampl_width == subsampling_width_tmp ||
686  subsampl_width == 0)&&
687  (subsampl_height == subsampling_height_tmp ||
688  subsampl_height == 0))){
689  back = SEQUENCE_ERROR;
690  }
691  return back;
692 }
693 
705 vpXmlParserCamera::read_camera_model (xmlDocPtr doc, xmlNodePtr node,
706  vpCameraParameters &cam_tmp)
707 {
708  // counter of the number of read parameters
709  int nb = 0;
710  vpXmlCodeType prop;
711  /* read value in the XML file. */
712 
713  char* model_type = NULL;
714  double u0 = cam_tmp.get_u0();
715  double v0 = cam_tmp.get_v0();
716  double px = cam_tmp.get_px();
717  double py = cam_tmp.get_py();
718  double kud = cam_tmp.get_kud();
719  double kdu = cam_tmp.get_kdu();
721  int validation = 0;
722 
723  for (node = node->xmlChildrenNode; node != NULL; node = node->next)
724  {
725  // vpDEBUG_TRACE (15, "Carac : %s.", node ->name);
726  if (node->type != XML_ELEMENT_NODE) continue;
727  if (SEQUENCE_OK != str2xmlcode ((char*)(node ->name), prop))
728  {
729  prop = CODE_XML_OTHER;
730  back = SEQUENCE_ERROR;
731  }
732 
733  switch (prop)
734  {
735  case CODE_XML_MODEL_TYPE:{
736  if(model_type != NULL){
737  xmlFree(model_type);
738  }
739  model_type = xmlReadCharChild(doc, node);
740  nb++;
741  validation = validation | 0x01;
742  }break;
743  case CODE_XML_U0:
744  u0 = xmlReadDoubleChild(doc, node);
745  nb++;
746  validation = validation | 0x02;
747  break;
748  case CODE_XML_V0:
749  v0 = xmlReadDoubleChild(doc, node);
750  nb++;
751  validation = validation | 0x04;
752  break;
753  case CODE_XML_PX:
754  px = xmlReadDoubleChild(doc, node);
755  nb++;
756  validation = validation | 0x08;
757  break;
758  case CODE_XML_PY:
759  py = xmlReadDoubleChild(doc, node);
760  nb++;
761  validation = validation | 0x10;
762  break;
763  case CODE_XML_KUD:
764  kud = xmlReadDoubleChild(doc, node);
765  nb++;
766  validation = validation | 0x20;
767  break;
768  case CODE_XML_KDU:
769  kdu = xmlReadDoubleChild(doc, node);
770  nb++;
771  validation = validation | 0x40;
772  break;
773  case CODE_XML_BAD:
774  case CODE_XML_OTHER:
775  case CODE_XML_CAMERA:
777  case CODE_XML_HEIGHT:
778  case CODE_XML_WIDTH:
782  case CODE_XML_FULL_WIDTH:
783  case CODE_XML_MODEL:
784  default:
785  back = SEQUENCE_ERROR;
786  break;
787  }
788  }
789 
790  if(model_type == NULL) {
791  vpERROR_TRACE("projection model type doesn't match with any known model !");
792  return SEQUENCE_ERROR;
793  }
794 
795  if( !strcmp(model_type,LABEL_XML_MODEL_WITHOUT_DISTORTION)){
796  if (nb != 5 || validation != 0x1F)
797  {
798  vpCERROR <<"ERROR in 'model' field:\n";
799  vpCERROR << "it must contain 5 parameters\n";
800  xmlFree(model_type);
801 
802  return SEQUENCE_ERROR;
803  }
804  cam_tmp.initPersProjWithoutDistortion(px,py,u0,v0) ;
805  }
806  else if( !strcmp(model_type,LABEL_XML_MODEL_WITH_DISTORTION)){
807  if (nb != 7 || validation != 0x7F)
808  {
809  vpCERROR <<"ERROR in 'model' field:\n";
810  vpCERROR << "it must contain 7 parameters\n";
811  xmlFree(model_type);
812 
813  return SEQUENCE_ERROR;
814  }
815  cam_tmp.initPersProjWithDistortion(px,py,u0,v0,kud,kdu);
816  }
817  else{
818  vpERROR_TRACE("projection model type doesn't match with any known model !");
819  xmlFree(model_type);
820 
821  return SEQUENCE_ERROR;
822  }
823  xmlFree(model_type);
824 
825  return back;
826 }
827 
845 int vpXmlParserCamera::
846 write (xmlNodePtr node, const std::string& cam_name,
847  const unsigned int im_width, const unsigned int im_height,
848  const unsigned int subsampl_width,
849  const unsigned int subsampl_height)
850 {
851  int back = SEQUENCE_OK;
852 
853  xmlNodePtr node_tmp;
854  xmlNodePtr node_camera;
855 
856  // <camera>
857  node_camera = xmlNewNode(NULL,(xmlChar*)LABEL_XML_CAMERA);
858  xmlAddChild(node,node_camera);
859  {
860  //<name>
861 
862  if(!cam_name.empty()){
863  node_tmp = xmlNewComment((xmlChar*)"Name of the camera");
864  xmlAddChild(node_camera,node_tmp);
865  xmlNewTextChild(node_camera,NULL,(xmlChar*)LABEL_XML_CAMERA_NAME,
866  (xmlChar*)cam_name.c_str());
867  }
868 
869  if(im_width != 0 || im_height != 0){
870  char str[11];
871  //<image_width>
872  node_tmp = xmlNewComment((xmlChar*)"Size of the image on which camera calibration was performed");
873  xmlAddChild(node_camera,node_tmp);
874 
875  sprintf(str,"%u",im_width);
876  xmlNewTextChild(node_camera,NULL,(xmlChar*)LABEL_XML_WIDTH,(xmlChar*)str);
877  //<image_height>
878 
879  sprintf(str,"%u",im_height);
880  xmlNewTextChild(node_camera,NULL,(xmlChar*)LABEL_XML_HEIGHT,(xmlChar*)str);
881  if(subsampling_width != 0 || subsampling_height != 0){
882  node_tmp = xmlNewComment((xmlChar*)"Subsampling used to obtain the current size of the image.");
883  xmlAddChild(node_camera,node_tmp);
884 
885  //<subsampling_width>
886  sprintf(str,"%u",subsampl_width);
887  xmlNewTextChild(node_camera,NULL,(xmlChar*)LABEL_XML_SUBSAMPLING_WIDTH,
888  (xmlChar*)str);
889  //<subsampling_height>
890  sprintf(str,"%u",subsampl_height);
891  xmlNewTextChild(node_camera,NULL,(xmlChar*)LABEL_XML_SUBSAMPLING_HEIGHT,
892  (xmlChar*)str);
893  node_tmp = xmlNewComment((xmlChar*)"The full size is the sensor size actually used to grab the image. full_width = subsampling_width * image_width");
894  xmlAddChild(node_camera,node_tmp);
895 
896  //<full_width>
897  sprintf(str,"%u",im_width*subsampl_width);
898  xmlNewTextChild(node_camera,NULL,(xmlChar*)LABEL_XML_FULL_WIDTH,
899  (xmlChar*)str);
900  //<full_height>
901  sprintf(str,"%u",im_height*subsampl_height);
902  xmlNewTextChild(node_camera,NULL,(xmlChar*)LABEL_XML_FULL_HEIGHT,
903  (xmlChar*)str);
904  }
905  }
906 
907  node_tmp = xmlNewComment((xmlChar*)"Intrinsic camera parameters computed for each projection model");
908 
909  xmlAddChild(node_camera,node_tmp);
910 
911  back = write_camera(node_camera);
912  }
913  return back;
914 }
922 int vpXmlParserCamera::
923 write_camera(xmlNodePtr node_camera){
924  xmlNodePtr node_model;
925  xmlNodePtr node_tmp;
926 
927  int back = SEQUENCE_OK;
928  switch(camera.get_projModel()){
930  //<model>
931  node_model = xmlNewNode(NULL,(xmlChar*)LABEL_XML_MODEL);
932  xmlAddChild(node_camera,node_model);
933  {
934  char str[21];
935  node_tmp = xmlNewComment((xmlChar*)"Projection model type");
936  xmlAddChild(node_model,node_tmp);
937 
938  //<type>without_distortion</type>
939  xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_MODEL_TYPE,
940  (xmlChar*)LABEL_XML_MODEL_WITHOUT_DISTORTION);
941 
942  node_tmp = xmlNewComment((xmlChar*)"Pixel ratio");
943  xmlAddChild(node_model,node_tmp);
944  //<px>
945  sprintf(str,"%.10f",camera.get_px());
946  xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_PX,(xmlChar*)str);
947  //<py>
948  sprintf(str,"%.10f",camera.get_py());
949  xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_PY,(xmlChar*)str);
950 
951  node_tmp = xmlNewComment((xmlChar*)"Principal point");
952  xmlAddChild(node_model,node_tmp);
953 
954  //<u0>
955  sprintf(str,"%.10f",camera.get_u0());
956  xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_U0,(xmlChar*)str);
957  //<v0>
958  sprintf(str,"%.10f",camera.get_v0());
959  xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_V0,(xmlChar*)str);
960  }
961  break;
963  //<model>
964  node_model = xmlNewNode(NULL,(xmlChar*)LABEL_XML_MODEL);
965  xmlAddChild(node_camera,node_model);
966  {
967  char str[21];
968  node_tmp = xmlNewComment((xmlChar*)"Projection model type");
969  xmlAddChild(node_model,node_tmp);
970  //<type>with_distortion</type>
971  xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_MODEL_TYPE,
972  (xmlChar*)LABEL_XML_MODEL_WITH_DISTORTION);
973 
974  node_tmp = xmlNewComment((xmlChar*)"Pixel ratio");
975  xmlAddChild(node_model,node_tmp);
976  //<px>
977  sprintf(str,"%.10f",camera.get_px());
978  xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_PX,(xmlChar*)str);
979  //<py>
980  sprintf(str,"%.10f",camera.get_py());
981  xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_PY,(xmlChar*)str);
982 
983  node_tmp = xmlNewComment((xmlChar*)"Principal point");
984  xmlAddChild(node_model,node_tmp);
985  //<u0>
986  sprintf(str,"%.10f",camera.get_u0());
987  xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_U0,(xmlChar*)str);
988  //<v0>
989  sprintf(str,"%.10f",camera.get_v0());
990  xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_V0,(xmlChar*)str);
991 
992  //<kud>
993  node_tmp = xmlNewComment((xmlChar*)"Undistorted to distorted distortion parameter");
994  xmlAddChild(node_model,node_tmp);
995  sprintf(str,"%.10f",camera.get_kud());
996  xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_KUD,(xmlChar*)str);
997 
998  //<kud>
999  node_tmp = xmlNewComment((xmlChar*)"Distorted to undistorted distortion parameter");
1000  xmlAddChild(node_model,node_tmp);
1001  sprintf(str,"%.10f",camera.get_kdu());
1002  xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_KDU,(xmlChar*)str);
1003  }
1004  break;
1005  }
1006  return back;
1007 }
1008 
1018 vpXmlParserCamera::str2xmlcode (char * str, vpXmlCodeType & res)
1019 {
1020  vpXmlCodeType val_int = CODE_XML_BAD;
1022 
1023  // DEBUG_TRACE (9, "# Entree :str=%s.", str);
1024 
1025  if (! strcmp (str, LABEL_XML_CAMERA))
1026  {
1027  val_int = CODE_XML_CAMERA;
1028  }
1029  else if (! strcmp (str, LABEL_XML_CAMERA_NAME))
1030  {
1031  val_int = CODE_XML_CAMERA_NAME;
1032  }
1033  else if (! strcmp (str, LABEL_XML_MODEL))
1034  {
1035  val_int = CODE_XML_MODEL;
1036  }
1037  else if (! strcmp (str, LABEL_XML_MODEL_TYPE))
1038  {
1039  val_int = CODE_XML_MODEL_TYPE;
1040  }
1041  else if (! strcmp (str, LABEL_XML_WIDTH))
1042  {
1043  val_int = CODE_XML_WIDTH;
1044  }
1045  else if (! strcmp (str, LABEL_XML_HEIGHT))
1046  {
1047  val_int = CODE_XML_HEIGHT;
1048  }
1049  else if (! strcmp (str, LABEL_XML_SUBSAMPLING_WIDTH))
1050  {
1051  val_int = CODE_XML_SUBSAMPLING_WIDTH;
1052  }
1053  else if (! strcmp (str, LABEL_XML_SUBSAMPLING_HEIGHT))
1054  {
1055  val_int = CODE_XML_SUBSAMPLING_HEIGHT;
1056  }
1057  else if (! strcmp (str, LABEL_XML_FULL_WIDTH))
1058  {
1059  val_int = CODE_XML_FULL_WIDTH;
1060  }
1061  else if (! strcmp (str, LABEL_XML_FULL_HEIGHT))
1062  {
1063  val_int = CODE_XML_FULL_HEIGHT;
1064  }
1065  else if (! strcmp (str, LABEL_XML_U0))
1066  {
1067  val_int = CODE_XML_U0;
1068  }
1069  else if (! strcmp (str, LABEL_XML_V0))
1070  {
1071  val_int = CODE_XML_V0;
1072  }
1073  else if (! strcmp (str, LABEL_XML_PX))
1074  {
1075  val_int = CODE_XML_PX;
1076  }
1077  else if (! strcmp (str, LABEL_XML_PY))
1078  {
1079  val_int = CODE_XML_PY;
1080  }
1081  else if (! strcmp (str, LABEL_XML_KUD))
1082  {
1083  val_int = CODE_XML_KUD;
1084  }
1085  else if (! strcmp (str, LABEL_XML_KDU))
1086  {
1087  val_int = CODE_XML_KDU;
1088  }
1089  else
1090  {
1091  val_int = CODE_XML_OTHER;
1092  }
1093  res = val_int;
1094 
1095  return back;
1096 }
1097 #elif !defined(VISP_BUILD_SHARED_LIBS)
1098 // Work arround to avoid warning: libvisp_core.a(vpXmlParserCamera.cpp.o) has no symbols
1099 void dummy_vpXmlParserCamera() {};
1100 #endif //VISP_HAVE_XML2
double get_u0() const
Perspective projection without distortion model.
vpXmlParserCamera & operator=(const vpXmlParserCamera &twinparser)
#define vpCERROR
Definition: vpDebug.h:365
#define vpERROR_TRACE
Definition: vpDebug.h:391
double xmlReadDoubleChild(xmlDocPtr doc, xmlNodePtr node)
double get_py() const
XML parser to load and save intrinsic camera parameters.
char * xmlReadCharChild(xmlDocPtr doc, xmlNodePtr node)
void initPersProjWithoutDistortion(const double px, const double py, const double u0, const double v0)
This class intends to simplify the creation of xml parser based on the libxml2 third party library...
Definition: vpXmlParser.h:174
int save(const vpCameraParameters &cam, const std::string &filename, const std::string &camera_name, const unsigned int image_width=0, const unsigned int image_height=0)
double get_v0() const
Generic class defining intrinsic camera parameters.
Perspective projection with distortion model.
double get_px() const
double get_kud() const
unsigned int xmlReadUnsignedIntChild(xmlDocPtr doc, xmlNodePtr node)
vpCameraParametersProjType get_projModel() const
double get_kdu() const
int parse(vpCameraParameters &cam, const std::string &filename, const std::string &camera_name, const vpCameraParameters::vpCameraParametersProjType &projModel, const unsigned int image_width=0, const unsigned int image_height=0)
void initPersProjWithDistortion(const double px, const double py, const double u0, const double v0, const double kud, const double kdu)