49 #include <visp/vpXmlParserCamera.h>
55 #include <visp/vpDebug.h>
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"
78 #define LABEL_XML_MODEL_WITHOUT_DISTORTION "perspectiveProjWithoutDistortion"
79 #define LABEL_XML_MODEL_WITH_DISTORTION "perspectiveProjWithDistortion"
85 camera(), camera_name(), image_width(0), image_height(0),
86 subsampling_width(0), subsampling_height(0), full_width(0), full_height(0)
95 camera(), camera_name(), image_width(0), image_height(0),
96 subsampling_width(0), subsampling_height(0), full_width(0), full_height(0)
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;
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;
143 const std::string& cam_name,
145 const unsigned int im_width,
146 const unsigned int im_height)
151 doc = xmlParseFile(filename);
157 node = xmlDocGetRootElement(doc);
164 int ret =
this ->read (doc, node, cam_name, projModel, im_width, im_height);
188 const std::string& cam_name,
189 const unsigned int im_width,
190 const unsigned int im_height)
194 xmlNodePtr nodeCamera = NULL;
196 doc = xmlReadFile(filename,NULL,XML_PARSE_NOWARNING + XML_PARSE_NOERROR
197 + XML_PARSE_NOBLANKS);
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);
211 node = xmlDocGetRootElement(doc);
220 int nbCamera = count(doc, node, cam_name,cam.
get_projModel(),
221 im_width, im_height);
232 nodeCamera = find_camera(doc, node, camera_name, image_width, image_height);
233 if(nodeCamera == NULL){
234 write(node, camera_name, image_width, image_height);
237 write_camera(nodeCamera);
240 xmlSaveFormatFile(filename,doc,1);
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)
281 for (node = node->xmlChildrenNode; node != NULL; node = node->next)
283 if (node->type != XML_ELEMENT_NODE)
continue;
284 if (
SEQUENCE_OK != str2xmlcode ((
char*)(node ->name), prop))
304 if (
SEQUENCE_OK == this->read_camera (doc, node, cam_name, projModel,
305 im_width, im_height, subsampl_width, subsampl_height))
313 vpCERROR <<
"No camera parameters is available" << std::endl
314 <<
"with your specifications" << std::endl;
316 else if(nbCamera > 1){
318 vpCERROR << nbCamera <<
" sets of camera parameters are available" << std::endl
319 <<
"with your specifications : " << std::endl
320 <<
"precise your choice..." << std::endl;
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)
357 for (node = node->xmlChildrenNode; node != NULL; node = node->next)
359 if (node->type != XML_ELEMENT_NODE)
continue;
360 if (
SEQUENCE_OK != str2xmlcode ((
char*)(node ->name), prop))
379 if (
SEQUENCE_OK == this->read_camera (doc, node, cam_name, projModel,
381 subsampl_width, subsampl_height))
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)
418 for (node = node->xmlChildrenNode; node != NULL; node = node->next)
420 if (node->type != XML_ELEMENT_NODE)
continue;
421 if (
SEQUENCE_OK != str2xmlcode ((
char*)(node ->name), prop))
440 if (
SEQUENCE_OK == this->read_camera_header(doc, node, cam_name,
442 subsampl_width, subsampl_height))
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)
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;
488 bool projModelFound =
false;
491 for (node = node->xmlChildrenNode; node != NULL; node = node->next)
494 if (node->type != XML_ELEMENT_NODE)
continue;
495 if (
SEQUENCE_OK != str2xmlcode ((
char*)(node ->name), prop))
506 camera_name_tmp = val_char;
532 back = read_camera_model(doc, node, cam_tmp_model);
534 cam_tmp = cam_tmp_model;
535 projModelFound =
true;
558 bool test_subsampling_width =
true;
559 bool test_subsampling_height =
true;
561 if (subsampling_width) {
562 test_subsampling_width = (abs((
int)subsampl_width - (
int)subsampling_width_tmp) < (allowedPixelDiffOnImageSize * (int)(subsampling_width_tmp / subsampling_width)));
564 if (subsampling_height) {
565 test_subsampling_height = (abs((
int)subsampl_height - (
int)subsampling_height_tmp) < (allowedPixelDiffOnImageSize * (int)(subsampling_height_tmp / subsampling_height)));
567 if( !((projModelFound ==
true) && (cam_name == camera_name_tmp) &&
568 (abs((
int)im_width - (int)image_width_tmp) < allowedPixelDiffOnImageSize || im_width == 0) &&
569 (abs((
int)im_height - (int)image_height_tmp) < allowedPixelDiffOnImageSize || im_height == 0) &&
570 (test_subsampling_width)&&
571 (test_subsampling_height))){
575 this->camera = cam_tmp;
576 this->camera_name = camera_name_tmp;
577 this->image_width = image_width_tmp;
578 this->image_height = image_height_tmp;
579 this->subsampling_width = subsampling_width_tmp;
580 this->subsampling_height = subsampling_height_tmp;
581 this->full_width = subsampling_width_tmp * image_width_tmp;
582 this->full_height = subsampling_height_tmp * image_height_tmp;
607 read_camera_header (xmlDocPtr doc, xmlNodePtr node,
608 const std::string& cam_name,
609 const unsigned int im_width,
610 const unsigned int im_height,
611 const unsigned int subsampl_width,
612 const unsigned int subsampl_height)
616 std::string camera_name_tmp =
"";
617 unsigned int image_height_tmp = 0 ;
618 unsigned int image_width_tmp = 0 ;
619 unsigned int subsampling_width_tmp = 0;
620 unsigned int subsampling_height_tmp = 0;
625 for (node = node->xmlChildrenNode; node != NULL; node = node->next)
628 if (node->type != XML_ELEMENT_NODE)
continue;
629 if (
SEQUENCE_OK != str2xmlcode ((
char*)(node ->name), prop))
640 camera_name_tmp = val_char;
685 if( !((cam_name == camera_name_tmp) &&
686 (im_width == image_width_tmp || im_width == 0) &&
687 (im_height == image_height_tmp || im_height == 0) &&
688 (subsampl_width == subsampling_width_tmp ||
689 subsampl_width == 0)&&
690 (subsampl_height == subsampling_height_tmp ||
691 subsampl_height == 0))){
708 vpXmlParserCamera::read_camera_model (xmlDocPtr doc, xmlNodePtr node,
716 char* model_type = NULL;
717 double u0 = cam_tmp.
get_u0();
718 double v0 = cam_tmp.
get_v0();
719 double px = cam_tmp.
get_px();
720 double py = cam_tmp.
get_py();
721 double kud = cam_tmp.
get_kud();
722 double kdu = cam_tmp.
get_kdu();
726 for (node = node->xmlChildrenNode; node != NULL; node = node->next)
729 if (node->type != XML_ELEMENT_NODE)
continue;
730 if (
SEQUENCE_OK != str2xmlcode ((
char*)(node ->name), prop))
739 if(model_type != NULL){
744 validation = validation | 0x01;
749 validation = validation | 0x02;
754 validation = validation | 0x04;
759 validation = validation | 0x08;
764 validation = validation | 0x10;
769 validation = validation | 0x20;
774 validation = validation | 0x40;
793 if(model_type == NULL) {
794 vpERROR_TRACE(
"projection model type doesn't match with any known model !");
798 if( !strcmp(model_type,LABEL_XML_MODEL_WITHOUT_DISTORTION)){
799 if (nb != 5 || validation != 0x1F)
801 vpCERROR <<
"ERROR in 'model' field:\n";
802 vpCERROR <<
"it must contain 5 parameters\n";
809 else if( !strcmp(model_type,LABEL_XML_MODEL_WITH_DISTORTION)){
810 if (nb != 7 || validation != 0x7F)
812 vpCERROR <<
"ERROR in 'model' field:\n";
813 vpCERROR <<
"it must contain 7 parameters\n";
821 vpERROR_TRACE(
"projection model type doesn't match with any known model !");
848 int vpXmlParserCamera::
849 write (xmlNodePtr node,
const std::string& cam_name,
850 const unsigned int im_width,
const unsigned int im_height,
851 const unsigned int subsampl_width,
852 const unsigned int subsampl_height)
857 xmlNodePtr node_camera;
860 node_camera = xmlNewNode(NULL,(xmlChar*)LABEL_XML_CAMERA);
861 xmlAddChild(node,node_camera);
865 if(!cam_name.empty()){
866 node_tmp = xmlNewComment((xmlChar*)
"Name of the camera");
867 xmlAddChild(node_camera,node_tmp);
868 xmlNewTextChild(node_camera,NULL,(xmlChar*)LABEL_XML_CAMERA_NAME,
869 (xmlChar*)cam_name.c_str());
872 if(im_width != 0 || im_height != 0){
875 node_tmp = xmlNewComment((xmlChar*)
"Size of the image on which camera calibration was performed");
876 xmlAddChild(node_camera,node_tmp);
878 sprintf(str,
"%u",im_width);
879 xmlNewTextChild(node_camera,NULL,(xmlChar*)LABEL_XML_WIDTH,(xmlChar*)str);
882 sprintf(str,
"%u",im_height);
883 xmlNewTextChild(node_camera,NULL,(xmlChar*)LABEL_XML_HEIGHT,(xmlChar*)str);
884 if(subsampling_width != 0 || subsampling_height != 0){
885 node_tmp = xmlNewComment((xmlChar*)
"Subsampling used to obtain the current size of the image.");
886 xmlAddChild(node_camera,node_tmp);
889 sprintf(str,
"%u",subsampl_width);
890 xmlNewTextChild(node_camera,NULL,(xmlChar*)LABEL_XML_SUBSAMPLING_WIDTH,
893 sprintf(str,
"%u",subsampl_height);
894 xmlNewTextChild(node_camera,NULL,(xmlChar*)LABEL_XML_SUBSAMPLING_HEIGHT,
896 node_tmp = xmlNewComment((xmlChar*)
"The full size is the sensor size actually used to grab the image. full_width = subsampling_width * image_width");
897 xmlAddChild(node_camera,node_tmp);
900 sprintf(str,
"%u",im_width*subsampl_width);
901 xmlNewTextChild(node_camera,NULL,(xmlChar*)LABEL_XML_FULL_WIDTH,
904 sprintf(str,
"%u",im_height*subsampl_height);
905 xmlNewTextChild(node_camera,NULL,(xmlChar*)LABEL_XML_FULL_HEIGHT,
910 node_tmp = xmlNewComment((xmlChar*)
"Intrinsic camera parameters computed for each projection model");
912 xmlAddChild(node_camera,node_tmp);
914 back = write_camera(node_camera);
925 int vpXmlParserCamera::
926 write_camera(xmlNodePtr node_camera){
927 xmlNodePtr node_model;
934 node_model = xmlNewNode(NULL,(xmlChar*)LABEL_XML_MODEL);
935 xmlAddChild(node_camera,node_model);
938 node_tmp = xmlNewComment((xmlChar*)
"Projection model type");
939 xmlAddChild(node_model,node_tmp);
942 xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_MODEL_TYPE,
943 (xmlChar*)LABEL_XML_MODEL_WITHOUT_DISTORTION);
945 node_tmp = xmlNewComment((xmlChar*)
"Pixel ratio");
946 xmlAddChild(node_model,node_tmp);
948 sprintf(str,
"%.10f",camera.
get_px());
949 xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_PX,(xmlChar*)str);
951 sprintf(str,
"%.10f",camera.
get_py());
952 xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_PY,(xmlChar*)str);
954 node_tmp = xmlNewComment((xmlChar*)
"Principal point");
955 xmlAddChild(node_model,node_tmp);
958 sprintf(str,
"%.10f",camera.
get_u0());
959 xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_U0,(xmlChar*)str);
961 sprintf(str,
"%.10f",camera.
get_v0());
962 xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_V0,(xmlChar*)str);
967 node_model = xmlNewNode(NULL,(xmlChar*)LABEL_XML_MODEL);
968 xmlAddChild(node_camera,node_model);
971 node_tmp = xmlNewComment((xmlChar*)
"Projection model type");
972 xmlAddChild(node_model,node_tmp);
974 xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_MODEL_TYPE,
975 (xmlChar*)LABEL_XML_MODEL_WITH_DISTORTION);
977 node_tmp = xmlNewComment((xmlChar*)
"Pixel ratio");
978 xmlAddChild(node_model,node_tmp);
980 sprintf(str,
"%.10f",camera.
get_px());
981 xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_PX,(xmlChar*)str);
983 sprintf(str,
"%.10f",camera.
get_py());
984 xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_PY,(xmlChar*)str);
986 node_tmp = xmlNewComment((xmlChar*)
"Principal point");
987 xmlAddChild(node_model,node_tmp);
989 sprintf(str,
"%.10f",camera.
get_u0());
990 xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_U0,(xmlChar*)str);
992 sprintf(str,
"%.10f",camera.
get_v0());
993 xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_V0,(xmlChar*)str);
996 node_tmp = xmlNewComment((xmlChar*)
"Undistorted to distorted distortion parameter");
997 xmlAddChild(node_model,node_tmp);
998 sprintf(str,
"%.10f",camera.
get_kud());
999 xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_KUD,(xmlChar*)str);
1002 node_tmp = xmlNewComment((xmlChar*)
"Distorted to undistorted distortion parameter");
1003 xmlAddChild(node_model,node_tmp);
1004 sprintf(str,
"%.10f",camera.
get_kdu());
1005 xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_KDU,(xmlChar*)str);
1021 vpXmlParserCamera::str2xmlcode (
char * str, vpXmlCodeType & res)
1028 if (! strcmp (str, LABEL_XML_CAMERA))
1032 else if (! strcmp (str, LABEL_XML_CAMERA_NAME))
1036 else if (! strcmp (str, LABEL_XML_MODEL))
1040 else if (! strcmp (str, LABEL_XML_MODEL_TYPE))
1044 else if (! strcmp (str, LABEL_XML_WIDTH))
1048 else if (! strcmp (str, LABEL_XML_HEIGHT))
1052 else if (! strcmp (str, LABEL_XML_SUBSAMPLING_WIDTH))
1056 else if (! strcmp (str, LABEL_XML_SUBSAMPLING_HEIGHT))
1060 else if (! strcmp (str, LABEL_XML_FULL_WIDTH))
1064 else if (! strcmp (str, LABEL_XML_FULL_HEIGHT))
1068 else if (! strcmp (str, LABEL_XML_U0))
1072 else if (! strcmp (str, LABEL_XML_V0))
1076 else if (! strcmp (str, LABEL_XML_PX))
1080 else if (! strcmp (str, LABEL_XML_PY))
1084 else if (! strcmp (str, LABEL_XML_KUD))
1088 else if (! strcmp (str, LABEL_XML_KDU))
1100 #endif //VISP_HAVE_XML2
Perspective projection without distortion model.
vpXmlParserCamera & operator=(const vpXmlParserCamera &twinparser)
double xmlReadDoubleChild(xmlDocPtr doc, xmlNodePtr node)
int save(const vpCameraParameters &cam, const char *filename, const std::string &camera_name, const unsigned int image_width=0, const unsigned int image_height=0)
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...
vpCameraParametersProjType
Generic class defining intrinsic camera parameters.
Perspective projection with distortion model.
int parse(vpCameraParameters &cam, const char *filename, const std::string &camera_name, const vpCameraParameters::vpCameraParametersProjType &projModel, const unsigned int image_width=0, const unsigned int image_height=0)
unsigned int xmlReadUnsignedIntChild(xmlDocPtr doc, xmlNodePtr node)
vpCameraParametersProjType get_projModel() const
void initPersProjWithDistortion(const double px, const double py, const double u0, const double v0, const double kud, const double kdu)