Visual Servoing Platform  version 3.0.1
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
vpXmlParserCamera.cpp
1 /****************************************************************************
2  *
3  * This file is part of the ViSP software.
4  * Copyright (C) 2005 - 2017 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 
77 #define LABEL_XML_ADDITIONAL_INFO "additional_information"
78 
82  : vpXmlParser(),
83  camera(), camera_name(), image_width(0), image_height(0),
84  subsampling_width(0), subsampling_height(0), full_width(0), full_height(0)
85 {
86 }
92  : vpXmlParser(twinParser),
93  camera(), camera_name(), image_width(0), image_height(0),
94  subsampling_width(0), subsampling_height(0), full_width(0), full_height(0)
95 
96 {
97  this->camera = twinParser.camera;
98  this->camera_name = twinParser.camera_name;
99  this->image_width = twinParser.image_width;
100  this->image_height = twinParser.image_height;
101  this->subsampling_width = twinParser.subsampling_width;
102  this->subsampling_height = twinParser.subsampling_height;
103  this->full_width = twinParser.full_width;
104  this->full_height = twinParser.full_height;
105 }
106 
114  this->camera = twinParser.camera;
115  this->camera_name = twinParser.camera_name;
116  this->image_width = twinParser.image_width;
117  this->image_height = twinParser.image_height;
118  this->subsampling_width = twinParser.subsampling_width;
119  this->subsampling_height = twinParser.subsampling_height;
120  this->full_width = twinParser.full_width;
121  this->full_height = twinParser.full_height;
122  return *this ;
123 }
124 
139 int
140 vpXmlParserCamera::parse(vpCameraParameters &cam, const std::string &filename,
141  const std::string& cam_name,
143  const unsigned int im_width,
144  const unsigned int im_height)
145 {
146  xmlDocPtr doc;
147  xmlNodePtr node;
148 
149  doc = xmlParseFile(filename.c_str());
150  if (doc == NULL)
151  {
152  return SEQUENCE_ERROR;
153  }
154 
155  node = xmlDocGetRootElement(doc);
156  if (node == NULL)
157  {
158  xmlFreeDoc(doc);
159  return SEQUENCE_ERROR;
160  }
161 
162  int ret = this ->read (doc, node, cam_name, projModel, im_width, im_height);
163 
164  cam = camera ;
165 
166  xmlFreeDoc(doc);
167 
168  return ret;
169 }
170 
214 int
215 vpXmlParserCamera::save(const vpCameraParameters &cam, const std::string &filename,
216  const std::string& cam_name,
217  const unsigned int im_width,
218  const unsigned int im_height,
219  const std::string &additionalInfo)
220 {
221  xmlDocPtr doc;
222  xmlNodePtr node;
223  xmlNodePtr nodeCamera = NULL;
224 
225  doc = xmlReadFile(filename.c_str(), NULL, XML_PARSE_NOWARNING + XML_PARSE_NOERROR
226  + XML_PARSE_NOBLANKS);
227  if (doc == NULL){
228  doc = xmlNewDoc ((xmlChar*)"1.0");
229  node = xmlNewNode(NULL,(xmlChar*)LABEL_XML_ROOT);
230  xmlDocSetRootElement(doc,node);
231  xmlNodePtr node_tmp = xmlNewComment((xmlChar*)
232  "This file stores intrinsic camera parameters used\n"
233  " in the vpCameraParameters Class of ViSP available\n"
234  " at http://www.irisa.fr/lagadic/visp/visp.html .\n"
235  " It can be read with the parse method of\n"
236  " the vpXmlParserCamera class.");
237  xmlAddChild(node,node_tmp);
238  }
239 
240  node = xmlDocGetRootElement(doc);
241  if (node == NULL)
242  {
243  xmlFreeDoc(doc);
244  return SEQUENCE_ERROR;
245  }
246 
247  this->camera = cam;
248 
249  int nbCamera = count(doc, node, cam_name,cam.get_projModel(),
250  im_width, im_height);
251  if( nbCamera > 0){
252 // vpCERROR << nbCamera
253 // << " set(s) of camera parameters is(are) already "<< std::endl
254 // << "available in the file with your specifications : "<< std::endl
255 // << "precise the grabber parameters or delete manually"<< std::endl
256 // << "the previous one."<<std::endl;
257  xmlFreeDoc(doc);
258  return SEQUENCE_ERROR;
259  }
260 
261  nodeCamera = find_camera(doc, node, cam_name, im_width, im_height);
262  if(nodeCamera == NULL){
263  write(node, cam_name, im_width, im_height);
264  }
265  else{
266  write_camera(nodeCamera);
267  }
268 
269  if(!additionalInfo.empty()) {
270  //Get camera node pointer
271  nodeCamera = find_camera(doc, node, cam_name, im_width, im_height);
272 
273  //Additional information provided by the user
274  xmlNodePtr nodeAdditionalInfo = find_additional_info(nodeCamera);
275 
276  if(nodeAdditionalInfo == NULL) {
277  //Create the additional information node
278  xmlNodePtr node_comment = xmlNewComment((xmlChar*)"Additional information");
279  xmlAddChild(nodeCamera,node_comment);
280 
281  nodeAdditionalInfo = xmlNewNode(NULL, (xmlChar*) LABEL_XML_ADDITIONAL_INFO);
282  xmlAddChild(nodeCamera, nodeAdditionalInfo);
283  }
284 
285  if(nodeAdditionalInfo != NULL) {
286  //Add the information in this specific node
287  xmlNodePtr pNewNode = NULL;
288  xmlParseInNodeContext(nodeAdditionalInfo, additionalInfo.c_str(), (int) additionalInfo.length(), 0, &pNewNode);
289  if (pNewNode != NULL) {
290  while (pNewNode != NULL) {
291  xmlAddChild(nodeAdditionalInfo, xmlCopyNode(pNewNode, 1));
292  pNewNode = pNewNode->next;
293  }
294 
295  xmlFreeNode(pNewNode);
296  }
297  }
298  }
299 
300  xmlSaveFormatFile(filename.c_str(), doc, 1);
301  xmlFreeDoc(doc);
302 
303  return SEQUENCE_OK;
304 }
305 
306 
307 
326 int
327 vpXmlParserCamera::read (xmlDocPtr doc, xmlNodePtr node,
328  const std::string& cam_name,
330  const unsigned int im_width,
331  const unsigned int im_height,
332  const unsigned int subsampl_width,
333  const unsigned int subsampl_height)
334 {
335  // char * val_char;
336  vpXmlCodeType prop;
337 
339  unsigned int nbCamera = 0;
340 
341  for (node = node->xmlChildrenNode; node != NULL; node = node->next)
342  {
343  if (node->type != XML_ELEMENT_NODE) continue;
344  if (SEQUENCE_OK != str2xmlcode ((char*)(node ->name), prop))
345  {
346  prop = CODE_XML_OTHER;
347  back = SEQUENCE_ERROR;
348  }
349  /*
350  switch (prop)
351  {
352  case CODE_XML_CAMERA:
353  if (SEQUENCE_OK == this->read_camera (doc, node, camera_name, projModel,
354  image_width, image_height, subsampling_width, subsampling_height)){
355  nbCamera++;
356  }
357  break;
358  default:
359  back = SEQUENCE_ERROR;
360  break;
361  }
362  */
363  if (prop == CODE_XML_CAMERA) {
364  if (SEQUENCE_OK == this->read_camera (doc, node, cam_name, projModel,
365  im_width, im_height, subsampl_width, subsampl_height))
366  nbCamera++;
367  }
368  else back = SEQUENCE_ERROR;
369  }
370 
371  if (nbCamera == 0){
372  back = SEQUENCE_ERROR;
373  vpCERROR << "No camera parameters is available" << std::endl
374  << "with your specifications" << std::endl;
375  }
376  else if(nbCamera > 1){
377  back = SEQUENCE_ERROR;
378  vpCERROR << nbCamera << " sets of camera parameters are available" << std::endl
379  << "with your specifications : " << std::endl
380  << "precise your choice..." << std::endl;
381  }
382 
383  return back;
384 }
404 int
405 vpXmlParserCamera::count (xmlDocPtr doc, xmlNodePtr node,
406  const std::string& cam_name,
408  const unsigned int im_width,
409  const unsigned int im_height,
410  const unsigned int subsampl_width,
411  const unsigned int subsampl_height)
412 {
413  // char * val_char;
414  vpXmlCodeType prop;
415  int nbCamera = 0;
416 
417  for (node = node->xmlChildrenNode; node != NULL; node = node->next)
418  {
419  if (node->type != XML_ELEMENT_NODE) continue;
420  if (SEQUENCE_OK != str2xmlcode ((char*)(node ->name), prop))
421  {
422  prop = CODE_XML_OTHER;
423  }
424  /*
425  switch (prop)
426  {
427  case CODE_XML_CAMERA:
428  if (SEQUENCE_OK == this->read_camera (doc, node, camera_name, projModel,
429  image_width, image_height,
430  subsampling_width, subsampling_height)){
431  nbCamera++;
432  }
433  break;
434  default:
435  break;
436  }
437  */
438  if (prop== CODE_XML_CAMERA) {
439  if (SEQUENCE_OK == this->read_camera (doc, node, cam_name, projModel,
440  im_width, im_height,
441  subsampl_width, subsampl_height))
442  nbCamera++;
443  }
444  }
445 
446  return nbCamera;
447 }
448 
468 xmlNodePtr
469 vpXmlParserCamera::find_camera (xmlDocPtr doc, xmlNodePtr node,
470  const std::string& cam_name,
471  const unsigned int im_width,
472  const unsigned int im_height,
473  const unsigned int subsampl_width,
474  const unsigned int subsampl_height)
475 {
476  // char * val_char;
477  vpXmlCodeType prop;
478 
479  for (node = node->xmlChildrenNode; node != NULL; node = node->next)
480  {
481  if (node->type != XML_ELEMENT_NODE) continue;
482  if (SEQUENCE_OK != str2xmlcode ((char*)(node ->name), prop))
483  {
484  prop = CODE_XML_OTHER;
485  }
486  /*
487  switch (prop)
488  {
489  case CODE_XML_CAMERA:
490  if (SEQUENCE_OK == this->read_camera_header(doc, node, camera_name,
491  image_width, image_height,
492  subsampling_width, subsampling_height)){
493  return node;
494  }
495  break;
496  default:
497  break;
498  }
499  */
500  if(prop == CODE_XML_CAMERA){
501  if (SEQUENCE_OK == this->read_camera_header(doc, node, cam_name,
502  im_width, im_height,
503  subsampl_width, subsampl_height))
504  return node;
505  }
506  }
507  return NULL;
508 }
509 
519 xmlNodePtr
520 vpXmlParserCamera::find_additional_info(xmlNodePtr node) {
521  vpXmlCodeType prop;
522 
523  for (node = node->xmlChildrenNode; node != NULL; node = node->next) {
524  if (node->type != XML_ELEMENT_NODE) {
525  continue;
526  }
527 
528  if (SEQUENCE_OK != str2xmlcode((char*) (node->name), prop)) {
529  prop = CODE_XML_OTHER;
530  }
531 
532  if (prop == CODE_XML_ADDITIONAL_INFO) {
533  //We found the node
534  return node;
535  }
536  }
537 
538  return NULL;
539 }
540 
560 int
561 vpXmlParserCamera::read_camera (xmlDocPtr doc, xmlNodePtr node,
562  const std::string& cam_name,
564  const unsigned int im_width,
565  const unsigned int im_height,
566  const unsigned int subsampl_width,
567  const unsigned int subsampl_height)
568 {
569  vpXmlCodeType prop;
570  /* read value in the XML file. */
571  std::string camera_name_tmp = "";
572  unsigned int image_height_tmp = 0 ;
573  unsigned int image_width_tmp = 0 ;
574  unsigned int subsampling_width_tmp = 0;
575  unsigned int subsampling_height_tmp = 0;
576  // unsigned int full_width_tmp = 0;
577  // unsigned int full_height_tmp = 0;
578  vpCameraParameters cam_tmp;
579  vpCameraParameters cam_tmp_model;
580  bool projModelFound = false;
582 
583  for (node = node->xmlChildrenNode; node != NULL; node = node->next)
584  {
585  // vpDEBUG_TRACE (15, "Carac : %s.", node ->name);
586  if (node->type != XML_ELEMENT_NODE) continue;
587  if (SEQUENCE_OK != str2xmlcode ((char*)(node ->name), prop))
588  {
589  prop = CODE_XML_OTHER;
590  back = SEQUENCE_ERROR;
591  }
592 
593 
594  switch (prop)
595  {
596  case CODE_XML_CAMERA_NAME: {
597  char * val_char = xmlReadCharChild(doc, node);
598  camera_name_tmp = val_char;
599  std::cout << "Found camera with name: \"" << camera_name_tmp << "\"" << std::endl;
600  xmlFree(val_char);
601  break;
602  }
603  case CODE_XML_WIDTH:
604  image_width_tmp = xmlReadUnsignedIntChild(doc, node);
605  break;
606 
607  case CODE_XML_HEIGHT:
608  image_height_tmp = xmlReadUnsignedIntChild(doc, node);
609  break;
611  subsampling_width_tmp = xmlReadUnsignedIntChild(doc, node);
612  break;
614  subsampling_height_tmp = xmlReadUnsignedIntChild(doc, node);
615  break;
616  // case CODE_XML_FULL_WIDTH:
617  // full_width_tmp = xmlReadUnsignedIntChild(doc, node);
618  // break;
619 
620  // case CODE_XML_FULL_HEIGHT:
621  // full_height_tmp = xmlReadUnsignedIntChild(doc, node);
622  // break;
623 
624  case CODE_XML_MODEL:
625  back = read_camera_model(doc, node, cam_tmp_model);
626  if(cam_tmp_model.get_projModel() == projModel){
627  cam_tmp = cam_tmp_model;
628  projModelFound = true;
629  }
630  break;
631 
633  break;
634 
635  case CODE_XML_BAD:
636  case CODE_XML_OTHER:
637  case CODE_XML_CAMERA:
639  case CODE_XML_FULL_WIDTH:
640  case CODE_XML_MODEL_TYPE:
641  case CODE_XML_U0:
642  case CODE_XML_V0:
643  case CODE_XML_PX:
644  case CODE_XML_PY:
645  case CODE_XML_KUD:
646  case CODE_XML_KDU:
647  default:
648  back = SEQUENCE_ERROR;
649  break;
650  }
651 
652  }
653  // Create a specific test for subsampling_width and subsampling_height to ensure that division by zero is not possible in the next test
654  bool test_subsampling_width = true;
655  bool test_subsampling_height = true;
656 
657  if (subsampling_width) {
658  test_subsampling_width = (abs((int)subsampl_width - (int)subsampling_width_tmp) < (allowedPixelDiffOnImageSize * (int)(subsampling_width_tmp / subsampling_width)));
659  }
660  if (subsampling_height) {
661  test_subsampling_height = (abs((int)subsampl_height - (int)subsampling_height_tmp) < (allowedPixelDiffOnImageSize * (int)(subsampling_height_tmp / subsampling_height)));
662  }
663  if( !((projModelFound == true) && (cam_name == camera_name_tmp) &&
664  (abs((int)im_width - (int)image_width_tmp) < allowedPixelDiffOnImageSize || im_width == 0) &&
665  (abs((int)im_height - (int)image_height_tmp) < allowedPixelDiffOnImageSize || im_height == 0) &&
666  (test_subsampling_width)&&
667  (test_subsampling_height))){
668  back = SEQUENCE_ERROR;
669  }
670  else{
671  this->camera = cam_tmp;
672  this->camera_name = camera_name_tmp;
673  this->image_width = image_width_tmp;
674  this->image_height = image_height_tmp;
675  this->subsampling_width = subsampling_width_tmp;
676  this->subsampling_height = subsampling_height_tmp;
677  this->full_width = subsampling_width_tmp * image_width_tmp;
678  this->full_height = subsampling_height_tmp * image_height_tmp;
679  }
680  return back;
681 }
701 int
702 vpXmlParserCamera::
703 read_camera_header (xmlDocPtr doc, xmlNodePtr node,
704  const std::string& cam_name,
705  const unsigned int im_width,
706  const unsigned int im_height,
707  const unsigned int subsampl_width,
708  const unsigned int subsampl_height)
709 {
710  vpXmlCodeType prop;
711  /* read value in the XML file. */
712  std::string camera_name_tmp = "";
713  unsigned int image_height_tmp = 0 ;
714  unsigned int image_width_tmp = 0 ;
715  unsigned int subsampling_width_tmp = 0;
716  unsigned int subsampling_height_tmp = 0;
717  // unsigned int full_width_tmp = 0;
718  // unsigned int full_height_tmp = 0;
720 
721  for (node = node->xmlChildrenNode; node != NULL; node = node->next)
722  {
723  // vpDEBUG_TRACE (15, "Carac : %s.", node ->name);
724  if (node->type != XML_ELEMENT_NODE) continue;
725  if (SEQUENCE_OK != str2xmlcode ((char*)(node ->name), prop))
726  {
727  prop = CODE_XML_OTHER;
728  back = SEQUENCE_ERROR;
729  }
730 
731 
732  switch (prop)
733  {
734  case CODE_XML_CAMERA_NAME:{
735  char * val_char = xmlReadCharChild(doc, node);
736  camera_name_tmp = val_char;
737  xmlFree(val_char);
738  }break;
739 
740  case CODE_XML_WIDTH:
741  image_width_tmp = xmlReadUnsignedIntChild(doc, node);
742  break;
743 
744  case CODE_XML_HEIGHT:
745  image_height_tmp = xmlReadUnsignedIntChild(doc, node);
746  break;
748  subsampling_width_tmp = xmlReadUnsignedIntChild(doc, node);
749  break;
751  subsampling_height_tmp = xmlReadUnsignedIntChild(doc, node);
752  break;
753  // case CODE_XML_FULL_WIDTH:
754  // full_width_tmp = xmlReadUnsignedIntChild(doc, node);
755  // break;
756 
757  // case CODE_XML_FULL_HEIGHT:
758  // full_height_tmp = xmlReadUnsignedIntChild(doc, node);
759  // break;
760 
761  case CODE_XML_MODEL:
762  break;
763 
765  break;
766 
767  case CODE_XML_BAD:
768  case CODE_XML_OTHER:
769  case CODE_XML_CAMERA:
771  case CODE_XML_FULL_WIDTH:
772  case CODE_XML_MODEL_TYPE:
773  case CODE_XML_U0:
774  case CODE_XML_V0:
775  case CODE_XML_PX:
776  case CODE_XML_PY:
777  case CODE_XML_KUD:
778  case CODE_XML_KDU:
779  default:
780  back = SEQUENCE_ERROR;
781  break;
782  }
783  }
784  if( !((cam_name == camera_name_tmp) &&
785  (im_width == image_width_tmp || im_width == 0) &&
786  (im_height == image_height_tmp || im_height == 0) &&
787  (subsampl_width == subsampling_width_tmp ||
788  subsampl_width == 0)&&
789  (subsampl_height == subsampling_height_tmp ||
790  subsampl_height == 0))){
791  back = SEQUENCE_ERROR;
792  }
793  return back;
794 }
795 
807 vpXmlParserCamera::read_camera_model (xmlDocPtr doc, xmlNodePtr node,
808  vpCameraParameters &cam_tmp)
809 {
810  // counter of the number of read parameters
811  int nb = 0;
812  vpXmlCodeType prop;
813  /* read value in the XML file. */
814 
815  char* model_type = NULL;
816  double u0 = cam_tmp.get_u0();
817  double v0 = cam_tmp.get_v0();
818  double px = cam_tmp.get_px();
819  double py = cam_tmp.get_py();
820  double kud = cam_tmp.get_kud();
821  double kdu = cam_tmp.get_kdu();
823  int validation = 0;
824 
825  for (node = node->xmlChildrenNode; node != NULL; node = node->next)
826  {
827  // vpDEBUG_TRACE (15, "Carac : %s.", node ->name);
828  if (node->type != XML_ELEMENT_NODE) continue;
829  if (SEQUENCE_OK != str2xmlcode ((char*)(node ->name), prop))
830  {
831  prop = CODE_XML_OTHER;
832  back = SEQUENCE_ERROR;
833  }
834 
835  switch (prop)
836  {
837  case CODE_XML_MODEL_TYPE:{
838  if(model_type != NULL){
839  xmlFree(model_type);
840  }
841  model_type = xmlReadCharChild(doc, node);
842  nb++;
843  validation = validation | 0x01;
844  }break;
845  case CODE_XML_U0:
846  u0 = xmlReadDoubleChild(doc, node);
847  nb++;
848  validation = validation | 0x02;
849  break;
850  case CODE_XML_V0:
851  v0 = xmlReadDoubleChild(doc, node);
852  nb++;
853  validation = validation | 0x04;
854  break;
855  case CODE_XML_PX:
856  px = xmlReadDoubleChild(doc, node);
857  nb++;
858  validation = validation | 0x08;
859  break;
860  case CODE_XML_PY:
861  py = xmlReadDoubleChild(doc, node);
862  nb++;
863  validation = validation | 0x10;
864  break;
865  case CODE_XML_KUD:
866  kud = xmlReadDoubleChild(doc, node);
867  nb++;
868  validation = validation | 0x20;
869  break;
870  case CODE_XML_KDU:
871  kdu = xmlReadDoubleChild(doc, node);
872  nb++;
873  validation = validation | 0x40;
874  break;
875  case CODE_XML_BAD:
876  case CODE_XML_OTHER:
877  case CODE_XML_CAMERA:
879  case CODE_XML_HEIGHT:
880  case CODE_XML_WIDTH:
884  case CODE_XML_FULL_WIDTH:
885  case CODE_XML_MODEL:
887  default:
888  back = SEQUENCE_ERROR;
889  break;
890  }
891  }
892 
893  if(model_type == NULL) {
894  vpERROR_TRACE("projection model type doesn't match with any known model !");
895  return SEQUENCE_ERROR;
896  }
897 
898  if( !strcmp(model_type,LABEL_XML_MODEL_WITHOUT_DISTORTION)){
899  if (nb != 5 || validation != 0x1F)
900  {
901  vpCERROR <<"ERROR in 'model' field:\n";
902  vpCERROR << "it must contain 5 parameters\n";
903  xmlFree(model_type);
904 
905  return SEQUENCE_ERROR;
906  }
907  cam_tmp.initPersProjWithoutDistortion(px,py,u0,v0) ;
908  }
909  else if( !strcmp(model_type,LABEL_XML_MODEL_WITH_DISTORTION)){
910  if (nb != 7 || validation != 0x7F)
911  {
912  vpCERROR <<"ERROR in 'model' field:\n";
913  vpCERROR << "it must contain 7 parameters\n";
914  xmlFree(model_type);
915 
916  return SEQUENCE_ERROR;
917  }
918  cam_tmp.initPersProjWithDistortion(px,py,u0,v0,kud,kdu);
919  }
920  else{
921  vpERROR_TRACE("projection model type doesn't match with any known model !");
922  xmlFree(model_type);
923 
924  return SEQUENCE_ERROR;
925  }
926  xmlFree(model_type);
927 
928  return back;
929 }
930 
948 int vpXmlParserCamera::
949 write (xmlNodePtr node, const std::string& cam_name,
950  const unsigned int im_width, const unsigned int im_height,
951  const unsigned int subsampl_width,
952  const unsigned int subsampl_height)
953 {
954  int back = SEQUENCE_OK;
955 
956  xmlNodePtr node_tmp;
957  xmlNodePtr node_camera;
958 
959  // <camera>
960  node_camera = xmlNewNode(NULL,(xmlChar*)LABEL_XML_CAMERA);
961  xmlAddChild(node,node_camera);
962  {
963  //<name>
964 
965  if(!cam_name.empty()){
966  node_tmp = xmlNewComment((xmlChar*)"Name of the camera");
967  xmlAddChild(node_camera,node_tmp);
968  xmlNewTextChild(node_camera,NULL,(xmlChar*)LABEL_XML_CAMERA_NAME,
969  (xmlChar*)cam_name.c_str());
970  }
971 
972  if(im_width != 0 || im_height != 0){
973  char str[11];
974  //<image_width>
975  node_tmp = xmlNewComment((xmlChar*)"Size of the image on which camera calibration was performed");
976  xmlAddChild(node_camera,node_tmp);
977 
978  sprintf(str,"%u",im_width);
979  xmlNewTextChild(node_camera,NULL,(xmlChar*)LABEL_XML_WIDTH,(xmlChar*)str);
980  //<image_height>
981 
982  sprintf(str,"%u",im_height);
983  xmlNewTextChild(node_camera,NULL,(xmlChar*)LABEL_XML_HEIGHT,(xmlChar*)str);
984  if(subsampling_width != 0 || subsampling_height != 0){
985  node_tmp = xmlNewComment((xmlChar*)"Subsampling used to obtain the current size of the image.");
986  xmlAddChild(node_camera,node_tmp);
987 
988  //<subsampling_width>
989  sprintf(str,"%u",subsampl_width);
990  xmlNewTextChild(node_camera,NULL,(xmlChar*)LABEL_XML_SUBSAMPLING_WIDTH,
991  (xmlChar*)str);
992  //<subsampling_height>
993  sprintf(str,"%u",subsampl_height);
994  xmlNewTextChild(node_camera,NULL,(xmlChar*)LABEL_XML_SUBSAMPLING_HEIGHT,
995  (xmlChar*)str);
996  node_tmp = xmlNewComment((xmlChar*)"The full size is the sensor size actually used to grab the image. full_width = subsampling_width * image_width");
997  xmlAddChild(node_camera,node_tmp);
998 
999  //<full_width>
1000  sprintf(str,"%u",im_width*subsampl_width);
1001  xmlNewTextChild(node_camera,NULL,(xmlChar*)LABEL_XML_FULL_WIDTH,
1002  (xmlChar*)str);
1003  //<full_height>
1004  sprintf(str,"%u",im_height*subsampl_height);
1005  xmlNewTextChild(node_camera,NULL,(xmlChar*)LABEL_XML_FULL_HEIGHT,
1006  (xmlChar*)str);
1007  }
1008  }
1009 
1010  node_tmp = xmlNewComment((xmlChar*)"Intrinsic camera parameters computed for each projection model");
1011 
1012  xmlAddChild(node_camera,node_tmp);
1013 
1014  back = write_camera(node_camera);
1015  }
1016  return back;
1017 }
1025 int vpXmlParserCamera::
1026 write_camera(xmlNodePtr node_camera){
1027  xmlNodePtr node_model;
1028  xmlNodePtr node_tmp;
1029 
1030  int back = SEQUENCE_OK;
1031  switch(camera.get_projModel()){
1033  //<model>
1034  node_model = xmlNewNode(NULL,(xmlChar*)LABEL_XML_MODEL);
1035  xmlAddChild(node_camera,node_model);
1036  {
1037  char str[21];
1038  node_tmp = xmlNewComment((xmlChar*)"Projection model type");
1039  xmlAddChild(node_model,node_tmp);
1040 
1041  //<type>without_distortion</type>
1042  xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_MODEL_TYPE,
1043  (xmlChar*)LABEL_XML_MODEL_WITHOUT_DISTORTION);
1044 
1045  node_tmp = xmlNewComment((xmlChar*)"Pixel ratio");
1046  xmlAddChild(node_model,node_tmp);
1047  //<px>
1048  sprintf(str,"%.10f",camera.get_px());
1049  xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_PX,(xmlChar*)str);
1050  //<py>
1051  sprintf(str,"%.10f",camera.get_py());
1052  xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_PY,(xmlChar*)str);
1053 
1054  node_tmp = xmlNewComment((xmlChar*)"Principal point");
1055  xmlAddChild(node_model,node_tmp);
1056 
1057  //<u0>
1058  sprintf(str,"%.10f",camera.get_u0());
1059  xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_U0,(xmlChar*)str);
1060  //<v0>
1061  sprintf(str,"%.10f",camera.get_v0());
1062  xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_V0,(xmlChar*)str);
1063  }
1064  break;
1066  //<model>
1067  node_model = xmlNewNode(NULL,(xmlChar*)LABEL_XML_MODEL);
1068  xmlAddChild(node_camera,node_model);
1069  {
1070  char str[21];
1071  node_tmp = xmlNewComment((xmlChar*)"Projection model type");
1072  xmlAddChild(node_model,node_tmp);
1073  //<type>with_distortion</type>
1074  xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_MODEL_TYPE,
1075  (xmlChar*)LABEL_XML_MODEL_WITH_DISTORTION);
1076 
1077  node_tmp = xmlNewComment((xmlChar*)"Pixel ratio");
1078  xmlAddChild(node_model,node_tmp);
1079  //<px>
1080  sprintf(str,"%.10f",camera.get_px());
1081  xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_PX,(xmlChar*)str);
1082  //<py>
1083  sprintf(str,"%.10f",camera.get_py());
1084  xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_PY,(xmlChar*)str);
1085 
1086  node_tmp = xmlNewComment((xmlChar*)"Principal point");
1087  xmlAddChild(node_model,node_tmp);
1088  //<u0>
1089  sprintf(str,"%.10f",camera.get_u0());
1090  xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_U0,(xmlChar*)str);
1091  //<v0>
1092  sprintf(str,"%.10f",camera.get_v0());
1093  xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_V0,(xmlChar*)str);
1094 
1095  //<kud>
1096  node_tmp = xmlNewComment((xmlChar*)"Undistorted to distorted distortion parameter");
1097  xmlAddChild(node_model,node_tmp);
1098  sprintf(str,"%.10f",camera.get_kud());
1099  xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_KUD,(xmlChar*)str);
1100 
1101  //<kud>
1102  node_tmp = xmlNewComment((xmlChar*)"Distorted to undistorted distortion parameter");
1103  xmlAddChild(node_model,node_tmp);
1104  sprintf(str,"%.10f",camera.get_kdu());
1105  xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_KDU,(xmlChar*)str);
1106  }
1107  break;
1108  }
1109  return back;
1110 }
1111 
1121 vpXmlParserCamera::str2xmlcode (char * str, vpXmlCodeType & res)
1122 {
1123  vpXmlCodeType val_int = CODE_XML_BAD;
1125 
1126  // DEBUG_TRACE (9, "# Entree :str=%s.", str);
1127 
1128  if (! strcmp (str, LABEL_XML_CAMERA))
1129  {
1130  val_int = CODE_XML_CAMERA;
1131  }
1132  else if (! strcmp (str, LABEL_XML_CAMERA_NAME))
1133  {
1134  val_int = CODE_XML_CAMERA_NAME;
1135  }
1136  else if (! strcmp (str, LABEL_XML_MODEL))
1137  {
1138  val_int = CODE_XML_MODEL;
1139  }
1140  else if (! strcmp (str, LABEL_XML_MODEL_TYPE))
1141  {
1142  val_int = CODE_XML_MODEL_TYPE;
1143  }
1144  else if (! strcmp (str, LABEL_XML_WIDTH))
1145  {
1146  val_int = CODE_XML_WIDTH;
1147  }
1148  else if (! strcmp (str, LABEL_XML_HEIGHT))
1149  {
1150  val_int = CODE_XML_HEIGHT;
1151  }
1152  else if (! strcmp (str, LABEL_XML_SUBSAMPLING_WIDTH))
1153  {
1154  val_int = CODE_XML_SUBSAMPLING_WIDTH;
1155  }
1156  else if (! strcmp (str, LABEL_XML_SUBSAMPLING_HEIGHT))
1157  {
1158  val_int = CODE_XML_SUBSAMPLING_HEIGHT;
1159  }
1160  else if (! strcmp (str, LABEL_XML_FULL_WIDTH))
1161  {
1162  val_int = CODE_XML_FULL_WIDTH;
1163  }
1164  else if (! strcmp (str, LABEL_XML_FULL_HEIGHT))
1165  {
1166  val_int = CODE_XML_FULL_HEIGHT;
1167  }
1168  else if (! strcmp (str, LABEL_XML_U0))
1169  {
1170  val_int = CODE_XML_U0;
1171  }
1172  else if (! strcmp (str, LABEL_XML_V0))
1173  {
1174  val_int = CODE_XML_V0;
1175  }
1176  else if (! strcmp (str, LABEL_XML_PX))
1177  {
1178  val_int = CODE_XML_PX;
1179  }
1180  else if (! strcmp (str, LABEL_XML_PY))
1181  {
1182  val_int = CODE_XML_PY;
1183  }
1184  else if (! strcmp (str, LABEL_XML_KUD))
1185  {
1186  val_int = CODE_XML_KUD;
1187  }
1188  else if (! strcmp (str, LABEL_XML_KDU))
1189  {
1190  val_int = CODE_XML_KDU;
1191  }
1192  else if (! strcmp (str, LABEL_XML_ADDITIONAL_INFO))
1193  {
1194  val_int = CODE_XML_ADDITIONAL_INFO;
1195  }
1196  else
1197  {
1198  val_int = CODE_XML_OTHER;
1199  }
1200  res = val_int;
1201 
1202  return back;
1203 }
1204 #elif !defined(VISP_BUILD_SHARED_LIBS)
1205 // Work arround to avoid warning: libvisp_core.a(vpXmlParserCamera.cpp.o) has no symbols
1206 void dummy_vpXmlParserCamera() {};
1207 #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:175
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 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="")
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)