45 #include <visp3/core/vpXmlParserCamera.h>
51 #include <visp3/core/vpDebug.h>
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"
77 #define LABEL_XML_MODEL_WITHOUT_DISTORTION "perspectiveProjWithoutDistortion"
78 #define LABEL_XML_MODEL_WITH_DISTORTION "perspectiveProjWithDistortion"
80 #define LABEL_XML_ADDITIONAL_INFO "additional_information"
85 :
vpXmlParser(), camera(), camera_name(), image_width(0), image_height(0), subsampling_width(0),
86 subsampling_height(0), full_width(0), full_height(0)
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)
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;
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;
140 const unsigned int im_width,
const unsigned int im_height)
145 doc = xmlParseFile(filename.c_str());
150 node = xmlDocGetRootElement(doc);
156 int ret = this->read(doc, node, cam_name, projModel, im_width, im_height);
209 const unsigned int im_width,
const unsigned int im_height,
210 const std::string &additionalInfo)
214 xmlNodePtr nodeCamera = NULL;
216 doc = xmlReadFile(filename.c_str(), NULL, XML_PARSE_NOWARNING + XML_PARSE_NOERROR + XML_PARSE_NOBLANKS);
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);
229 node = xmlDocGetRootElement(doc);
237 int nbCamera = count(doc, node, cam_name, cam.
get_projModel(), im_width, im_height);
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);
255 write_camera(nodeCamera);
258 if (!additionalInfo.empty()) {
260 nodeCamera = find_camera(doc, node, cam_name, im_width, im_height);
263 xmlNodePtr nodeAdditionalInfo = find_additional_info(nodeCamera);
265 if (nodeAdditionalInfo == NULL) {
267 xmlNodePtr node_comment = xmlNewComment((xmlChar *)
"Additional information");
268 xmlAddChild(nodeCamera, node_comment);
270 nodeAdditionalInfo = xmlNewNode(NULL, (xmlChar *)LABEL_XML_ADDITIONAL_INFO);
271 xmlAddChild(nodeCamera, nodeAdditionalInfo);
274 if (nodeAdditionalInfo != NULL) {
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;
284 xmlFreeNode(pNewNode);
289 xmlSaveFormatFile(filename.c_str(), doc, 1);
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)
322 unsigned int nbCamera = 0;
324 for (node = node->xmlChildrenNode; node != NULL; node = node->next) {
325 if (node->type != XML_ELEMENT_NODE)
327 if (
SEQUENCE_OK != str2xmlcode((
char *)(node->name), prop)) {
347 this->read_camera(doc, node, cam_name, projModel, im_width, im_height, subsampl_width, subsampl_height))
355 vpCERROR <<
"No camera parameters is available" << std::endl <<
"with your specifications" << std::endl;
356 }
else if (nbCamera > 1) {
358 vpCERROR << nbCamera <<
" sets of camera parameters are available" << std::endl
359 <<
"with your specifications : " << std::endl
360 <<
"precise your choice..." << std::endl;
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)
393 for (node = node->xmlChildrenNode; node != NULL; node = node->next) {
394 if (node->type != XML_ELEMENT_NODE)
396 if (
SEQUENCE_OK != str2xmlcode((
char *)(node->name), prop)) {
415 this->read_camera(doc, node, cam_name, projModel, im_width, im_height, subsampl_width, subsampl_height))
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)
449 for (node = node->xmlChildrenNode; node != NULL; node = node->next) {
450 if (node->type != XML_ELEMENT_NODE)
452 if (
SEQUENCE_OK != str2xmlcode((
char *)(node->name), prop)) {
471 this->read_camera_header(doc, node, cam_name, im_width, im_height, subsampl_width, subsampl_height))
487 xmlNodePtr vpXmlParserCamera::find_additional_info(xmlNodePtr node)
491 for (node = node->xmlChildrenNode; node != NULL; node = node->next) {
492 if (node->type != XML_ELEMENT_NODE) {
496 if (
SEQUENCE_OK != str2xmlcode((
char *)(node->name), prop)) {
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)
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;
544 bool projModelFound =
false;
547 for (node = node->xmlChildrenNode; node != NULL; node = node->next) {
549 if (node->type != XML_ELEMENT_NODE)
551 if (
SEQUENCE_OK != str2xmlcode((
char *)(node->name), prop)) {
559 camera_name_tmp = val_char;
560 std::cout <<
"Found camera with name: \"" << camera_name_tmp <<
"\"" << std::endl;
586 back = read_camera_model(doc, node, cam_tmp_model);
588 cam_tmp = cam_tmp_model;
589 projModelFound =
true;
615 bool test_subsampling_width =
true;
616 bool test_subsampling_height =
true;
618 if (subsampling_width) {
619 test_subsampling_width = (abs((
int)subsampl_width - (
int)subsampling_width_tmp) <
620 (allowedPixelDiffOnImageSize * (int)(subsampling_width_tmp / subsampling_width)));
622 if (subsampling_height) {
623 test_subsampling_height = (abs((
int)subsampl_height - (
int)subsampling_height_tmp) <
624 (allowedPixelDiffOnImageSize * (int)(subsampling_height_tmp / subsampling_height)));
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))) {
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;
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)
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;
677 for (node = node->xmlChildrenNode; node != NULL; node = node->next) {
679 if (node->type != XML_ELEMENT_NODE)
681 if (
SEQUENCE_OK != str2xmlcode((
char *)(node->name), prop)) {
689 camera_name_tmp = val_char;
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))) {
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();
774 for (node = node->xmlChildrenNode; node != NULL; node = node->next) {
776 if (node->type != XML_ELEMENT_NODE)
778 if (
SEQUENCE_OK != str2xmlcode((
char *)(node->name), prop)) {
785 if (model_type != NULL) {
790 validation = validation | 0x01;
795 validation = validation | 0x02;
800 validation = validation | 0x04;
805 validation = validation | 0x08;
810 validation = validation | 0x10;
815 validation = validation | 0x20;
820 validation = validation | 0x40;
840 if (model_type == NULL) {
841 vpERROR_TRACE(
"projection model type doesn't match with any known model !");
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";
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";
864 vpERROR_TRACE(
"projection model type doesn't match with any known model !");
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)
898 xmlNodePtr node_camera;
901 node_camera = xmlNewNode(NULL, (xmlChar *)LABEL_XML_CAMERA);
902 xmlAddChild(node, node_camera);
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());
912 if (im_width != 0 || im_height != 0) {
915 node_tmp = xmlNewComment((xmlChar *)
"Size of the image on which camera "
916 "calibration was performed");
917 xmlAddChild(node_camera, node_tmp);
919 sprintf(str,
"%u", im_width);
920 xmlNewTextChild(node_camera, NULL, (xmlChar *)LABEL_XML_WIDTH, (xmlChar *)str);
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);
931 sprintf(str,
"%u", subsampl_width);
932 xmlNewTextChild(node_camera, NULL, (xmlChar *)LABEL_XML_SUBSAMPLING_WIDTH, (xmlChar *)str);
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 * "
939 xmlAddChild(node_camera, node_tmp);
942 sprintf(str,
"%u", im_width * subsampl_width);
943 xmlNewTextChild(node_camera, NULL, (xmlChar *)LABEL_XML_FULL_WIDTH, (xmlChar *)str);
945 sprintf(str,
"%u", im_height * subsampl_height);
946 xmlNewTextChild(node_camera, NULL, (xmlChar *)LABEL_XML_FULL_HEIGHT, (xmlChar *)str);
950 node_tmp = xmlNewComment((xmlChar *)
"Intrinsic camera parameters "
951 "computed for each projection model");
953 xmlAddChild(node_camera, node_tmp);
955 back = write_camera(node_camera);
966 int vpXmlParserCamera::write_camera(xmlNodePtr node_camera)
968 xmlNodePtr node_model;
975 node_model = xmlNewNode(NULL, (xmlChar *)LABEL_XML_MODEL);
976 xmlAddChild(node_camera, node_model);
979 node_tmp = xmlNewComment((xmlChar *)
"Projection model type");
980 xmlAddChild(node_model, node_tmp);
983 xmlNewTextChild(node_model, NULL, (xmlChar *)LABEL_XML_MODEL_TYPE, (xmlChar *)LABEL_XML_MODEL_WITHOUT_DISTORTION);
985 node_tmp = xmlNewComment((xmlChar *)
"Pixel ratio");
986 xmlAddChild(node_model, node_tmp);
988 sprintf(str,
"%.10f", camera.
get_px());
989 xmlNewTextChild(node_model, NULL, (xmlChar *)LABEL_XML_PX, (xmlChar *)str);
991 sprintf(str,
"%.10f", camera.
get_py());
992 xmlNewTextChild(node_model, NULL, (xmlChar *)LABEL_XML_PY, (xmlChar *)str);
994 node_tmp = xmlNewComment((xmlChar *)
"Principal point");
995 xmlAddChild(node_model, node_tmp);
998 sprintf(str,
"%.10f", camera.
get_u0());
999 xmlNewTextChild(node_model, NULL, (xmlChar *)LABEL_XML_U0, (xmlChar *)str);
1001 sprintf(str,
"%.10f", camera.
get_v0());
1002 xmlNewTextChild(node_model, NULL, (xmlChar *)LABEL_XML_V0, (xmlChar *)str);
1007 node_model = xmlNewNode(NULL, (xmlChar *)LABEL_XML_MODEL);
1008 xmlAddChild(node_camera, node_model);
1011 node_tmp = xmlNewComment((xmlChar *)
"Projection model type");
1012 xmlAddChild(node_model, node_tmp);
1014 xmlNewTextChild(node_model, NULL, (xmlChar *)LABEL_XML_MODEL_TYPE, (xmlChar *)LABEL_XML_MODEL_WITH_DISTORTION);
1016 node_tmp = xmlNewComment((xmlChar *)
"Pixel ratio");
1017 xmlAddChild(node_model, node_tmp);
1019 sprintf(str,
"%.10f", camera.
get_px());
1020 xmlNewTextChild(node_model, NULL, (xmlChar *)LABEL_XML_PX, (xmlChar *)str);
1022 sprintf(str,
"%.10f", camera.
get_py());
1023 xmlNewTextChild(node_model, NULL, (xmlChar *)LABEL_XML_PY, (xmlChar *)str);
1025 node_tmp = xmlNewComment((xmlChar *)
"Principal point");
1026 xmlAddChild(node_model, node_tmp);
1028 sprintf(str,
"%.10f", camera.
get_u0());
1029 xmlNewTextChild(node_model, NULL, (xmlChar *)LABEL_XML_U0, (xmlChar *)str);
1031 sprintf(str,
"%.10f", camera.
get_v0());
1032 xmlNewTextChild(node_model, NULL, (xmlChar *)LABEL_XML_V0, (xmlChar *)str);
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);
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);
1066 if (!strcmp(str, LABEL_XML_CAMERA)) {
1068 }
else if (!strcmp(str, LABEL_XML_CAMERA_NAME)) {
1070 }
else if (!strcmp(str, LABEL_XML_MODEL)) {
1072 }
else if (!strcmp(str, LABEL_XML_MODEL_TYPE)) {
1074 }
else if (!strcmp(str, LABEL_XML_WIDTH)) {
1076 }
else if (!strcmp(str, LABEL_XML_HEIGHT)) {
1078 }
else if (!strcmp(str, LABEL_XML_SUBSAMPLING_WIDTH)) {
1080 }
else if (!strcmp(str, LABEL_XML_SUBSAMPLING_HEIGHT)) {
1082 }
else if (!strcmp(str, LABEL_XML_FULL_WIDTH)) {
1084 }
else if (!strcmp(str, LABEL_XML_FULL_HEIGHT)) {
1086 }
else if (!strcmp(str, LABEL_XML_U0)) {
1088 }
else if (!strcmp(str, LABEL_XML_V0)) {
1090 }
else if (!strcmp(str, LABEL_XML_PX)) {
1092 }
else if (!strcmp(str, LABEL_XML_PY)) {
1094 }
else if (!strcmp(str, LABEL_XML_KUD)) {
1096 }
else if (!strcmp(str, LABEL_XML_KDU)) {
1098 }
else if (!strcmp(str, LABEL_XML_ADDITIONAL_INFO)) {
1107 #elif !defined(VISP_BUILD_SHARED_LIBS)
1110 void dummy_vpXmlParserCamera(){};
1111 #endif // VISP_HAVE_XML2