45 #include <visp3/core/vpXmlParserCamera.h>
51 #include <visp3/core/vpDebug.h>
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"
74 #define LABEL_XML_MODEL_WITHOUT_DISTORTION "perspectiveProjWithoutDistortion"
75 #define LABEL_XML_MODEL_WITH_DISTORTION "perspectiveProjWithDistortion"
81 camera(), camera_name(), image_width(0), image_height(0),
82 subsampling_width(0), subsampling_height(0), full_width(0), full_height(0)
91 camera(), camera_name(), image_width(0), image_height(0),
92 subsampling_width(0), subsampling_height(0), full_width(0), full_height(0)
95 this->camera = twinParser.camera;
96 this->camera_name = twinParser.camera_name;
97 this->image_width = twinParser.image_width;
98 this->image_height = twinParser.image_height;
99 this->subsampling_width = twinParser.subsampling_width;
100 this->subsampling_height = twinParser.subsampling_height;
101 this->full_width = twinParser.full_width;
102 this->full_height = twinParser.full_height;
112 this->camera = twinParser.camera;
113 this->camera_name = twinParser.camera_name;
114 this->image_width = twinParser.image_width;
115 this->image_height = twinParser.image_height;
116 this->subsampling_width = twinParser.subsampling_width;
117 this->subsampling_height = twinParser.subsampling_height;
118 this->full_width = twinParser.full_width;
119 this->full_height = twinParser.full_height;
139 const std::string& cam_name,
141 const unsigned int im_width,
142 const unsigned int im_height)
147 doc = xmlParseFile(filename.c_str());
153 node = xmlDocGetRootElement(doc);
160 int ret =
this ->read (doc, node, cam_name, projModel, im_width, im_height);
184 const std::string& cam_name,
185 const unsigned int im_width,
186 const unsigned int im_height)
190 xmlNodePtr nodeCamera = NULL;
192 doc = xmlReadFile(filename.c_str(), NULL, XML_PARSE_NOWARNING + XML_PARSE_NOERROR
193 + XML_PARSE_NOBLANKS);
195 doc = xmlNewDoc ((xmlChar*)
"1.0");
196 node = xmlNewNode(NULL,(xmlChar*)LABEL_XML_ROOT);
197 xmlDocSetRootElement(doc,node);
198 xmlNodePtr node_tmp = xmlNewComment((xmlChar*)
199 "This file stores intrinsic camera parameters used\n"
200 " in the vpCameraParameters Class of ViSP available\n"
201 " at http://www.irisa.fr/lagadic/visp/visp.html .\n"
202 " It can be read with the parse method of\n"
203 " the vpXmlParserCamera class.");
204 xmlAddChild(node,node_tmp);
207 node = xmlDocGetRootElement(doc);
216 int nbCamera = count(doc, node, cam_name,cam.
get_projModel(),
217 im_width, im_height);
228 nodeCamera = find_camera(doc, node, cam_name, im_width, im_height);
229 if(nodeCamera == NULL){
230 write(node, cam_name, im_width, im_height);
233 write_camera(nodeCamera);
236 xmlSaveFormatFile(filename.c_str(), doc, 1);
263 vpXmlParserCamera::read (xmlDocPtr doc, xmlNodePtr node,
264 const std::string& cam_name,
266 const unsigned int im_width,
267 const unsigned int im_height,
268 const unsigned int subsampl_width,
269 const unsigned int subsampl_height)
275 unsigned int nbCamera = 0;
277 for (node = node->xmlChildrenNode; node != NULL; node = node->next)
279 if (node->type != XML_ELEMENT_NODE)
continue;
280 if (
SEQUENCE_OK != str2xmlcode ((
char*)(node ->name), prop))
300 if (
SEQUENCE_OK == this->read_camera (doc, node, cam_name, projModel,
301 im_width, im_height, subsampl_width, subsampl_height))
309 vpCERROR <<
"No camera parameters is available" << std::endl
310 <<
"with your specifications" << std::endl;
312 else if(nbCamera > 1){
314 vpCERROR << nbCamera <<
" sets of camera parameters are available" << std::endl
315 <<
"with your specifications : " << std::endl
316 <<
"precise your choice..." << std::endl;
341 vpXmlParserCamera::count (xmlDocPtr doc, xmlNodePtr node,
342 const std::string& cam_name,
344 const unsigned int im_width,
345 const unsigned int im_height,
346 const unsigned int subsampl_width,
347 const unsigned int subsampl_height)
353 for (node = node->xmlChildrenNode; node != NULL; node = node->next)
355 if (node->type != XML_ELEMENT_NODE)
continue;
356 if (
SEQUENCE_OK != str2xmlcode ((
char*)(node ->name), prop))
375 if (
SEQUENCE_OK == this->read_camera (doc, node, cam_name, projModel,
377 subsampl_width, subsampl_height))
404 vpXmlParserCamera::find_camera (xmlDocPtr doc, xmlNodePtr node,
405 const std::string& cam_name,
406 const unsigned int im_width,
407 const unsigned int im_height,
408 const unsigned int subsampl_width,
409 const unsigned int subsampl_height)
414 for (node = node->xmlChildrenNode; node != NULL; node = node->next)
416 if (node->type != XML_ELEMENT_NODE)
continue;
417 if (
SEQUENCE_OK != str2xmlcode ((
char*)(node ->name), prop))
436 if (
SEQUENCE_OK == this->read_camera_header(doc, node, cam_name,
438 subsampl_width, subsampl_height))
465 vpXmlParserCamera::read_camera (xmlDocPtr doc, xmlNodePtr node,
466 const std::string& cam_name,
468 const unsigned int im_width,
469 const unsigned int im_height,
470 const unsigned int subsampl_width,
471 const unsigned int subsampl_height)
475 std::string camera_name_tmp =
"";
476 unsigned int image_height_tmp = 0 ;
477 unsigned int image_width_tmp = 0 ;
478 unsigned int subsampling_width_tmp = 0;
479 unsigned int subsampling_height_tmp = 0;
484 bool projModelFound =
false;
487 for (node = node->xmlChildrenNode; node != NULL; node = node->next)
490 if (node->type != XML_ELEMENT_NODE)
continue;
491 if (
SEQUENCE_OK != str2xmlcode ((
char*)(node ->name), prop))
502 camera_name_tmp = val_char;
503 std::cout <<
"Found camera with name: \"" << camera_name_tmp <<
"\"" << std::endl;
529 back = read_camera_model(doc, node, cam_tmp_model);
531 cam_tmp = cam_tmp_model;
532 projModelFound =
true;
555 bool test_subsampling_width =
true;
556 bool test_subsampling_height =
true;
558 if (subsampling_width) {
559 test_subsampling_width = (abs((
int)subsampl_width - (
int)subsampling_width_tmp) < (allowedPixelDiffOnImageSize * (int)(subsampling_width_tmp / subsampling_width)));
561 if (subsampling_height) {
562 test_subsampling_height = (abs((
int)subsampl_height - (
int)subsampling_height_tmp) < (allowedPixelDiffOnImageSize * (int)(subsampling_height_tmp / subsampling_height)));
564 if( !((projModelFound ==
true) && (cam_name == camera_name_tmp) &&
565 (abs((
int)im_width - (int)image_width_tmp) < allowedPixelDiffOnImageSize || im_width == 0) &&
566 (abs((
int)im_height - (int)image_height_tmp) < allowedPixelDiffOnImageSize || im_height == 0) &&
567 (test_subsampling_width)&&
568 (test_subsampling_height))){
572 this->camera = cam_tmp;
573 this->camera_name = camera_name_tmp;
574 this->image_width = image_width_tmp;
575 this->image_height = image_height_tmp;
576 this->subsampling_width = subsampling_width_tmp;
577 this->subsampling_height = subsampling_height_tmp;
578 this->full_width = subsampling_width_tmp * image_width_tmp;
579 this->full_height = subsampling_height_tmp * image_height_tmp;
604 read_camera_header (xmlDocPtr doc, xmlNodePtr node,
605 const std::string& cam_name,
606 const unsigned int im_width,
607 const unsigned int im_height,
608 const unsigned int subsampl_width,
609 const unsigned int subsampl_height)
613 std::string camera_name_tmp =
"";
614 unsigned int image_height_tmp = 0 ;
615 unsigned int image_width_tmp = 0 ;
616 unsigned int subsampling_width_tmp = 0;
617 unsigned int subsampling_height_tmp = 0;
622 for (node = node->xmlChildrenNode; node != NULL; node = node->next)
625 if (node->type != XML_ELEMENT_NODE)
continue;
626 if (
SEQUENCE_OK != str2xmlcode ((
char*)(node ->name), prop))
637 camera_name_tmp = val_char;
682 if( !((cam_name == camera_name_tmp) &&
683 (im_width == image_width_tmp || im_width == 0) &&
684 (im_height == image_height_tmp || im_height == 0) &&
685 (subsampl_width == subsampling_width_tmp ||
686 subsampl_width == 0)&&
687 (subsampl_height == subsampling_height_tmp ||
688 subsampl_height == 0))){
705 vpXmlParserCamera::read_camera_model (xmlDocPtr doc, xmlNodePtr node,
713 char* model_type = NULL;
714 double u0 = cam_tmp.
get_u0();
715 double v0 = cam_tmp.
get_v0();
716 double px = cam_tmp.
get_px();
717 double py = cam_tmp.
get_py();
718 double kud = cam_tmp.
get_kud();
719 double kdu = cam_tmp.
get_kdu();
723 for (node = node->xmlChildrenNode; node != NULL; node = node->next)
726 if (node->type != XML_ELEMENT_NODE)
continue;
727 if (
SEQUENCE_OK != str2xmlcode ((
char*)(node ->name), prop))
736 if(model_type != NULL){
741 validation = validation | 0x01;
746 validation = validation | 0x02;
751 validation = validation | 0x04;
756 validation = validation | 0x08;
761 validation = validation | 0x10;
766 validation = validation | 0x20;
771 validation = validation | 0x40;
790 if(model_type == NULL) {
791 vpERROR_TRACE(
"projection model type doesn't match with any known model !");
795 if( !strcmp(model_type,LABEL_XML_MODEL_WITHOUT_DISTORTION)){
796 if (nb != 5 || validation != 0x1F)
798 vpCERROR <<
"ERROR in 'model' field:\n";
799 vpCERROR <<
"it must contain 5 parameters\n";
806 else if( !strcmp(model_type,LABEL_XML_MODEL_WITH_DISTORTION)){
807 if (nb != 7 || validation != 0x7F)
809 vpCERROR <<
"ERROR in 'model' field:\n";
810 vpCERROR <<
"it must contain 7 parameters\n";
818 vpERROR_TRACE(
"projection model type doesn't match with any known model !");
845 int vpXmlParserCamera::
846 write (xmlNodePtr node,
const std::string& cam_name,
847 const unsigned int im_width,
const unsigned int im_height,
848 const unsigned int subsampl_width,
849 const unsigned int subsampl_height)
854 xmlNodePtr node_camera;
857 node_camera = xmlNewNode(NULL,(xmlChar*)LABEL_XML_CAMERA);
858 xmlAddChild(node,node_camera);
862 if(!cam_name.empty()){
863 node_tmp = xmlNewComment((xmlChar*)
"Name of the camera");
864 xmlAddChild(node_camera,node_tmp);
865 xmlNewTextChild(node_camera,NULL,(xmlChar*)LABEL_XML_CAMERA_NAME,
866 (xmlChar*)cam_name.c_str());
869 if(im_width != 0 || im_height != 0){
872 node_tmp = xmlNewComment((xmlChar*)
"Size of the image on which camera calibration was performed");
873 xmlAddChild(node_camera,node_tmp);
875 sprintf(str,
"%u",im_width);
876 xmlNewTextChild(node_camera,NULL,(xmlChar*)LABEL_XML_WIDTH,(xmlChar*)str);
879 sprintf(str,
"%u",im_height);
880 xmlNewTextChild(node_camera,NULL,(xmlChar*)LABEL_XML_HEIGHT,(xmlChar*)str);
881 if(subsampling_width != 0 || subsampling_height != 0){
882 node_tmp = xmlNewComment((xmlChar*)
"Subsampling used to obtain the current size of the image.");
883 xmlAddChild(node_camera,node_tmp);
886 sprintf(str,
"%u",subsampl_width);
887 xmlNewTextChild(node_camera,NULL,(xmlChar*)LABEL_XML_SUBSAMPLING_WIDTH,
890 sprintf(str,
"%u",subsampl_height);
891 xmlNewTextChild(node_camera,NULL,(xmlChar*)LABEL_XML_SUBSAMPLING_HEIGHT,
893 node_tmp = xmlNewComment((xmlChar*)
"The full size is the sensor size actually used to grab the image. full_width = subsampling_width * image_width");
894 xmlAddChild(node_camera,node_tmp);
897 sprintf(str,
"%u",im_width*subsampl_width);
898 xmlNewTextChild(node_camera,NULL,(xmlChar*)LABEL_XML_FULL_WIDTH,
901 sprintf(str,
"%u",im_height*subsampl_height);
902 xmlNewTextChild(node_camera,NULL,(xmlChar*)LABEL_XML_FULL_HEIGHT,
907 node_tmp = xmlNewComment((xmlChar*)
"Intrinsic camera parameters computed for each projection model");
909 xmlAddChild(node_camera,node_tmp);
911 back = write_camera(node_camera);
922 int vpXmlParserCamera::
923 write_camera(xmlNodePtr node_camera){
924 xmlNodePtr node_model;
931 node_model = xmlNewNode(NULL,(xmlChar*)LABEL_XML_MODEL);
932 xmlAddChild(node_camera,node_model);
935 node_tmp = xmlNewComment((xmlChar*)
"Projection model type");
936 xmlAddChild(node_model,node_tmp);
939 xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_MODEL_TYPE,
940 (xmlChar*)LABEL_XML_MODEL_WITHOUT_DISTORTION);
942 node_tmp = xmlNewComment((xmlChar*)
"Pixel ratio");
943 xmlAddChild(node_model,node_tmp);
945 sprintf(str,
"%.10f",camera.
get_px());
946 xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_PX,(xmlChar*)str);
948 sprintf(str,
"%.10f",camera.
get_py());
949 xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_PY,(xmlChar*)str);
951 node_tmp = xmlNewComment((xmlChar*)
"Principal point");
952 xmlAddChild(node_model,node_tmp);
955 sprintf(str,
"%.10f",camera.
get_u0());
956 xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_U0,(xmlChar*)str);
958 sprintf(str,
"%.10f",camera.
get_v0());
959 xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_V0,(xmlChar*)str);
964 node_model = xmlNewNode(NULL,(xmlChar*)LABEL_XML_MODEL);
965 xmlAddChild(node_camera,node_model);
968 node_tmp = xmlNewComment((xmlChar*)
"Projection model type");
969 xmlAddChild(node_model,node_tmp);
971 xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_MODEL_TYPE,
972 (xmlChar*)LABEL_XML_MODEL_WITH_DISTORTION);
974 node_tmp = xmlNewComment((xmlChar*)
"Pixel ratio");
975 xmlAddChild(node_model,node_tmp);
977 sprintf(str,
"%.10f",camera.
get_px());
978 xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_PX,(xmlChar*)str);
980 sprintf(str,
"%.10f",camera.
get_py());
981 xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_PY,(xmlChar*)str);
983 node_tmp = xmlNewComment((xmlChar*)
"Principal point");
984 xmlAddChild(node_model,node_tmp);
986 sprintf(str,
"%.10f",camera.
get_u0());
987 xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_U0,(xmlChar*)str);
989 sprintf(str,
"%.10f",camera.
get_v0());
990 xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_V0,(xmlChar*)str);
993 node_tmp = xmlNewComment((xmlChar*)
"Undistorted to distorted distortion parameter");
994 xmlAddChild(node_model,node_tmp);
995 sprintf(str,
"%.10f",camera.
get_kud());
996 xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_KUD,(xmlChar*)str);
999 node_tmp = xmlNewComment((xmlChar*)
"Distorted to undistorted distortion parameter");
1000 xmlAddChild(node_model,node_tmp);
1001 sprintf(str,
"%.10f",camera.
get_kdu());
1002 xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_KDU,(xmlChar*)str);
1018 vpXmlParserCamera::str2xmlcode (
char * str, vpXmlCodeType & res)
1025 if (! strcmp (str, LABEL_XML_CAMERA))
1029 else if (! strcmp (str, LABEL_XML_CAMERA_NAME))
1033 else if (! strcmp (str, LABEL_XML_MODEL))
1037 else if (! strcmp (str, LABEL_XML_MODEL_TYPE))
1041 else if (! strcmp (str, LABEL_XML_WIDTH))
1045 else if (! strcmp (str, LABEL_XML_HEIGHT))
1049 else if (! strcmp (str, LABEL_XML_SUBSAMPLING_WIDTH))
1053 else if (! strcmp (str, LABEL_XML_SUBSAMPLING_HEIGHT))
1057 else if (! strcmp (str, LABEL_XML_FULL_WIDTH))
1061 else if (! strcmp (str, LABEL_XML_FULL_HEIGHT))
1065 else if (! strcmp (str, LABEL_XML_U0))
1069 else if (! strcmp (str, LABEL_XML_V0))
1073 else if (! strcmp (str, LABEL_XML_PX))
1077 else if (! strcmp (str, LABEL_XML_PY))
1081 else if (! strcmp (str, LABEL_XML_KUD))
1085 else if (! strcmp (str, LABEL_XML_KDU))
1097 #elif !defined(VISP_BUILD_SHARED_LIBS)
1099 void dummy_vpXmlParserCamera() {};
1100 #endif //VISP_HAVE_XML2
Perspective projection without distortion model.
vpXmlParserCamera & operator=(const vpXmlParserCamera &twinparser)
double xmlReadDoubleChild(xmlDocPtr doc, xmlNodePtr node)
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...
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)
vpCameraParametersProjType
Generic class defining intrinsic camera parameters.
Perspective projection with distortion model.
unsigned int xmlReadUnsignedIntChild(xmlDocPtr doc, xmlNodePtr node)
vpCameraParametersProjType get_projModel() 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)