Visual Servoing Platform  version 3.2.0
vpXmlParserCamera.cpp
1 /****************************************************************************
2  *
3  * ViSP, open source Visual Servoing Platform software.
4  * Copyright (C) 2005 - 2019 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * See the file LICENSE.txt at the root directory of this source
11  * distribution for additional information about the GNU GPL.
12  *
13  * For using ViSP with software that can not be combined with the GNU
14  * GPL, please contact Inria about acquiring a ViSP Professional
15  * Edition License.
16  *
17  * See http://visp.inria.fr for more information.
18  *
19  * This software was developed at:
20  * Inria Rennes - Bretagne Atlantique
21  * Campus Universitaire de Beaulieu
22  * 35042 Rennes Cedex
23  * France
24  *
25  * If you have questions regarding the use of this file, please contact
26  * Inria at visp@inria.fr
27  *
28  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30  *
31  * Description:
32  * XML parser to load and save camera intrinsic parameters.
33  *
34  * Authors:
35  * Anthony Saunier
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  */
54 /* --- LABEL XML ------------------------------------------------------------
55  */
56 /* --------------------------------------------------------------------------
57  */
58 
59 #define LABEL_XML_ROOT "root"
60 #define LABEL_XML_CAMERA "camera"
61 #define LABEL_XML_CAMERA_NAME "name"
62 #define LABEL_XML_WIDTH "image_width"
63 #define LABEL_XML_HEIGHT "image_height"
64 #define LABEL_XML_SUBSAMPLING_WIDTH "subsampling_width"
65 #define LABEL_XML_SUBSAMPLING_HEIGHT "subsampling_height"
66 #define LABEL_XML_FULL_WIDTH "full_width"
67 #define LABEL_XML_FULL_HEIGHT "full_height"
68 #define LABEL_XML_MODEL "model"
69 #define LABEL_XML_MODEL_TYPE "type"
70 #define LABEL_XML_U0 "u0"
71 #define LABEL_XML_V0 "v0"
72 #define LABEL_XML_PX "px"
73 #define LABEL_XML_PY "py"
74 #define LABEL_XML_KUD "kud"
75 #define LABEL_XML_KDU "kdu"
76 
77 #define LABEL_XML_MODEL_WITHOUT_DISTORTION "perspectiveProjWithoutDistortion"
78 #define LABEL_XML_MODEL_WITH_DISTORTION "perspectiveProjWithDistortion"
79 
80 #define LABEL_XML_ADDITIONAL_INFO "additional_information"
81 
85  : vpXmlParser(), camera(), camera_name(), image_width(0), image_height(0), subsampling_width(0),
86  subsampling_height(0), full_width(0), full_height(0)
87 {
88 }
94  : vpXmlParser(twinParser), camera(twinParser.camera), camera_name(twinParser.camera_name), image_width(0),
95  image_height(0), subsampling_width(0), subsampling_height(0), full_width(0), full_height(0)
96 
97 {
98  this->image_width = twinParser.image_width;
99  this->image_height = twinParser.image_height;
100  this->subsampling_width = twinParser.subsampling_width;
101  this->subsampling_height = twinParser.subsampling_height;
102  this->full_width = twinParser.full_width;
103  this->full_height = twinParser.full_height;
104 }
105 
112 {
113  this->camera = twinParser.camera;
114  this->camera_name = twinParser.camera_name;
115  this->image_width = twinParser.image_width;
116  this->image_height = twinParser.image_height;
117  this->subsampling_width = twinParser.subsampling_width;
118  this->subsampling_height = twinParser.subsampling_height;
119  this->full_width = twinParser.full_width;
120  this->full_height = twinParser.full_height;
121  return *this;
122 }
123 
138 int vpXmlParserCamera::parse(vpCameraParameters &cam, const std::string &filename, const std::string &cam_name,
140  const unsigned int im_width, const unsigned int im_height)
141 {
142  xmlDocPtr doc;
143  xmlNodePtr node;
144 
145  doc = xmlParseFile(filename.c_str());
146  if (doc == NULL) {
147  return SEQUENCE_ERROR;
148  }
149 
150  node = xmlDocGetRootElement(doc);
151  if (node == NULL) {
152  xmlFreeDoc(doc);
153  return SEQUENCE_ERROR;
154  }
155 
156  int ret = this->read(doc, node, cam_name, projModel, im_width, im_height);
157 
158  cam = camera;
159 
160  xmlFreeDoc(doc);
161 
162  return ret;
163 }
164 
208 int vpXmlParserCamera::save(const vpCameraParameters &cam, const std::string &filename, const std::string &cam_name,
209  const unsigned int im_width, const unsigned int im_height,
210  const std::string &additionalInfo)
211 {
212  xmlDocPtr doc;
213  xmlNodePtr node;
214  xmlNodePtr nodeCamera = NULL;
215 
216  doc = xmlReadFile(filename.c_str(), NULL, XML_PARSE_NOWARNING + XML_PARSE_NOERROR + XML_PARSE_NOBLANKS);
217  if (doc == NULL) {
218  doc = xmlNewDoc((xmlChar *)"1.0");
219  node = xmlNewNode(NULL, (xmlChar *)LABEL_XML_ROOT);
220  xmlDocSetRootElement(doc, node);
221  xmlNodePtr node_tmp = xmlNewComment((xmlChar *)"This file stores intrinsic camera parameters used\n"
222  " in the vpCameraParameters Class of ViSP available\n"
223  " at https://visp.inria.fr/download/ .\n"
224  " It can be read with the parse method of\n"
225  " the vpXmlParserCamera class.");
226  xmlAddChild(node, node_tmp);
227  }
228 
229  node = xmlDocGetRootElement(doc);
230  if (node == NULL) {
231  xmlFreeDoc(doc);
232  return SEQUENCE_ERROR;
233  }
234 
235  this->camera = cam;
236 
237  int nbCamera = count(doc, node, cam_name, cam.get_projModel(), im_width, im_height);
238  if (nbCamera > 0) {
239  // vpCERROR << nbCamera
240  // << " set(s) of camera parameters is(are) already "<<
241  // std::endl
242  // << "available in the file with your specifications : "<<
243  // std::endl
244  // << "precise the grabber parameters or delete manually"<<
245  // std::endl
246  // << "the previous one."<<std::endl;
247  xmlFreeDoc(doc);
248  return SEQUENCE_ERROR;
249  }
250 
251  nodeCamera = find_camera(doc, node, cam_name, im_width, im_height);
252  if (nodeCamera == NULL) {
253  write(node, cam_name, im_width, im_height);
254  } else {
255  write_camera(nodeCamera);
256  }
257 
258  if (!additionalInfo.empty()) {
259  // Get camera node pointer
260  nodeCamera = find_camera(doc, node, cam_name, im_width, im_height);
261 
262  // Additional information provided by the user
263  xmlNodePtr nodeAdditionalInfo = find_additional_info(nodeCamera);
264 
265  if (nodeAdditionalInfo == NULL) {
266  // Create the additional information node
267  xmlNodePtr node_comment = xmlNewComment((xmlChar *)"Additional information");
268  xmlAddChild(nodeCamera, node_comment);
269 
270  nodeAdditionalInfo = xmlNewNode(NULL, (xmlChar *)LABEL_XML_ADDITIONAL_INFO);
271  xmlAddChild(nodeCamera, nodeAdditionalInfo);
272  }
273 
274  if (nodeAdditionalInfo != NULL) {
275  // Add the information in this specific node
276  xmlNodePtr pNewNode = NULL;
277  xmlParseInNodeContext(nodeAdditionalInfo, additionalInfo.c_str(), (int)additionalInfo.length(), 0, &pNewNode);
278  if (pNewNode != NULL) {
279  while (pNewNode != NULL) {
280  xmlAddChild(nodeAdditionalInfo, xmlCopyNode(pNewNode, 1));
281  pNewNode = pNewNode->next;
282  }
283 
284  xmlFreeNode(pNewNode);
285  }
286  }
287  }
288 
289  xmlSaveFormatFile(filename.c_str(), doc, 1);
290  xmlFreeDoc(doc);
291 
292  return SEQUENCE_OK;
293 }
294 
313 int vpXmlParserCamera::read(xmlDocPtr doc, xmlNodePtr node, const std::string &cam_name,
315  const unsigned int im_width, const unsigned int im_height,
316  const unsigned int subsampl_width, const unsigned int subsampl_height)
317 {
318  // char * val_char;
319  vpXmlCodeType prop;
320 
322  unsigned int nbCamera = 0;
323 
324  for (node = node->xmlChildrenNode; node != NULL; node = node->next) {
325  if (node->type != XML_ELEMENT_NODE)
326  continue;
327  if (SEQUENCE_OK != str2xmlcode((char *)(node->name), prop)) {
328  prop = CODE_XML_OTHER;
329  back = SEQUENCE_ERROR;
330  }
331  /*
332  switch (prop)
333  {
334  case CODE_XML_CAMERA:
335  if (SEQUENCE_OK == this->read_camera (doc, node, camera_name, projModel,
336  image_width, image_height, subsampling_width, subsampling_height)){
337  nbCamera++;
338  }
339  break;
340  default:
341  back = SEQUENCE_ERROR;
342  break;
343  }
344  */
345  if (prop == CODE_XML_CAMERA) {
346  if (SEQUENCE_OK ==
347  this->read_camera(doc, node, cam_name, projModel, im_width, im_height, subsampl_width, subsampl_height))
348  nbCamera++;
349  } else
350  back = SEQUENCE_ERROR;
351  }
352 
353  if (nbCamera == 0) {
354  back = SEQUENCE_ERROR;
355  vpCERROR << "No camera parameters is available" << std::endl << "with your specifications" << std::endl;
356  } else if (nbCamera > 1) {
357  back = SEQUENCE_ERROR;
358  vpCERROR << nbCamera << " sets of camera parameters are available" << std::endl
359  << "with your specifications : " << std::endl
360  << "precise your choice..." << std::endl;
361  }
362 
363  return back;
364 }
384 int vpXmlParserCamera::count(xmlDocPtr doc, xmlNodePtr node, const std::string &cam_name,
386  const unsigned int im_width, const unsigned int im_height,
387  const unsigned int subsampl_width, const unsigned int subsampl_height)
388 {
389  // char * val_char;
390  vpXmlCodeType prop;
391  int nbCamera = 0;
392 
393  for (node = node->xmlChildrenNode; node != NULL; node = node->next) {
394  if (node->type != XML_ELEMENT_NODE)
395  continue;
396  if (SEQUENCE_OK != str2xmlcode((char *)(node->name), prop)) {
397  prop = CODE_XML_OTHER;
398  }
399  /*
400  switch (prop)
401  {
402  case CODE_XML_CAMERA:
403  if (SEQUENCE_OK == this->read_camera (doc, node, camera_name, projModel,
404  image_width, image_height,
405  subsampling_width, subsampling_height)){
406  nbCamera++;
407  }
408  break;
409  default:
410  break;
411  }
412  */
413  if (prop == CODE_XML_CAMERA) {
414  if (SEQUENCE_OK ==
415  this->read_camera(doc, node, cam_name, projModel, im_width, im_height, subsampl_width, subsampl_height))
416  nbCamera++;
417  }
418  }
419 
420  return nbCamera;
421 }
422 
442 xmlNodePtr vpXmlParserCamera::find_camera(xmlDocPtr doc, xmlNodePtr node, const std::string &cam_name,
443  const unsigned int im_width, const unsigned int im_height,
444  const unsigned int subsampl_width, const unsigned int subsampl_height)
445 {
446  // char * val_char;
447  vpXmlCodeType prop;
448 
449  for (node = node->xmlChildrenNode; node != NULL; node = node->next) {
450  if (node->type != XML_ELEMENT_NODE)
451  continue;
452  if (SEQUENCE_OK != str2xmlcode((char *)(node->name), prop)) {
453  prop = CODE_XML_OTHER;
454  }
455  /*
456  switch (prop)
457  {
458  case CODE_XML_CAMERA:
459  if (SEQUENCE_OK == this->read_camera_header(doc, node, camera_name,
460  image_width, image_height,
461  subsampling_width, subsampling_height)){
462  return node;
463  }
464  break;
465  default:
466  break;
467  }
468  */
469  if (prop == CODE_XML_CAMERA) {
470  if (SEQUENCE_OK ==
471  this->read_camera_header(doc, node, cam_name, im_width, im_height, subsampl_width, subsampl_height))
472  return node;
473  }
474  }
475  return NULL;
476 }
477 
487 xmlNodePtr vpXmlParserCamera::find_additional_info(xmlNodePtr node)
488 {
489  vpXmlCodeType prop;
490 
491  for (node = node->xmlChildrenNode; node != NULL; node = node->next) {
492  if (node->type != XML_ELEMENT_NODE) {
493  continue;
494  }
495 
496  if (SEQUENCE_OK != str2xmlcode((char *)(node->name), prop)) {
497  prop = CODE_XML_OTHER;
498  }
499 
500  if (prop == CODE_XML_ADDITIONAL_INFO) {
501  // We found the node
502  return node;
503  }
504  }
505 
506  return NULL;
507 }
508 
528 int vpXmlParserCamera::read_camera(xmlDocPtr doc, xmlNodePtr node, const std::string &cam_name,
530  const unsigned int im_width, const unsigned int im_height,
531  const unsigned int subsampl_width, const unsigned int subsampl_height)
532 {
533  vpXmlCodeType prop;
534  /* read value in the XML file. */
535  std::string camera_name_tmp = "";
536  unsigned int image_height_tmp = 0;
537  unsigned int image_width_tmp = 0;
538  unsigned int subsampling_width_tmp = 0;
539  unsigned int subsampling_height_tmp = 0;
540  // unsigned int full_width_tmp = 0;
541  // unsigned int full_height_tmp = 0;
542  vpCameraParameters cam_tmp;
543  vpCameraParameters cam_tmp_model;
544  bool projModelFound = false;
546 
547  for (node = node->xmlChildrenNode; node != NULL; node = node->next) {
548  // vpDEBUG_TRACE (15, "Carac : %s.", node ->name);
549  if (node->type != XML_ELEMENT_NODE)
550  continue;
551  if (SEQUENCE_OK != str2xmlcode((char *)(node->name), prop)) {
552  prop = CODE_XML_OTHER;
553  back = SEQUENCE_ERROR;
554  }
555 
556  switch (prop) {
557  case CODE_XML_CAMERA_NAME: {
558  char *val_char = xmlReadCharChild(doc, node);
559  camera_name_tmp = val_char;
560  std::cout << "Found camera with name: \"" << camera_name_tmp << "\"" << std::endl;
561  xmlFree(val_char);
562  break;
563  }
564  case CODE_XML_WIDTH:
565  image_width_tmp = xmlReadUnsignedIntChild(doc, node);
566  break;
567 
568  case CODE_XML_HEIGHT:
569  image_height_tmp = xmlReadUnsignedIntChild(doc, node);
570  break;
572  subsampling_width_tmp = xmlReadUnsignedIntChild(doc, node);
573  break;
575  subsampling_height_tmp = xmlReadUnsignedIntChild(doc, node);
576  break;
577  // case CODE_XML_FULL_WIDTH:
578  // full_width_tmp = xmlReadUnsignedIntChild(doc, node);
579  // break;
580 
581  // case CODE_XML_FULL_HEIGHT:
582  // full_height_tmp = xmlReadUnsignedIntChild(doc, node);
583  // break;
584 
585  case CODE_XML_MODEL:
586  back = read_camera_model(doc, node, cam_tmp_model);
587  if (cam_tmp_model.get_projModel() == projModel) {
588  cam_tmp = cam_tmp_model;
589  projModelFound = true;
590  }
591  break;
592 
594  break;
595 
596  case CODE_XML_BAD:
597  case CODE_XML_OTHER:
598  case CODE_XML_CAMERA:
600  case CODE_XML_FULL_WIDTH:
601  case CODE_XML_MODEL_TYPE:
602  case CODE_XML_U0:
603  case CODE_XML_V0:
604  case CODE_XML_PX:
605  case CODE_XML_PY:
606  case CODE_XML_KUD:
607  case CODE_XML_KDU:
608  default:
609  back = SEQUENCE_ERROR;
610  break;
611  }
612  }
613  // Create a specific test for subsampling_width and subsampling_height to
614  // ensure that division by zero is not possible in the next test
615  bool test_subsampling_width = true;
616  bool test_subsampling_height = true;
617 
618  if (subsampling_width) {
619  test_subsampling_width = (abs((int)subsampl_width - (int)subsampling_width_tmp) <
620  (allowedPixelDiffOnImageSize * (int)(subsampling_width_tmp / subsampling_width)));
621  }
622  if (subsampling_height) {
623  test_subsampling_height = (abs((int)subsampl_height - (int)subsampling_height_tmp) <
624  (allowedPixelDiffOnImageSize * (int)(subsampling_height_tmp / subsampling_height)));
625  }
626  if (!((projModelFound == true) && (cam_name == camera_name_tmp) &&
627  (abs((int)im_width - (int)image_width_tmp) < allowedPixelDiffOnImageSize || im_width == 0) &&
628  (abs((int)im_height - (int)image_height_tmp) < allowedPixelDiffOnImageSize || im_height == 0) &&
629  (test_subsampling_width) && (test_subsampling_height))) {
630  back = SEQUENCE_ERROR;
631  } else {
632  this->camera = cam_tmp;
633  this->camera_name = camera_name_tmp;
634  this->image_width = image_width_tmp;
635  this->image_height = image_height_tmp;
636  this->subsampling_width = subsampling_width_tmp;
637  this->subsampling_height = subsampling_height_tmp;
638  this->full_width = subsampling_width_tmp * image_width_tmp;
639  this->full_height = subsampling_height_tmp * image_height_tmp;
640  }
641  return back;
642 }
662 int vpXmlParserCamera::read_camera_header(xmlDocPtr doc, xmlNodePtr node, const std::string &cam_name,
663  const unsigned int im_width, const unsigned int im_height,
664  const unsigned int subsampl_width, const unsigned int subsampl_height)
665 {
666  vpXmlCodeType prop;
667  /* read value in the XML file. */
668  std::string camera_name_tmp = "";
669  unsigned int image_height_tmp = 0;
670  unsigned int image_width_tmp = 0;
671  unsigned int subsampling_width_tmp = 0;
672  unsigned int subsampling_height_tmp = 0;
673  // unsigned int full_width_tmp = 0;
674  // unsigned int full_height_tmp = 0;
676 
677  for (node = node->xmlChildrenNode; node != NULL; node = node->next) {
678  // vpDEBUG_TRACE (15, "Carac : %s.", node ->name);
679  if (node->type != XML_ELEMENT_NODE)
680  continue;
681  if (SEQUENCE_OK != str2xmlcode((char *)(node->name), prop)) {
682  prop = CODE_XML_OTHER;
683  back = SEQUENCE_ERROR;
684  }
685 
686  switch (prop) {
687  case CODE_XML_CAMERA_NAME: {
688  char *val_char = xmlReadCharChild(doc, node);
689  camera_name_tmp = val_char;
690  xmlFree(val_char);
691  } break;
692 
693  case CODE_XML_WIDTH:
694  image_width_tmp = xmlReadUnsignedIntChild(doc, node);
695  break;
696 
697  case CODE_XML_HEIGHT:
698  image_height_tmp = xmlReadUnsignedIntChild(doc, node);
699  break;
701  subsampling_width_tmp = xmlReadUnsignedIntChild(doc, node);
702  break;
704  subsampling_height_tmp = xmlReadUnsignedIntChild(doc, node);
705  break;
706  // case CODE_XML_FULL_WIDTH:
707  // full_width_tmp = xmlReadUnsignedIntChild(doc, node);
708  // break;
709 
710  // case CODE_XML_FULL_HEIGHT:
711  // full_height_tmp = xmlReadUnsignedIntChild(doc, node);
712  // break;
713 
714  case CODE_XML_MODEL:
715  break;
716 
718  break;
719 
720  case CODE_XML_BAD:
721  case CODE_XML_OTHER:
722  case CODE_XML_CAMERA:
724  case CODE_XML_FULL_WIDTH:
725  case CODE_XML_MODEL_TYPE:
726  case CODE_XML_U0:
727  case CODE_XML_V0:
728  case CODE_XML_PX:
729  case CODE_XML_PY:
730  case CODE_XML_KUD:
731  case CODE_XML_KDU:
732  default:
733  back = SEQUENCE_ERROR;
734  break;
735  }
736  }
737  if (!((cam_name == camera_name_tmp) && (im_width == image_width_tmp || im_width == 0) &&
738  (im_height == image_height_tmp || im_height == 0) &&
739  (subsampl_width == subsampling_width_tmp || subsampl_width == 0) &&
740  (subsampl_height == subsampling_height_tmp || subsampl_height == 0))) {
741  back = SEQUENCE_ERROR;
742  }
743  return back;
744 }
745 
756 vpXmlParserCamera::vpXmlCodeSequenceType vpXmlParserCamera::read_camera_model(xmlDocPtr doc, xmlNodePtr node,
757  vpCameraParameters &cam_tmp)
758 {
759  // counter of the number of read parameters
760  int nb = 0;
761  vpXmlCodeType prop;
762  /* read value in the XML file. */
763 
764  char *model_type = NULL;
765  double u0 = cam_tmp.get_u0();
766  double v0 = cam_tmp.get_v0();
767  double px = cam_tmp.get_px();
768  double py = cam_tmp.get_py();
769  double kud = cam_tmp.get_kud();
770  double kdu = cam_tmp.get_kdu();
772  int validation = 0;
773 
774  for (node = node->xmlChildrenNode; node != NULL; node = node->next) {
775  // vpDEBUG_TRACE (15, "Carac : %s.", node ->name);
776  if (node->type != XML_ELEMENT_NODE)
777  continue;
778  if (SEQUENCE_OK != str2xmlcode((char *)(node->name), prop)) {
779  prop = CODE_XML_OTHER;
780  back = SEQUENCE_ERROR;
781  }
782 
783  switch (prop) {
784  case CODE_XML_MODEL_TYPE: {
785  if (model_type != NULL) {
786  xmlFree(model_type);
787  }
788  model_type = xmlReadCharChild(doc, node);
789  nb++;
790  validation = validation | 0x01;
791  } break;
792  case CODE_XML_U0:
793  u0 = xmlReadDoubleChild(doc, node);
794  nb++;
795  validation = validation | 0x02;
796  break;
797  case CODE_XML_V0:
798  v0 = xmlReadDoubleChild(doc, node);
799  nb++;
800  validation = validation | 0x04;
801  break;
802  case CODE_XML_PX:
803  px = xmlReadDoubleChild(doc, node);
804  nb++;
805  validation = validation | 0x08;
806  break;
807  case CODE_XML_PY:
808  py = xmlReadDoubleChild(doc, node);
809  nb++;
810  validation = validation | 0x10;
811  break;
812  case CODE_XML_KUD:
813  kud = xmlReadDoubleChild(doc, node);
814  nb++;
815  validation = validation | 0x20;
816  break;
817  case CODE_XML_KDU:
818  kdu = xmlReadDoubleChild(doc, node);
819  nb++;
820  validation = validation | 0x40;
821  break;
822  case CODE_XML_BAD:
823  case CODE_XML_OTHER:
824  case CODE_XML_CAMERA:
826  case CODE_XML_HEIGHT:
827  case CODE_XML_WIDTH:
831  case CODE_XML_FULL_WIDTH:
832  case CODE_XML_MODEL:
834  default:
835  back = SEQUENCE_ERROR;
836  break;
837  }
838  }
839 
840  if (model_type == NULL) {
841  vpERROR_TRACE("projection model type doesn't match with any known model !");
842  return SEQUENCE_ERROR;
843  }
844 
845  if (!strcmp(model_type, LABEL_XML_MODEL_WITHOUT_DISTORTION)) {
846  if (nb != 5 || validation != 0x1F) {
847  vpCERROR << "ERROR in 'model' field:\n";
848  vpCERROR << "it must contain 5 parameters\n";
849  xmlFree(model_type);
850 
851  return SEQUENCE_ERROR;
852  }
853  cam_tmp.initPersProjWithoutDistortion(px, py, u0, v0);
854  } else if (!strcmp(model_type, LABEL_XML_MODEL_WITH_DISTORTION)) {
855  if (nb != 7 || validation != 0x7F) {
856  vpCERROR << "ERROR in 'model' field:\n";
857  vpCERROR << "it must contain 7 parameters\n";
858  xmlFree(model_type);
859 
860  return SEQUENCE_ERROR;
861  }
862  cam_tmp.initPersProjWithDistortion(px, py, u0, v0, kud, kdu);
863  } else {
864  vpERROR_TRACE("projection model type doesn't match with any known model !");
865  xmlFree(model_type);
866 
867  return SEQUENCE_ERROR;
868  }
869  xmlFree(model_type);
870 
871  return back;
872 }
873 
891 int vpXmlParserCamera::write(xmlNodePtr node, const std::string &cam_name, const unsigned int im_width,
892  const unsigned int im_height, const unsigned int subsampl_width,
893  const unsigned int subsampl_height)
894 {
895  int back = SEQUENCE_OK;
896 
897  xmlNodePtr node_tmp;
898  xmlNodePtr node_camera;
899 
900  // <camera>
901  node_camera = xmlNewNode(NULL, (xmlChar *)LABEL_XML_CAMERA);
902  xmlAddChild(node, node_camera);
903  {
904  //<name>
905 
906  if (!cam_name.empty()) {
907  node_tmp = xmlNewComment((xmlChar *)"Name of the camera");
908  xmlAddChild(node_camera, node_tmp);
909  xmlNewTextChild(node_camera, NULL, (xmlChar *)LABEL_XML_CAMERA_NAME, (xmlChar *)cam_name.c_str());
910  }
911 
912  if (im_width != 0 || im_height != 0) {
913  char str[11];
914  //<image_width>
915  node_tmp = xmlNewComment((xmlChar *)"Size of the image on which camera "
916  "calibration was performed");
917  xmlAddChild(node_camera, node_tmp);
918 
919  sprintf(str, "%u", im_width);
920  xmlNewTextChild(node_camera, NULL, (xmlChar *)LABEL_XML_WIDTH, (xmlChar *)str);
921  //<image_height>
922 
923  sprintf(str, "%u", im_height);
924  xmlNewTextChild(node_camera, NULL, (xmlChar *)LABEL_XML_HEIGHT, (xmlChar *)str);
925  if (subsampling_width != 0 || subsampling_height != 0) {
926  node_tmp = xmlNewComment((xmlChar *)"Subsampling used to obtain the "
927  "current size of the image.");
928  xmlAddChild(node_camera, node_tmp);
929 
930  //<subsampling_width>
931  sprintf(str, "%u", subsampl_width);
932  xmlNewTextChild(node_camera, NULL, (xmlChar *)LABEL_XML_SUBSAMPLING_WIDTH, (xmlChar *)str);
933  //<subsampling_height>
934  sprintf(str, "%u", subsampl_height);
935  xmlNewTextChild(node_camera, NULL, (xmlChar *)LABEL_XML_SUBSAMPLING_HEIGHT, (xmlChar *)str);
936  node_tmp = xmlNewComment((xmlChar *)"The full size is the sensor size actually used to "
937  "grab the image. full_width = subsampling_width * "
938  "image_width");
939  xmlAddChild(node_camera, node_tmp);
940 
941  //<full_width>
942  sprintf(str, "%u", im_width * subsampl_width);
943  xmlNewTextChild(node_camera, NULL, (xmlChar *)LABEL_XML_FULL_WIDTH, (xmlChar *)str);
944  //<full_height>
945  sprintf(str, "%u", im_height * subsampl_height);
946  xmlNewTextChild(node_camera, NULL, (xmlChar *)LABEL_XML_FULL_HEIGHT, (xmlChar *)str);
947  }
948  }
949 
950  node_tmp = xmlNewComment((xmlChar *)"Intrinsic camera parameters "
951  "computed for each projection model");
952 
953  xmlAddChild(node_camera, node_tmp);
954 
955  back = write_camera(node_camera);
956  }
957  return back;
958 }
966 int vpXmlParserCamera::write_camera(xmlNodePtr node_camera)
967 {
968  xmlNodePtr node_model;
969  xmlNodePtr node_tmp;
970 
971  int back = SEQUENCE_OK;
972  switch (camera.get_projModel()) {
974  //<model>
975  node_model = xmlNewNode(NULL, (xmlChar *)LABEL_XML_MODEL);
976  xmlAddChild(node_camera, node_model);
977  {
978  char str[21];
979  node_tmp = xmlNewComment((xmlChar *)"Projection model type");
980  xmlAddChild(node_model, node_tmp);
981 
982  //<type>without_distortion</type>
983  xmlNewTextChild(node_model, NULL, (xmlChar *)LABEL_XML_MODEL_TYPE, (xmlChar *)LABEL_XML_MODEL_WITHOUT_DISTORTION);
984 
985  node_tmp = xmlNewComment((xmlChar *)"Pixel ratio");
986  xmlAddChild(node_model, node_tmp);
987  //<px>
988  sprintf(str, "%.10f", camera.get_px());
989  xmlNewTextChild(node_model, NULL, (xmlChar *)LABEL_XML_PX, (xmlChar *)str);
990  //<py>
991  sprintf(str, "%.10f", camera.get_py());
992  xmlNewTextChild(node_model, NULL, (xmlChar *)LABEL_XML_PY, (xmlChar *)str);
993 
994  node_tmp = xmlNewComment((xmlChar *)"Principal point");
995  xmlAddChild(node_model, node_tmp);
996 
997  //<u0>
998  sprintf(str, "%.10f", camera.get_u0());
999  xmlNewTextChild(node_model, NULL, (xmlChar *)LABEL_XML_U0, (xmlChar *)str);
1000  //<v0>
1001  sprintf(str, "%.10f", camera.get_v0());
1002  xmlNewTextChild(node_model, NULL, (xmlChar *)LABEL_XML_V0, (xmlChar *)str);
1003  }
1004  break;
1006  //<model>
1007  node_model = xmlNewNode(NULL, (xmlChar *)LABEL_XML_MODEL);
1008  xmlAddChild(node_camera, node_model);
1009  {
1010  char str[21];
1011  node_tmp = xmlNewComment((xmlChar *)"Projection model type");
1012  xmlAddChild(node_model, node_tmp);
1013  //<type>with_distortion</type>
1014  xmlNewTextChild(node_model, NULL, (xmlChar *)LABEL_XML_MODEL_TYPE, (xmlChar *)LABEL_XML_MODEL_WITH_DISTORTION);
1015 
1016  node_tmp = xmlNewComment((xmlChar *)"Pixel ratio");
1017  xmlAddChild(node_model, node_tmp);
1018  //<px>
1019  sprintf(str, "%.10f", camera.get_px());
1020  xmlNewTextChild(node_model, NULL, (xmlChar *)LABEL_XML_PX, (xmlChar *)str);
1021  //<py>
1022  sprintf(str, "%.10f", camera.get_py());
1023  xmlNewTextChild(node_model, NULL, (xmlChar *)LABEL_XML_PY, (xmlChar *)str);
1024 
1025  node_tmp = xmlNewComment((xmlChar *)"Principal point");
1026  xmlAddChild(node_model, node_tmp);
1027  //<u0>
1028  sprintf(str, "%.10f", camera.get_u0());
1029  xmlNewTextChild(node_model, NULL, (xmlChar *)LABEL_XML_U0, (xmlChar *)str);
1030  //<v0>
1031  sprintf(str, "%.10f", camera.get_v0());
1032  xmlNewTextChild(node_model, NULL, (xmlChar *)LABEL_XML_V0, (xmlChar *)str);
1033 
1034  //<kud>
1035  node_tmp = xmlNewComment((xmlChar *)"Undistorted to distorted distortion parameter");
1036  xmlAddChild(node_model, node_tmp);
1037  sprintf(str, "%.10f", camera.get_kud());
1038  xmlNewTextChild(node_model, NULL, (xmlChar *)LABEL_XML_KUD, (xmlChar *)str);
1039 
1040  //<kud>
1041  node_tmp = xmlNewComment((xmlChar *)"Distorted to undistorted distortion parameter");
1042  xmlAddChild(node_model, node_tmp);
1043  sprintf(str, "%.10f", camera.get_kdu());
1044  xmlNewTextChild(node_model, NULL, (xmlChar *)LABEL_XML_KDU, (xmlChar *)str);
1045  }
1046  break;
1047  }
1048  return back;
1049 }
1050 
1059 vpXmlParserCamera::vpXmlCodeSequenceType vpXmlParserCamera::str2xmlcode(char *str, vpXmlCodeType &res)
1060 {
1061  vpXmlCodeType val_int = CODE_XML_BAD;
1063 
1064  // DEBUG_TRACE (9, "# Entree :str=%s.", str);
1065 
1066  if (!strcmp(str, LABEL_XML_CAMERA)) {
1067  val_int = CODE_XML_CAMERA;
1068  } else if (!strcmp(str, LABEL_XML_CAMERA_NAME)) {
1069  val_int = CODE_XML_CAMERA_NAME;
1070  } else if (!strcmp(str, LABEL_XML_MODEL)) {
1071  val_int = CODE_XML_MODEL;
1072  } else if (!strcmp(str, LABEL_XML_MODEL_TYPE)) {
1073  val_int = CODE_XML_MODEL_TYPE;
1074  } else if (!strcmp(str, LABEL_XML_WIDTH)) {
1075  val_int = CODE_XML_WIDTH;
1076  } else if (!strcmp(str, LABEL_XML_HEIGHT)) {
1077  val_int = CODE_XML_HEIGHT;
1078  } else if (!strcmp(str, LABEL_XML_SUBSAMPLING_WIDTH)) {
1079  val_int = CODE_XML_SUBSAMPLING_WIDTH;
1080  } else if (!strcmp(str, LABEL_XML_SUBSAMPLING_HEIGHT)) {
1081  val_int = CODE_XML_SUBSAMPLING_HEIGHT;
1082  } else if (!strcmp(str, LABEL_XML_FULL_WIDTH)) {
1083  val_int = CODE_XML_FULL_WIDTH;
1084  } else if (!strcmp(str, LABEL_XML_FULL_HEIGHT)) {
1085  val_int = CODE_XML_FULL_HEIGHT;
1086  } else if (!strcmp(str, LABEL_XML_U0)) {
1087  val_int = CODE_XML_U0;
1088  } else if (!strcmp(str, LABEL_XML_V0)) {
1089  val_int = CODE_XML_V0;
1090  } else if (!strcmp(str, LABEL_XML_PX)) {
1091  val_int = CODE_XML_PX;
1092  } else if (!strcmp(str, LABEL_XML_PY)) {
1093  val_int = CODE_XML_PY;
1094  } else if (!strcmp(str, LABEL_XML_KUD)) {
1095  val_int = CODE_XML_KUD;
1096  } else if (!strcmp(str, LABEL_XML_KDU)) {
1097  val_int = CODE_XML_KDU;
1098  } else if (!strcmp(str, LABEL_XML_ADDITIONAL_INFO)) {
1099  val_int = CODE_XML_ADDITIONAL_INFO;
1100  } else {
1101  val_int = CODE_XML_OTHER;
1102  }
1103  res = val_int;
1104 
1105  return back;
1106 }
1107 #elif !defined(VISP_BUILD_SHARED_LIBS)
1108 // Work arround to avoid warning: libvisp_core.a(vpXmlParserCamera.cpp.o) has
1109 // no symbols
1110 void dummy_vpXmlParserCamera(){};
1111 #endif // VISP_HAVE_XML2
vpXmlParserCamera::CODE_XML_CAMERA_NAME
Definition: vpXmlParserCamera.h:197
vpXmlParserCamera::parse
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)
Definition: vpXmlParserCamera.cpp:137
vpXmlParserCamera::vpXmlParserCamera
vpXmlParserCamera()
Definition: vpXmlParserCamera.cpp:83
vpXmlParserCamera::CODE_XML_OTHER
Definition: vpXmlParserCamera.h:195
vpXmlParserCamera::operator=
vpXmlParserCamera & operator=(const vpXmlParserCamera &twinparser)
Definition: vpXmlParserCamera.cpp:110
vpCameraParameters::get_py
double get_py() const
Definition: vpCameraParameters.h:332
vpXmlParser
This class intends to simplify the creation of xml parser based on the libxml2 third party library.
Definition: vpXmlParser.h:176
vpXmlParser::xmlReadDoubleChild
double xmlReadDoubleChild(xmlDocPtr doc, xmlNodePtr node)
Definition: vpXmlParser.cpp:211
vpXmlParserCamera::CODE_XML_SUBSAMPLING_HEIGHT
Definition: vpXmlParserCamera.h:201
vpXmlParserCamera::CODE_XML_KDU
Definition: vpXmlParserCamera.h:211
vpXmlParserCamera::CODE_XML_BAD
Definition: vpXmlParserCamera.h:194
vpCameraParameters
Generic class defining intrinsic camera parameters.
Definition: vpCameraParameters.h:232
vpCameraParameters::perspectiveProjWithoutDistortion
Definition: vpCameraParameters.h:239
vpXmlParserCamera::CODE_XML_V0
Definition: vpXmlParserCamera.h:207
vpXmlParserCamera::vpXmlCodeType
vpXmlCodeType
Definition: vpXmlParserCamera.h:193
vpXmlParserCamera
XML parser to load and save intrinsic camera parameters.
Definition: vpXmlParserCamera.h:187
vpXmlParserCamera::CODE_XML_U0
Definition: vpXmlParserCamera.h:206
vpXmlParserCamera::CODE_XML_MODEL_TYPE
Definition: vpXmlParserCamera.h:205
vpXmlParserCamera::CODE_XML_SUBSAMPLING_WIDTH
Definition: vpXmlParserCamera.h:200
vpXmlParserCamera::CODE_XML_CAMERA
Definition: vpXmlParserCamera.h:196
vpXmlParser::xmlReadCharChild
char * xmlReadCharChild(xmlDocPtr doc, xmlNodePtr node)
Definition: vpXmlParser.cpp:99
vpCameraParameters::vpCameraParametersProjType
vpCameraParametersProjType
Definition: vpCameraParameters.h:238
vpXmlParserCamera::CODE_XML_PX
Definition: vpXmlParserCamera.h:208
vpCameraParameters::get_px
double get_px() const
Definition: vpCameraParameters.h:329
vpXmlParserCamera::CODE_XML_ADDITIONAL_INFO
Definition: vpXmlParserCamera.h:212
vpXmlParserCamera::CODE_XML_MODEL
Definition: vpXmlParserCamera.h:204
vpXmlParserCamera::CODE_XML_KUD
Definition: vpXmlParserCamera.h:210
vpXmlParserCamera::CODE_XML_PY
Definition: vpXmlParserCamera.h:209
vpCameraParameters::get_v0
double get_v0() const
Definition: vpCameraParameters.h:334
vpCERROR
#define vpCERROR
Definition: vpDebug.h:364
vpXmlParserCamera::vpXmlCodeSequenceType
vpXmlCodeSequenceType
Definition: vpXmlParserCamera.h:215
vpCameraParameters::get_projModel
vpCameraParametersProjType get_projModel() const
Definition: vpCameraParameters.h:338
vpERROR_TRACE
#define vpERROR_TRACE
Definition: vpDebug.h:392
vpXmlParser::xmlReadUnsignedIntChild
unsigned int xmlReadUnsignedIntChild(xmlDocPtr doc, xmlNodePtr node)
Definition: vpXmlParser.cpp:177
vpXmlParserCamera::save
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, const std::string &additionalInfo="")
Definition: vpXmlParserCamera.cpp:207
vpXmlParserCamera::CODE_XML_FULL_WIDTH
Definition: vpXmlParserCamera.h:203
vpCameraParameters::initPersProjWithDistortion
void initPersProjWithDistortion(const double px, const double py, const double u0, const double v0, const double kud, const double kdu)
Definition: vpCameraParameters.cpp:248
vpXmlParserCamera::CODE_XML_FULL_HEIGHT
Definition: vpXmlParserCamera.h:202
vpXmlParserCamera::SEQUENCE_ERROR
Definition: vpXmlParserCamera.h:215
vpCameraParameters::get_u0
double get_u0() const
Definition: vpCameraParameters.h:333
vpCameraParameters::perspectiveProjWithDistortion
Definition: vpCameraParameters.h:241
vpXmlParserCamera::CODE_XML_HEIGHT
Definition: vpXmlParserCamera.h:198
vpCameraParameters::get_kud
double get_kud() const
Definition: vpCameraParameters.h:335
vpXmlParserCamera::SEQUENCE_OK
Definition: vpXmlParserCamera.h:215
vpXmlParserCamera::CODE_XML_WIDTH
Definition: vpXmlParserCamera.h:199
vpCameraParameters::initPersProjWithoutDistortion
void initPersProjWithoutDistortion(const double px, const double py, const double u0, const double v0)
Definition: vpCameraParameters.cpp:182
vpCameraParameters::get_kdu
double get_kdu() const
Definition: vpCameraParameters.h:336