ViSP  2.10.0
vpXmlParserCamera.cpp
1 /****************************************************************************
2  *
3  * $Id: vpXmlParserCamera.cpp 5264 2015-02-04 13:49:55Z 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  * XML parser to load and save camera intrinsic parameters.
36  *
37  * Authors:
38  * Anthony Saunier
39  *
40  *****************************************************************************/
41 
42 
49 #include <visp/vpXmlParserCamera.h>
50 #ifdef VISP_HAVE_XML2
51 
52 #include <stdlib.h>
53 #include <string.h>
54 
55 #include <visp/vpDebug.h>
56 /* -------------------------------------------------------------------------- */
57 /* --- LABEL XML ------------------------------------------------------------ */
58 /* -------------------------------------------------------------------------- */
59 
60 #define LABEL_XML_ROOT "root"
61 #define LABEL_XML_CAMERA "camera"
62 #define LABEL_XML_CAMERA_NAME "name"
63 #define LABEL_XML_WIDTH "image_width"
64 #define LABEL_XML_HEIGHT "image_height"
65 #define LABEL_XML_SUBSAMPLING_WIDTH "subsampling_width"
66 #define LABEL_XML_SUBSAMPLING_HEIGHT "subsampling_height"
67 #define LABEL_XML_FULL_WIDTH "full_width"
68 #define LABEL_XML_FULL_HEIGHT "full_height"
69 #define LABEL_XML_MODEL "model"
70 #define LABEL_XML_MODEL_TYPE "type"
71 #define LABEL_XML_U0 "u0"
72 #define LABEL_XML_V0 "v0"
73 #define LABEL_XML_PX "px"
74 #define LABEL_XML_PY "py"
75 #define LABEL_XML_KUD "kud"
76 #define LABEL_XML_KDU "kdu"
77 
78 #define LABEL_XML_MODEL_WITHOUT_DISTORTION "perspectiveProjWithoutDistortion"
79 #define LABEL_XML_MODEL_WITH_DISTORTION "perspectiveProjWithDistortion"
80 
84  : vpXmlParser(),
85  camera(), camera_name(), image_width(0), image_height(0),
86  subsampling_width(0), subsampling_height(0), full_width(0), full_height(0)
87 {
88 }
94  : vpXmlParser(twinParser),
95  camera(), camera_name(), image_width(0), image_height(0),
96  subsampling_width(0), subsampling_height(0), full_width(0), full_height(0)
97 
98 {
99  this->camera = twinParser.camera;
100  this->camera_name = twinParser.camera_name;
101  this->image_width = twinParser.image_width;
102  this->image_height = twinParser.image_height;
103  this->subsampling_width = twinParser.subsampling_width;
104  this->subsampling_height = twinParser.subsampling_height;
105  this->full_width = twinParser.full_width;
106  this->full_height = twinParser.full_height;
107 }
108 
116  this->camera = twinParser.camera;
117  this->camera_name = twinParser.camera_name;
118  this->image_width = twinParser.image_width;
119  this->image_height = twinParser.image_height;
120  this->subsampling_width = twinParser.subsampling_width;
121  this->subsampling_height = twinParser.subsampling_height;
122  this->full_width = twinParser.full_width;
123  this->full_height = twinParser.full_height;
124  return *this ;
125 }
126 
141 int
142 vpXmlParserCamera::parse(vpCameraParameters &cam, const std::string &filename,
143  const std::string& cam_name,
145  const unsigned int im_width,
146  const unsigned int im_height)
147 {
148  xmlDocPtr doc;
149  xmlNodePtr node;
150 
151  doc = xmlParseFile(filename.c_str());
152  if (doc == NULL)
153  {
154  return SEQUENCE_ERROR;
155  }
156 
157  node = xmlDocGetRootElement(doc);
158  if (node == NULL)
159  {
160  xmlFreeDoc(doc);
161  return SEQUENCE_ERROR;
162  }
163 
164  int ret = this ->read (doc, node, cam_name, projModel, im_width, im_height);
165 
166  cam = camera ;
167 
168  xmlFreeDoc(doc);
169 
170  return ret;
171 }
172 
186 int
187 vpXmlParserCamera::save(const vpCameraParameters &cam, const std::string &filename,
188  const std::string& cam_name,
189  const unsigned int im_width,
190  const unsigned int im_height)
191 {
192  xmlDocPtr doc;
193  xmlNodePtr node;
194  xmlNodePtr nodeCamera = NULL;
195 
196  doc = xmlReadFile(filename.c_str(), NULL, XML_PARSE_NOWARNING + XML_PARSE_NOERROR
197  + XML_PARSE_NOBLANKS);
198  if (doc == NULL){
199  doc = xmlNewDoc ((xmlChar*)"1.0");
200  node = xmlNewNode(NULL,(xmlChar*)LABEL_XML_ROOT);
201  xmlDocSetRootElement(doc,node);
202  xmlNodePtr node_tmp = xmlNewComment((xmlChar*)
203  "This file stores intrinsic camera parameters used\n"
204  " in the vpCameraParameters Class of ViSP available\n"
205  " at http://www.irisa.fr/lagadic/visp/visp.html .\n"
206  " It can be read with the parse method of\n"
207  " the vpXmlParserCamera class.");
208  xmlAddChild(node,node_tmp);
209  }
210 
211  node = xmlDocGetRootElement(doc);
212  if (node == NULL)
213  {
214  xmlFreeDoc(doc);
215  return SEQUENCE_ERROR;
216  }
217 
218  this->camera = cam;
219 
220  int nbCamera = count(doc, node, cam_name,cam.get_projModel(),
221  im_width, im_height);
222  if( nbCamera > 0){
223 // vpCERROR << nbCamera
224 // << " set(s) of camera parameters is(are) already "<< std::endl
225 // << "available in the file with your specifications : "<< std::endl
226 // << "precise the grabber parameters or delete manually"<< std::endl
227 // << "the previous one."<<std::endl;
228  xmlFreeDoc(doc);
229  return SEQUENCE_ERROR;
230  }
231 
232  nodeCamera = find_camera(doc, node, cam_name, im_width, im_height);
233  if(nodeCamera == NULL){
234  write(node, cam_name, im_width, im_height);
235  }
236  else{
237  write_camera(nodeCamera);
238  }
239 
240  xmlSaveFormatFile(filename.c_str(), doc, 1);
241  xmlFreeDoc(doc);
242 
243  return SEQUENCE_OK;
244 }
245 
246 
247 
266 int
267 vpXmlParserCamera::read (xmlDocPtr doc, xmlNodePtr node,
268  const std::string& cam_name,
270  const unsigned int im_width,
271  const unsigned int im_height,
272  const unsigned int subsampl_width,
273  const unsigned int subsampl_height)
274 {
275  // char * val_char;
276  vpXmlCodeType prop;
277 
279  unsigned int nbCamera = 0;
280 
281  for (node = node->xmlChildrenNode; node != NULL; node = node->next)
282  {
283  if (node->type != XML_ELEMENT_NODE) continue;
284  if (SEQUENCE_OK != str2xmlcode ((char*)(node ->name), prop))
285  {
286  prop = CODE_XML_OTHER;
287  back = SEQUENCE_ERROR;
288  }
289  /*
290  switch (prop)
291  {
292  case CODE_XML_CAMERA:
293  if (SEQUENCE_OK == this->read_camera (doc, node, camera_name, projModel,
294  image_width, image_height, subsampling_width, subsampling_height)){
295  nbCamera++;
296  }
297  break;
298  default:
299  back = SEQUENCE_ERROR;
300  break;
301  }
302  */
303  if (prop == CODE_XML_CAMERA){
304  if (SEQUENCE_OK == this->read_camera (doc, node, cam_name, projModel,
305  im_width, im_height, subsampl_width, subsampl_height))
306  nbCamera++;
307  }
308  else back = SEQUENCE_ERROR;
309  }
310 
311  if (nbCamera == 0){
312  back = SEQUENCE_ERROR;
313  vpCERROR << "No camera parameters is available" << std::endl
314  << "with your specifications" << std::endl;
315  }
316  else if(nbCamera > 1){
317  back = SEQUENCE_ERROR;
318  vpCERROR << nbCamera << " sets of camera parameters are available" << std::endl
319  << "with your specifications : " << std::endl
320  << "precise your choice..." << std::endl;
321  }
322 
323  return back;
324 }
344 int
345 vpXmlParserCamera::count (xmlDocPtr doc, xmlNodePtr node,
346  const std::string& cam_name,
348  const unsigned int im_width,
349  const unsigned int im_height,
350  const unsigned int subsampl_width,
351  const unsigned int subsampl_height)
352 {
353  // char * val_char;
354  vpXmlCodeType prop;
355  int nbCamera = 0;
356 
357  for (node = node->xmlChildrenNode; node != NULL; node = node->next)
358  {
359  if (node->type != XML_ELEMENT_NODE) continue;
360  if (SEQUENCE_OK != str2xmlcode ((char*)(node ->name), prop))
361  {
362  prop = CODE_XML_OTHER;
363  }
364  /*
365  switch (prop)
366  {
367  case CODE_XML_CAMERA:
368  if (SEQUENCE_OK == this->read_camera (doc, node, camera_name, projModel,
369  image_width, image_height,
370  subsampling_width, subsampling_height)){
371  nbCamera++;
372  }
373  break;
374  default:
375  break;
376  }
377  */
378  if (prop== CODE_XML_CAMERA) {
379  if (SEQUENCE_OK == this->read_camera (doc, node, cam_name, projModel,
380  im_width, im_height,
381  subsampl_width, subsampl_height))
382  nbCamera++;
383  }
384  }
385 
386  return nbCamera;
387 }
407 xmlNodePtr
408 vpXmlParserCamera::find_camera (xmlDocPtr doc, xmlNodePtr node,
409  const std::string& cam_name,
410  const unsigned int im_width,
411  const unsigned int im_height,
412  const unsigned int subsampl_width,
413  const unsigned int subsampl_height)
414 {
415  // char * val_char;
416  vpXmlCodeType prop;
417 
418  for (node = node->xmlChildrenNode; node != NULL; node = node->next)
419  {
420  if (node->type != XML_ELEMENT_NODE) continue;
421  if (SEQUENCE_OK != str2xmlcode ((char*)(node ->name), prop))
422  {
423  prop = CODE_XML_OTHER;
424  }
425  /*
426  switch (prop)
427  {
428  case CODE_XML_CAMERA:
429  if (SEQUENCE_OK == this->read_camera_header(doc, node, camera_name,
430  image_width, image_height,
431  subsampling_width, subsampling_height)){
432  return node;
433  }
434  break;
435  default:
436  break;
437  }
438  */
439  if(prop == CODE_XML_CAMERA){
440  if (SEQUENCE_OK == this->read_camera_header(doc, node, cam_name,
441  im_width, im_height,
442  subsampl_width, subsampl_height))
443  return node;
444  }
445  }
446  return NULL;
447 }
448 
468 int
469 vpXmlParserCamera::read_camera (xmlDocPtr doc, xmlNodePtr node,
470  const std::string& cam_name,
472  const unsigned int im_width,
473  const unsigned int im_height,
474  const unsigned int subsampl_width,
475  const unsigned int subsampl_height)
476 {
477  vpXmlCodeType prop;
478  /* read value in the XML file. */
479  std::string camera_name_tmp = "";
480  unsigned int image_height_tmp = 0 ;
481  unsigned int image_width_tmp = 0 ;
482  unsigned int subsampling_width_tmp = 0;
483  unsigned int subsampling_height_tmp = 0;
484  // unsigned int full_width_tmp = 0;
485  // unsigned int full_height_tmp = 0;
486  vpCameraParameters cam_tmp;
487  vpCameraParameters cam_tmp_model;
488  bool projModelFound = false;
490 
491  for (node = node->xmlChildrenNode; node != NULL; node = node->next)
492  {
493  // vpDEBUG_TRACE (15, "Carac : %s.", node ->name);
494  if (node->type != XML_ELEMENT_NODE) continue;
495  if (SEQUENCE_OK != str2xmlcode ((char*)(node ->name), prop))
496  {
497  prop = CODE_XML_OTHER;
498  back = SEQUENCE_ERROR;
499  }
500 
501 
502  switch (prop)
503  {
504  case CODE_XML_CAMERA_NAME: {
505  char * val_char = xmlReadCharChild(doc, node);
506  camera_name_tmp = val_char;
507  std::cout << "Found camera with name: \"" << camera_name_tmp << "\"" << std::endl;
508  xmlFree(val_char);
509  break;
510  }
511  case CODE_XML_WIDTH:
512  image_width_tmp = xmlReadUnsignedIntChild(doc, node);
513  break;
514 
515  case CODE_XML_HEIGHT:
516  image_height_tmp = xmlReadUnsignedIntChild(doc, node);
517  break;
519  subsampling_width_tmp = xmlReadUnsignedIntChild(doc, node);
520  break;
522  subsampling_height_tmp = xmlReadUnsignedIntChild(doc, node);
523  break;
524  // case CODE_XML_FULL_WIDTH:
525  // full_width_tmp = xmlReadUnsignedIntChild(doc, node);
526  // break;
527 
528  // case CODE_XML_FULL_HEIGHT:
529  // full_height_tmp = xmlReadUnsignedIntChild(doc, node);
530  // break;
531 
532  case CODE_XML_MODEL:
533  back = read_camera_model(doc, node, cam_tmp_model);
534  if(cam_tmp_model.get_projModel() == projModel){
535  cam_tmp = cam_tmp_model;
536  projModelFound = true;
537  }
538  break;
539 
540  case CODE_XML_BAD:
541  case CODE_XML_OTHER:
542  case CODE_XML_CAMERA:
544  case CODE_XML_FULL_WIDTH:
545  case CODE_XML_MODEL_TYPE:
546  case CODE_XML_U0:
547  case CODE_XML_V0:
548  case CODE_XML_PX:
549  case CODE_XML_PY:
550  case CODE_XML_KUD:
551  case CODE_XML_KDU:
552  default:
553  back = SEQUENCE_ERROR;
554  break;
555  }
556 
557  }
558  // Create a specific test for subsampling_width and subsampling_height to ensure that division by zero is not possible in the next test
559  bool test_subsampling_width = true;
560  bool test_subsampling_height = true;
561 
562  if (subsampling_width) {
563  test_subsampling_width = (abs((int)subsampl_width - (int)subsampling_width_tmp) < (allowedPixelDiffOnImageSize * (int)(subsampling_width_tmp / subsampling_width)));
564  }
565  if (subsampling_height) {
566  test_subsampling_height = (abs((int)subsampl_height - (int)subsampling_height_tmp) < (allowedPixelDiffOnImageSize * (int)(subsampling_height_tmp / subsampling_height)));
567  }
568  if( !((projModelFound == true) && (cam_name == camera_name_tmp) &&
569  (abs((int)im_width - (int)image_width_tmp) < allowedPixelDiffOnImageSize || im_width == 0) &&
570  (abs((int)im_height - (int)image_height_tmp) < allowedPixelDiffOnImageSize || im_height == 0) &&
571  (test_subsampling_width)&&
572  (test_subsampling_height))){
573  back = SEQUENCE_ERROR;
574  }
575  else{
576  this->camera = cam_tmp;
577  this->camera_name = camera_name_tmp;
578  this->image_width = image_width_tmp;
579  this->image_height = image_height_tmp;
580  this->subsampling_width = subsampling_width_tmp;
581  this->subsampling_height = subsampling_height_tmp;
582  this->full_width = subsampling_width_tmp * image_width_tmp;
583  this->full_height = subsampling_height_tmp * image_height_tmp;
584  }
585  return back;
586 }
606 int
607 vpXmlParserCamera::
608 read_camera_header (xmlDocPtr doc, xmlNodePtr node,
609  const std::string& cam_name,
610  const unsigned int im_width,
611  const unsigned int im_height,
612  const unsigned int subsampl_width,
613  const unsigned int subsampl_height)
614 {
615  vpXmlCodeType prop;
616  /* read value in the XML file. */
617  std::string camera_name_tmp = "";
618  unsigned int image_height_tmp = 0 ;
619  unsigned int image_width_tmp = 0 ;
620  unsigned int subsampling_width_tmp = 0;
621  unsigned int subsampling_height_tmp = 0;
622  // unsigned int full_width_tmp = 0;
623  // unsigned int full_height_tmp = 0;
625 
626  for (node = node->xmlChildrenNode; node != NULL; node = node->next)
627  {
628  // vpDEBUG_TRACE (15, "Carac : %s.", node ->name);
629  if (node->type != XML_ELEMENT_NODE) continue;
630  if (SEQUENCE_OK != str2xmlcode ((char*)(node ->name), prop))
631  {
632  prop = CODE_XML_OTHER;
633  back = SEQUENCE_ERROR;
634  }
635 
636 
637  switch (prop)
638  {
639  case CODE_XML_CAMERA_NAME:{
640  char * val_char = xmlReadCharChild(doc, node);
641  camera_name_tmp = val_char;
642  xmlFree(val_char);
643  }break;
644 
645  case CODE_XML_WIDTH:
646  image_width_tmp = xmlReadUnsignedIntChild(doc, node);
647  break;
648 
649  case CODE_XML_HEIGHT:
650  image_height_tmp = xmlReadUnsignedIntChild(doc, node);
651  break;
653  subsampling_width_tmp = xmlReadUnsignedIntChild(doc, node);
654  break;
656  subsampling_height_tmp = xmlReadUnsignedIntChild(doc, node);
657  break;
658  // case CODE_XML_FULL_WIDTH:
659  // full_width_tmp = xmlReadUnsignedIntChild(doc, node);
660  // break;
661 
662  // case CODE_XML_FULL_HEIGHT:
663  // full_height_tmp = xmlReadUnsignedIntChild(doc, node);
664  // break;
665 
666  case CODE_XML_MODEL:
667  break;
668 
669  case CODE_XML_BAD:
670  case CODE_XML_OTHER:
671  case CODE_XML_CAMERA:
673  case CODE_XML_FULL_WIDTH:
674  case CODE_XML_MODEL_TYPE:
675  case CODE_XML_U0:
676  case CODE_XML_V0:
677  case CODE_XML_PX:
678  case CODE_XML_PY:
679  case CODE_XML_KUD:
680  case CODE_XML_KDU:
681  default:
682  back = SEQUENCE_ERROR;
683  break;
684  }
685  }
686  if( !((cam_name == camera_name_tmp) &&
687  (im_width == image_width_tmp || im_width == 0) &&
688  (im_height == image_height_tmp || im_height == 0) &&
689  (subsampl_width == subsampling_width_tmp ||
690  subsampl_width == 0)&&
691  (subsampl_height == subsampling_height_tmp ||
692  subsampl_height == 0))){
693  back = SEQUENCE_ERROR;
694  }
695  return back;
696 }
697 
709 vpXmlParserCamera::read_camera_model (xmlDocPtr doc, xmlNodePtr node,
710  vpCameraParameters &cam_tmp)
711 {
712  // counter of the number of read parameters
713  int nb = 0;
714  vpXmlCodeType prop;
715  /* read value in the XML file. */
716 
717  char* model_type = NULL;
718  double u0 = cam_tmp.get_u0();
719  double v0 = cam_tmp.get_v0();
720  double px = cam_tmp.get_px();
721  double py = cam_tmp.get_py();
722  double kud = cam_tmp.get_kud();
723  double kdu = cam_tmp.get_kdu();
725  int validation = 0;
726 
727  for (node = node->xmlChildrenNode; node != NULL; node = node->next)
728  {
729  // vpDEBUG_TRACE (15, "Carac : %s.", node ->name);
730  if (node->type != XML_ELEMENT_NODE) continue;
731  if (SEQUENCE_OK != str2xmlcode ((char*)(node ->name), prop))
732  {
733  prop = CODE_XML_OTHER;
734  back = SEQUENCE_ERROR;
735  }
736 
737  switch (prop)
738  {
739  case CODE_XML_MODEL_TYPE:{
740  if(model_type != NULL){
741  xmlFree(model_type);
742  }
743  model_type = xmlReadCharChild(doc, node);
744  nb++;
745  validation = validation | 0x01;
746  }break;
747  case CODE_XML_U0:
748  u0 = xmlReadDoubleChild(doc, node);
749  nb++;
750  validation = validation | 0x02;
751  break;
752  case CODE_XML_V0:
753  v0 = xmlReadDoubleChild(doc, node);
754  nb++;
755  validation = validation | 0x04;
756  break;
757  case CODE_XML_PX:
758  px = xmlReadDoubleChild(doc, node);
759  nb++;
760  validation = validation | 0x08;
761  break;
762  case CODE_XML_PY:
763  py = xmlReadDoubleChild(doc, node);
764  nb++;
765  validation = validation | 0x10;
766  break;
767  case CODE_XML_KUD:
768  kud = xmlReadDoubleChild(doc, node);
769  nb++;
770  validation = validation | 0x20;
771  break;
772  case CODE_XML_KDU:
773  kdu = xmlReadDoubleChild(doc, node);
774  nb++;
775  validation = validation | 0x40;
776  break;
777  case CODE_XML_BAD:
778  case CODE_XML_OTHER:
779  case CODE_XML_CAMERA:
781  case CODE_XML_HEIGHT:
782  case CODE_XML_WIDTH:
786  case CODE_XML_FULL_WIDTH:
787  case CODE_XML_MODEL:
788  default:
789  back = SEQUENCE_ERROR;
790  break;
791  }
792  }
793 
794  if(model_type == NULL) {
795  vpERROR_TRACE("projection model type doesn't match with any known model !");
796  return SEQUENCE_ERROR;
797  }
798 
799  if( !strcmp(model_type,LABEL_XML_MODEL_WITHOUT_DISTORTION)){
800  if (nb != 5 || validation != 0x1F)
801  {
802  vpCERROR <<"ERROR in 'model' field:\n";
803  vpCERROR << "it must contain 5 parameters\n";
804  xmlFree(model_type);
805 
806  return SEQUENCE_ERROR;
807  }
808  cam_tmp.initPersProjWithoutDistortion(px,py,u0,v0) ;
809  }
810  else if( !strcmp(model_type,LABEL_XML_MODEL_WITH_DISTORTION)){
811  if (nb != 7 || validation != 0x7F)
812  {
813  vpCERROR <<"ERROR in 'model' field:\n";
814  vpCERROR << "it must contain 7 parameters\n";
815  xmlFree(model_type);
816 
817  return SEQUENCE_ERROR;
818  }
819  cam_tmp.initPersProjWithDistortion(px,py,u0,v0,kud,kdu);
820  }
821  else{
822  vpERROR_TRACE("projection model type doesn't match with any known model !");
823  xmlFree(model_type);
824 
825  return SEQUENCE_ERROR;
826  }
827  xmlFree(model_type);
828 
829  return back;
830 }
831 
849 int vpXmlParserCamera::
850 write (xmlNodePtr node, const std::string& cam_name,
851  const unsigned int im_width, const unsigned int im_height,
852  const unsigned int subsampl_width,
853  const unsigned int subsampl_height)
854 {
855  int back = SEQUENCE_OK;
856 
857  xmlNodePtr node_tmp;
858  xmlNodePtr node_camera;
859 
860  // <camera>
861  node_camera = xmlNewNode(NULL,(xmlChar*)LABEL_XML_CAMERA);
862  xmlAddChild(node,node_camera);
863  {
864  //<name>
865 
866  if(!cam_name.empty()){
867  node_tmp = xmlNewComment((xmlChar*)"Name of the camera");
868  xmlAddChild(node_camera,node_tmp);
869  xmlNewTextChild(node_camera,NULL,(xmlChar*)LABEL_XML_CAMERA_NAME,
870  (xmlChar*)cam_name.c_str());
871  }
872 
873  if(im_width != 0 || im_height != 0){
874  char str[11];
875  //<image_width>
876  node_tmp = xmlNewComment((xmlChar*)"Size of the image on which camera calibration was performed");
877  xmlAddChild(node_camera,node_tmp);
878 
879  sprintf(str,"%u",im_width);
880  xmlNewTextChild(node_camera,NULL,(xmlChar*)LABEL_XML_WIDTH,(xmlChar*)str);
881  //<image_height>
882 
883  sprintf(str,"%u",im_height);
884  xmlNewTextChild(node_camera,NULL,(xmlChar*)LABEL_XML_HEIGHT,(xmlChar*)str);
885  if(subsampling_width != 0 || subsampling_height != 0){
886  node_tmp = xmlNewComment((xmlChar*)"Subsampling used to obtain the current size of the image.");
887  xmlAddChild(node_camera,node_tmp);
888 
889  //<subsampling_width>
890  sprintf(str,"%u",subsampl_width);
891  xmlNewTextChild(node_camera,NULL,(xmlChar*)LABEL_XML_SUBSAMPLING_WIDTH,
892  (xmlChar*)str);
893  //<subsampling_height>
894  sprintf(str,"%u",subsampl_height);
895  xmlNewTextChild(node_camera,NULL,(xmlChar*)LABEL_XML_SUBSAMPLING_HEIGHT,
896  (xmlChar*)str);
897  node_tmp = xmlNewComment((xmlChar*)"The full size is the sensor size actually used to grab the image. full_width = subsampling_width * image_width");
898  xmlAddChild(node_camera,node_tmp);
899 
900  //<full_width>
901  sprintf(str,"%u",im_width*subsampl_width);
902  xmlNewTextChild(node_camera,NULL,(xmlChar*)LABEL_XML_FULL_WIDTH,
903  (xmlChar*)str);
904  //<full_height>
905  sprintf(str,"%u",im_height*subsampl_height);
906  xmlNewTextChild(node_camera,NULL,(xmlChar*)LABEL_XML_FULL_HEIGHT,
907  (xmlChar*)str);
908  }
909  }
910 
911  node_tmp = xmlNewComment((xmlChar*)"Intrinsic camera parameters computed for each projection model");
912 
913  xmlAddChild(node_camera,node_tmp);
914 
915  back = write_camera(node_camera);
916  }
917  return back;
918 }
926 int vpXmlParserCamera::
927 write_camera(xmlNodePtr node_camera){
928  xmlNodePtr node_model;
929  xmlNodePtr node_tmp;
930 
931  int back = SEQUENCE_OK;
932  switch(camera.get_projModel()){
934  //<model>
935  node_model = xmlNewNode(NULL,(xmlChar*)LABEL_XML_MODEL);
936  xmlAddChild(node_camera,node_model);
937  {
938  char str[21];
939  node_tmp = xmlNewComment((xmlChar*)"Projection model type");
940  xmlAddChild(node_model,node_tmp);
941 
942  //<type>without_distortion</type>
943  xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_MODEL_TYPE,
944  (xmlChar*)LABEL_XML_MODEL_WITHOUT_DISTORTION);
945 
946  node_tmp = xmlNewComment((xmlChar*)"Pixel ratio");
947  xmlAddChild(node_model,node_tmp);
948  //<px>
949  sprintf(str,"%.10f",camera.get_px());
950  xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_PX,(xmlChar*)str);
951  //<py>
952  sprintf(str,"%.10f",camera.get_py());
953  xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_PY,(xmlChar*)str);
954 
955  node_tmp = xmlNewComment((xmlChar*)"Principal point");
956  xmlAddChild(node_model,node_tmp);
957 
958  //<u0>
959  sprintf(str,"%.10f",camera.get_u0());
960  xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_U0,(xmlChar*)str);
961  //<v0>
962  sprintf(str,"%.10f",camera.get_v0());
963  xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_V0,(xmlChar*)str);
964  }
965  break;
967  //<model>
968  node_model = xmlNewNode(NULL,(xmlChar*)LABEL_XML_MODEL);
969  xmlAddChild(node_camera,node_model);
970  {
971  char str[21];
972  node_tmp = xmlNewComment((xmlChar*)"Projection model type");
973  xmlAddChild(node_model,node_tmp);
974  //<type>with_distortion</type>
975  xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_MODEL_TYPE,
976  (xmlChar*)LABEL_XML_MODEL_WITH_DISTORTION);
977 
978  node_tmp = xmlNewComment((xmlChar*)"Pixel ratio");
979  xmlAddChild(node_model,node_tmp);
980  //<px>
981  sprintf(str,"%.10f",camera.get_px());
982  xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_PX,(xmlChar*)str);
983  //<py>
984  sprintf(str,"%.10f",camera.get_py());
985  xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_PY,(xmlChar*)str);
986 
987  node_tmp = xmlNewComment((xmlChar*)"Principal point");
988  xmlAddChild(node_model,node_tmp);
989  //<u0>
990  sprintf(str,"%.10f",camera.get_u0());
991  xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_U0,(xmlChar*)str);
992  //<v0>
993  sprintf(str,"%.10f",camera.get_v0());
994  xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_V0,(xmlChar*)str);
995 
996  //<kud>
997  node_tmp = xmlNewComment((xmlChar*)"Undistorted to distorted distortion parameter");
998  xmlAddChild(node_model,node_tmp);
999  sprintf(str,"%.10f",camera.get_kud());
1000  xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_KUD,(xmlChar*)str);
1001 
1002  //<kud>
1003  node_tmp = xmlNewComment((xmlChar*)"Distorted to undistorted distortion parameter");
1004  xmlAddChild(node_model,node_tmp);
1005  sprintf(str,"%.10f",camera.get_kdu());
1006  xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_KDU,(xmlChar*)str);
1007  }
1008  break;
1009  }
1010  return back;
1011 }
1012 
1022 vpXmlParserCamera::str2xmlcode (char * str, vpXmlCodeType & res)
1023 {
1024  vpXmlCodeType val_int = CODE_XML_BAD;
1026 
1027  // DEBUG_TRACE (9, "# Entree :str=%s.", str);
1028 
1029  if (! strcmp (str, LABEL_XML_CAMERA))
1030  {
1031  val_int = CODE_XML_CAMERA;
1032  }
1033  else if (! strcmp (str, LABEL_XML_CAMERA_NAME))
1034  {
1035  val_int = CODE_XML_CAMERA_NAME;
1036  }
1037  else if (! strcmp (str, LABEL_XML_MODEL))
1038  {
1039  val_int = CODE_XML_MODEL;
1040  }
1041  else if (! strcmp (str, LABEL_XML_MODEL_TYPE))
1042  {
1043  val_int = CODE_XML_MODEL_TYPE;
1044  }
1045  else if (! strcmp (str, LABEL_XML_WIDTH))
1046  {
1047  val_int = CODE_XML_WIDTH;
1048  }
1049  else if (! strcmp (str, LABEL_XML_HEIGHT))
1050  {
1051  val_int = CODE_XML_HEIGHT;
1052  }
1053  else if (! strcmp (str, LABEL_XML_SUBSAMPLING_WIDTH))
1054  {
1055  val_int = CODE_XML_SUBSAMPLING_WIDTH;
1056  }
1057  else if (! strcmp (str, LABEL_XML_SUBSAMPLING_HEIGHT))
1058  {
1059  val_int = CODE_XML_SUBSAMPLING_HEIGHT;
1060  }
1061  else if (! strcmp (str, LABEL_XML_FULL_WIDTH))
1062  {
1063  val_int = CODE_XML_FULL_WIDTH;
1064  }
1065  else if (! strcmp (str, LABEL_XML_FULL_HEIGHT))
1066  {
1067  val_int = CODE_XML_FULL_HEIGHT;
1068  }
1069  else if (! strcmp (str, LABEL_XML_U0))
1070  {
1071  val_int = CODE_XML_U0;
1072  }
1073  else if (! strcmp (str, LABEL_XML_V0))
1074  {
1075  val_int = CODE_XML_V0;
1076  }
1077  else if (! strcmp (str, LABEL_XML_PX))
1078  {
1079  val_int = CODE_XML_PX;
1080  }
1081  else if (! strcmp (str, LABEL_XML_PY))
1082  {
1083  val_int = CODE_XML_PY;
1084  }
1085  else if (! strcmp (str, LABEL_XML_KUD))
1086  {
1087  val_int = CODE_XML_KUD;
1088  }
1089  else if (! strcmp (str, LABEL_XML_KDU))
1090  {
1091  val_int = CODE_XML_KDU;
1092  }
1093  else
1094  {
1095  val_int = CODE_XML_OTHER;
1096  }
1097  res = val_int;
1098 
1099  return back;
1100 }
1101 #endif //VISP_HAVE_XML2
double get_u0() const
Perspective projection without distortion model.
vpXmlParserCamera & operator=(const vpXmlParserCamera &twinparser)
#define vpERROR_TRACE
Definition: vpDebug.h:395
#define vpCERROR
Definition: vpDebug.h:369
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:178
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)