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
vpCameraParametersProjType get_projModel() const
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.
unsigned int xmlReadUnsignedIntChild(xmlDocPtr doc, xmlNodePtr node)
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)