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"
77 #define LABEL_XML_ADDITIONAL_INFO "additional_information"
83 camera(), camera_name(), image_width(0), image_height(0),
84 subsampling_width(0), subsampling_height(0), full_width(0), full_height(0)
93 camera(), camera_name(), image_width(0), image_height(0),
94 subsampling_width(0), subsampling_height(0), full_width(0), full_height(0)
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;
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;
141 const std::string& cam_name,
143 const unsigned int im_width,
144 const unsigned int im_height)
149 doc = xmlParseFile(filename.c_str());
155 node = xmlDocGetRootElement(doc);
162 int ret =
this ->read (doc, node, cam_name, projModel, im_width, im_height);
216 const std::string& cam_name,
217 const unsigned int im_width,
218 const unsigned int im_height,
219 const std::string &additionalInfo)
223 xmlNodePtr nodeCamera = NULL;
225 doc = xmlReadFile(filename.c_str(), NULL, XML_PARSE_NOWARNING + XML_PARSE_NOERROR
226 + XML_PARSE_NOBLANKS);
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);
240 node = xmlDocGetRootElement(doc);
249 int nbCamera = count(doc, node, cam_name,cam.
get_projModel(),
250 im_width, im_height);
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);
266 write_camera(nodeCamera);
269 if(!additionalInfo.empty()) {
271 nodeCamera = find_camera(doc, node, cam_name, im_width, im_height);
274 xmlNodePtr nodeAdditionalInfo = find_additional_info(nodeCamera);
276 if(nodeAdditionalInfo == NULL) {
278 xmlNodePtr node_comment = xmlNewComment((xmlChar*)
"Additional information");
279 xmlAddChild(nodeCamera,node_comment);
281 nodeAdditionalInfo = xmlNewNode(NULL, (xmlChar*) LABEL_XML_ADDITIONAL_INFO);
282 xmlAddChild(nodeCamera, nodeAdditionalInfo);
285 if(nodeAdditionalInfo != NULL) {
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;
295 xmlFreeNode(pNewNode);
300 xmlSaveFormatFile(filename.c_str(), doc, 1);
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)
339 unsigned int nbCamera = 0;
341 for (node = node->xmlChildrenNode; node != NULL; node = node->next)
343 if (node->type != XML_ELEMENT_NODE)
continue;
344 if (
SEQUENCE_OK != str2xmlcode ((
char*)(node ->name), prop))
364 if (
SEQUENCE_OK == this->read_camera (doc, node, cam_name, projModel,
365 im_width, im_height, subsampl_width, subsampl_height))
373 vpCERROR <<
"No camera parameters is available" << std::endl
374 <<
"with your specifications" << std::endl;
376 else if(nbCamera > 1){
378 vpCERROR << nbCamera <<
" sets of camera parameters are available" << std::endl
379 <<
"with your specifications : " << std::endl
380 <<
"precise your choice..." << std::endl;
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)
417 for (node = node->xmlChildrenNode; node != NULL; node = node->next)
419 if (node->type != XML_ELEMENT_NODE)
continue;
420 if (
SEQUENCE_OK != str2xmlcode ((
char*)(node ->name), prop))
439 if (
SEQUENCE_OK == this->read_camera (doc, node, cam_name, projModel,
441 subsampl_width, subsampl_height))
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)
479 for (node = node->xmlChildrenNode; node != NULL; node = node->next)
481 if (node->type != XML_ELEMENT_NODE)
continue;
482 if (
SEQUENCE_OK != str2xmlcode ((
char*)(node ->name), prop))
501 if (
SEQUENCE_OK == this->read_camera_header(doc, node, cam_name,
503 subsampl_width, subsampl_height))
520 vpXmlParserCamera::find_additional_info(xmlNodePtr node) {
523 for (node = node->xmlChildrenNode; node != NULL; node = node->next) {
524 if (node->type != XML_ELEMENT_NODE) {
528 if (
SEQUENCE_OK != str2xmlcode((
char*) (node->name), prop)) {
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)
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;
580 bool projModelFound =
false;
583 for (node = node->xmlChildrenNode; node != NULL; node = node->next)
586 if (node->type != XML_ELEMENT_NODE)
continue;
587 if (
SEQUENCE_OK != str2xmlcode ((
char*)(node ->name), prop))
598 camera_name_tmp = val_char;
599 std::cout <<
"Found camera with name: \"" << camera_name_tmp <<
"\"" << std::endl;
625 back = read_camera_model(doc, node, cam_tmp_model);
627 cam_tmp = cam_tmp_model;
628 projModelFound =
true;
654 bool test_subsampling_width =
true;
655 bool test_subsampling_height =
true;
657 if (subsampling_width) {
658 test_subsampling_width = (abs((
int)subsampl_width - (
int)subsampling_width_tmp) < (allowedPixelDiffOnImageSize * (int)(subsampling_width_tmp / subsampling_width)));
660 if (subsampling_height) {
661 test_subsampling_height = (abs((
int)subsampl_height - (
int)subsampling_height_tmp) < (allowedPixelDiffOnImageSize * (int)(subsampling_height_tmp / subsampling_height)));
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))){
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;
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)
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;
721 for (node = node->xmlChildrenNode; node != NULL; node = node->next)
724 if (node->type != XML_ELEMENT_NODE)
continue;
725 if (
SEQUENCE_OK != str2xmlcode ((
char*)(node ->name), prop))
736 camera_name_tmp = val_char;
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))){
807 vpXmlParserCamera::read_camera_model (xmlDocPtr doc, xmlNodePtr node,
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();
825 for (node = node->xmlChildrenNode; node != NULL; node = node->next)
828 if (node->type != XML_ELEMENT_NODE)
continue;
829 if (
SEQUENCE_OK != str2xmlcode ((
char*)(node ->name), prop))
838 if(model_type != NULL){
843 validation = validation | 0x01;
848 validation = validation | 0x02;
853 validation = validation | 0x04;
858 validation = validation | 0x08;
863 validation = validation | 0x10;
868 validation = validation | 0x20;
873 validation = validation | 0x40;
893 if(model_type == NULL) {
894 vpERROR_TRACE(
"projection model type doesn't match with any known model !");
898 if( !strcmp(model_type,LABEL_XML_MODEL_WITHOUT_DISTORTION)){
899 if (nb != 5 || validation != 0x1F)
901 vpCERROR <<
"ERROR in 'model' field:\n";
902 vpCERROR <<
"it must contain 5 parameters\n";
909 else if( !strcmp(model_type,LABEL_XML_MODEL_WITH_DISTORTION)){
910 if (nb != 7 || validation != 0x7F)
912 vpCERROR <<
"ERROR in 'model' field:\n";
913 vpCERROR <<
"it must contain 7 parameters\n";
921 vpERROR_TRACE(
"projection model type doesn't match with any known model !");
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)
957 xmlNodePtr node_camera;
960 node_camera = xmlNewNode(NULL,(xmlChar*)LABEL_XML_CAMERA);
961 xmlAddChild(node,node_camera);
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());
972 if(im_width != 0 || im_height != 0){
975 node_tmp = xmlNewComment((xmlChar*)
"Size of the image on which camera calibration was performed");
976 xmlAddChild(node_camera,node_tmp);
978 sprintf(str,
"%u",im_width);
979 xmlNewTextChild(node_camera,NULL,(xmlChar*)LABEL_XML_WIDTH,(xmlChar*)str);
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);
989 sprintf(str,
"%u",subsampl_width);
990 xmlNewTextChild(node_camera,NULL,(xmlChar*)LABEL_XML_SUBSAMPLING_WIDTH,
993 sprintf(str,
"%u",subsampl_height);
994 xmlNewTextChild(node_camera,NULL,(xmlChar*)LABEL_XML_SUBSAMPLING_HEIGHT,
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);
1000 sprintf(str,
"%u",im_width*subsampl_width);
1001 xmlNewTextChild(node_camera,NULL,(xmlChar*)LABEL_XML_FULL_WIDTH,
1004 sprintf(str,
"%u",im_height*subsampl_height);
1005 xmlNewTextChild(node_camera,NULL,(xmlChar*)LABEL_XML_FULL_HEIGHT,
1010 node_tmp = xmlNewComment((xmlChar*)
"Intrinsic camera parameters computed for each projection model");
1012 xmlAddChild(node_camera,node_tmp);
1014 back = write_camera(node_camera);
1025 int vpXmlParserCamera::
1026 write_camera(xmlNodePtr node_camera){
1027 xmlNodePtr node_model;
1028 xmlNodePtr node_tmp;
1034 node_model = xmlNewNode(NULL,(xmlChar*)LABEL_XML_MODEL);
1035 xmlAddChild(node_camera,node_model);
1038 node_tmp = xmlNewComment((xmlChar*)
"Projection model type");
1039 xmlAddChild(node_model,node_tmp);
1042 xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_MODEL_TYPE,
1043 (xmlChar*)LABEL_XML_MODEL_WITHOUT_DISTORTION);
1045 node_tmp = xmlNewComment((xmlChar*)
"Pixel ratio");
1046 xmlAddChild(node_model,node_tmp);
1048 sprintf(str,
"%.10f",camera.
get_px());
1049 xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_PX,(xmlChar*)str);
1051 sprintf(str,
"%.10f",camera.
get_py());
1052 xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_PY,(xmlChar*)str);
1054 node_tmp = xmlNewComment((xmlChar*)
"Principal point");
1055 xmlAddChild(node_model,node_tmp);
1058 sprintf(str,
"%.10f",camera.
get_u0());
1059 xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_U0,(xmlChar*)str);
1061 sprintf(str,
"%.10f",camera.
get_v0());
1062 xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_V0,(xmlChar*)str);
1067 node_model = xmlNewNode(NULL,(xmlChar*)LABEL_XML_MODEL);
1068 xmlAddChild(node_camera,node_model);
1071 node_tmp = xmlNewComment((xmlChar*)
"Projection model type");
1072 xmlAddChild(node_model,node_tmp);
1074 xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_MODEL_TYPE,
1075 (xmlChar*)LABEL_XML_MODEL_WITH_DISTORTION);
1077 node_tmp = xmlNewComment((xmlChar*)
"Pixel ratio");
1078 xmlAddChild(node_model,node_tmp);
1080 sprintf(str,
"%.10f",camera.
get_px());
1081 xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_PX,(xmlChar*)str);
1083 sprintf(str,
"%.10f",camera.
get_py());
1084 xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_PY,(xmlChar*)str);
1086 node_tmp = xmlNewComment((xmlChar*)
"Principal point");
1087 xmlAddChild(node_model,node_tmp);
1089 sprintf(str,
"%.10f",camera.
get_u0());
1090 xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_U0,(xmlChar*)str);
1092 sprintf(str,
"%.10f",camera.
get_v0());
1093 xmlNewTextChild(node_model,NULL,(xmlChar*)LABEL_XML_V0,(xmlChar*)str);
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);
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);
1121 vpXmlParserCamera::str2xmlcode (
char * str, vpXmlCodeType & res)
1128 if (! strcmp (str, LABEL_XML_CAMERA))
1132 else if (! strcmp (str, LABEL_XML_CAMERA_NAME))
1136 else if (! strcmp (str, LABEL_XML_MODEL))
1140 else if (! strcmp (str, LABEL_XML_MODEL_TYPE))
1144 else if (! strcmp (str, LABEL_XML_WIDTH))
1148 else if (! strcmp (str, LABEL_XML_HEIGHT))
1152 else if (! strcmp (str, LABEL_XML_SUBSAMPLING_WIDTH))
1156 else if (! strcmp (str, LABEL_XML_SUBSAMPLING_HEIGHT))
1160 else if (! strcmp (str, LABEL_XML_FULL_WIDTH))
1164 else if (! strcmp (str, LABEL_XML_FULL_HEIGHT))
1168 else if (! strcmp (str, LABEL_XML_U0))
1172 else if (! strcmp (str, LABEL_XML_V0))
1176 else if (! strcmp (str, LABEL_XML_PX))
1180 else if (! strcmp (str, LABEL_XML_PY))
1184 else if (! strcmp (str, LABEL_XML_KUD))
1188 else if (! strcmp (str, LABEL_XML_KDU))
1192 else if (! strcmp (str, LABEL_XML_ADDITIONAL_INFO))
1204 #elif !defined(VISP_BUILD_SHARED_LIBS)
1206 void dummy_vpXmlParserCamera() {};
1207 #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...
vpCameraParametersProjType
Generic class defining intrinsic camera parameters.
Perspective projection with distortion model.
unsigned int xmlReadUnsignedIntChild(xmlDocPtr doc, xmlNodePtr node)
vpCameraParametersProjType get_projModel() 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)