41 #include <visp3/core/vpXmlParserCamera.h>
43 #if defined(VISP_HAVE_PUGIXML)
44 #include <pugixml.hpp>
53 #define LABEL_XML_ROOT "root"
54 #define LABEL_XML_CAMERA "camera"
55 #define LABEL_XML_CAMERA_NAME "name"
56 #define LABEL_XML_WIDTH "image_width"
57 #define LABEL_XML_HEIGHT "image_height"
58 #define LABEL_XML_SUBSAMPLING_WIDTH "subsampling_width"
59 #define LABEL_XML_SUBSAMPLING_HEIGHT "subsampling_height"
60 #define LABEL_XML_FULL_WIDTH "full_width"
61 #define LABEL_XML_FULL_HEIGHT "full_height"
62 #define LABEL_XML_MODEL "model"
63 #define LABEL_XML_MODEL_TYPE "type"
64 #define LABEL_XML_U0 "u0"
65 #define LABEL_XML_V0 "v0"
66 #define LABEL_XML_PX "px"
67 #define LABEL_XML_PY "py"
68 #define LABEL_XML_KUD "kud"
69 #define LABEL_XML_KDU "kdu"
70 #define LABEL_XML_K1 "k1"
71 #define LABEL_XML_K2 "k2"
72 #define LABEL_XML_K3 "k3"
73 #define LABEL_XML_K4 "k4"
74 #define LABEL_XML_K5 "k5"
76 #define LABEL_XML_MODEL_WITHOUT_DISTORTION "perspectiveProjWithoutDistortion"
77 #define LABEL_XML_MODEL_WITH_DISTORTION "perspectiveProjWithDistortion"
78 #define LABEL_XML_MODEL_WITH_KANNALA_BRANDT_DISTORTION "ProjWithKannalaBrandtDistortion"
80 #define LABEL_XML_ADDITIONAL_INFO "additional_information"
83 #ifndef DOXYGEN_SHOULD_SKIP_THIS
84 class vpXmlParserCamera::Impl
96 CODE_XML_SUBSAMPLING_WIDTH,
97 CODE_XML_SUBSAMPLING_HEIGHT,
113 CODE_XML_ADDITIONAL_INFO
117 : camera(), camera_name(), image_width(0), image_height(0), subsampling_width(0), subsampling_height(0),
118 full_width(0), full_height(0)
123 unsigned int im_height,
bool verbose)
125 pugi::xml_document doc;
126 if (!doc.load_file(filename.c_str())) {
130 pugi::xml_node node = doc.document_element();
135 int ret = read(node, cam_name, projModel, im_width, im_height, verbose);
159 int read(
const pugi::xml_node &node_,
const std::string &cam_name,
161 unsigned int im_height,
bool verbose,
unsigned int subsampl_width = 0,
unsigned int subsampl_height = 0)
165 unsigned int nbCamera = 0;
167 for (pugi::xml_node node = node_.first_child(); node; node = node.next_sibling()) {
168 if (node.type() == pugi::node_element) {
169 if (
SEQUENCE_OK != str2xmlcode(node.name(), prop)) {
170 prop = CODE_XML_OTHER;
173 if (prop == CODE_XML_CAMERA) {
174 if (
SEQUENCE_OK == read_camera(node, cam_name, projModel, im_width, im_height, subsampl_width, subsampl_height, verbose)) {
186 std::cout <<
"Warning: No camera parameters is available" << std::endl <<
"with your specifications" << std::endl;
188 else if (nbCamera > 1) {
190 std::cout <<
"Warning: " << nbCamera <<
" sets of camera parameters are available" << std::endl
191 <<
"with your specifications : " << std::endl
192 <<
"precise your choice..." << std::endl;
215 int read_camera(
const pugi::xml_node &node_,
const std::string &cam_name,
217 unsigned int im_height,
unsigned int subsampl_width,
unsigned int subsampl_height,
bool verbose)
221 std::string camera_name_tmp =
"";
222 unsigned int image_height_tmp = 0;
223 unsigned int image_width_tmp = 0;
224 unsigned int subsampling_width_tmp = 0;
225 unsigned int subsampling_height_tmp = 0;
228 bool same_proj_model =
false;
231 for (pugi::xml_node node = node_.first_child(); node; node = node.next_sibling()) {
232 if (node.type() == pugi::node_element) {
233 if (
SEQUENCE_OK != str2xmlcode(node.name(), prop)) {
234 prop = CODE_XML_OTHER;
239 case CODE_XML_CAMERA_NAME: {
240 camera_name_tmp = node.text().as_string();
242 std::cout <<
"Found camera with name: \"" << camera_name_tmp <<
"\"" << std::endl;
247 image_width_tmp = node.text().as_uint();
250 case CODE_XML_HEIGHT:
251 image_height_tmp = node.text().as_uint();
253 case CODE_XML_SUBSAMPLING_WIDTH:
254 subsampling_width_tmp = node.text().as_uint();
256 case CODE_XML_SUBSAMPLING_HEIGHT:
257 subsampling_height_tmp = node.text().as_uint();
261 back = read_camera_model(node, cam_tmp_model);
263 cam_tmp = cam_tmp_model;
264 same_proj_model =
true;
268 case CODE_XML_ADDITIONAL_INFO:
273 case CODE_XML_CAMERA:
274 case CODE_XML_FULL_HEIGHT:
275 case CODE_XML_FULL_WIDTH:
276 case CODE_XML_MODEL_TYPE:
297 bool test_subsampling_width =
true;
298 bool test_subsampling_height =
true;
300 if (subsampling_width) {
301 test_subsampling_width = (abs(
static_cast<int>(subsampl_width) -
static_cast<int>(subsampling_width_tmp)) <
302 (allowedPixelDiffOnImageSize *
static_cast<int>(subsampling_width_tmp / subsampling_width)));
304 if (subsampling_height) {
305 test_subsampling_height = (abs(
static_cast<int>(subsampl_height) -
static_cast<int>(subsampling_height_tmp)) <
306 (allowedPixelDiffOnImageSize *
static_cast<int>(subsampling_height_tmp / subsampling_height)));
310 bool same_name = (cam_name.empty() || (cam_name == camera_name_tmp));
311 bool imWidthOk = (abs(
static_cast<int>(im_width) -
static_cast<int>(image_width_tmp)) < allowedPixelDiffOnImageSize) || (im_width == 0);
312 bool imHeightOk = (abs(
static_cast<int>(im_height) -
static_cast<int>(image_height_tmp)) < allowedPixelDiffOnImageSize) || (im_height == 0);
313 bool imSizeOk = imWidthOk && imHeightOk;
314 bool same_img_size = imSizeOk && test_subsampling_width && test_subsampling_height;
315 if (same_name && same_img_size && same_proj_model) {
318 camera_name = camera_name_tmp;
319 image_width = image_width_tmp;
320 image_height = image_height_tmp;
321 subsampling_width = subsampling_width_tmp;
322 subsampling_height = subsampling_height_tmp;
323 full_width = subsampling_width_tmp * image_width_tmp;
324 full_height = subsampling_height_tmp * image_height_tmp;
331 if (!((projModelFound ==
true) &&
332 (abs(
static_cast<int>(im_width) -
static_cast<int>(image_width_tmp)) < allowedPixelDiffOnImageSize || im_width == 0) &&
333 (abs(
static_cast<int>(im_height) -
static_cast<int>(image_height_tmp)) < allowedPixelDiffOnImageSize || im_height == 0) &&
334 (test_subsampling_width) && (test_subsampling_height))) {
336 if (!cam_name.empty() && (cam_name != camera_name_tmp)) {
345 camera_name = camera_name_tmp;
346 image_width = image_width_tmp;
347 image_height = image_height_tmp;
348 subsampling_width = subsampling_width_tmp;
349 subsampling_height = subsampling_height_tmp;
350 full_width = subsampling_width_tmp * image_width_tmp;
351 full_height = subsampling_height_tmp * image_height_tmp;
371 std::string model_type =
"";
372 double u0 = cam_tmp.
get_u0();
373 double v0 = cam_tmp.
get_v0();
374 double px = cam_tmp.
get_px();
375 double py = cam_tmp.
get_py();
376 double kud = cam_tmp.
get_kud();
377 double kdu = cam_tmp.
get_kdu();
378 std::vector<double> distortion_coeffs;
380 unsigned int validation = 0;
382 for (pugi::xml_node node = node_.first_child(); node; node = node.next_sibling()) {
383 if (node.type() == pugi::node_element) {
384 if (
SEQUENCE_OK != str2xmlcode(node.name(), prop)) {
385 prop = CODE_XML_OTHER;
390 case CODE_XML_MODEL_TYPE: {
391 model_type = node.text().as_string();
393 validation = validation | 0x01;
396 u0 = node.text().as_double();
398 validation = validation | 0x02;
401 v0 = node.text().as_double();
403 validation = validation | 0x04;
406 px = node.text().as_double();
408 validation = validation | 0x08;
411 py = node.text().as_double();
413 validation = validation | 0x10;
416 kud = node.text().as_double();
418 validation = validation | 0x20;
421 kdu = node.text().as_double();
423 validation = validation | 0x40;
426 distortion_coeffs.push_back(node.text().as_double());
428 validation = validation | 0x20;
431 distortion_coeffs.push_back(node.text().as_double());
433 validation = validation | 0x40;
436 distortion_coeffs.push_back(node.text().as_double());
438 validation = validation | 0x80;
441 distortion_coeffs.push_back(node.text().as_double());
443 validation = validation | 0x100;
446 distortion_coeffs.push_back(node.text().as_double());
448 validation = validation | 0x200;
452 case CODE_XML_CAMERA:
453 case CODE_XML_CAMERA_NAME:
454 case CODE_XML_HEIGHT:
456 case CODE_XML_SUBSAMPLING_WIDTH:
457 case CODE_XML_SUBSAMPLING_HEIGHT:
458 case CODE_XML_FULL_HEIGHT:
459 case CODE_XML_FULL_WIDTH:
461 case CODE_XML_ADDITIONAL_INFO:
469 if (model_type.empty()) {
470 std::cout <<
"Warning: projection model type doesn't match with any known model !" << std::endl;
474 if (!strcmp(model_type.c_str(), LABEL_XML_MODEL_WITHOUT_DISTORTION)) {
475 if (nb != 5 || validation != 0x001F) {
476 std::cout <<
"ERROR in 'model' field:\n";
477 std::cout <<
"it must contain 5 parameters\n";
483 else if (!strcmp(model_type.c_str(), LABEL_XML_MODEL_WITH_DISTORTION)) {
484 if (nb != 7 || validation != 0x7F) {
485 std::cout <<
"ERROR in 'model' field:\n";
486 std::cout <<
"it must contain 7 parameters\n";
492 else if (!strcmp(model_type.c_str(), LABEL_XML_MODEL_WITH_KANNALA_BRANDT_DISTORTION)) {
493 if (nb != 10 || validation != 0x3FF) {
494 std::cout <<
"ERROR in 'model' field:\n";
495 std::cout <<
"it must contain 10 parameters\n";
497 std::vector<double> fixed_distortion_coeffs;
503 const int dividerForBitCheck = 32;
504 int check = validation / dividerForBitCheck;
507 const int nbRemainingBits = 5;
508 const int moduloForOddity = 2;
509 const int dividerForRightShift = 2;
510 for (
int i = 0; i < nbRemainingBits; ++i) {
511 int bit = check % moduloForOddity;
513 fixed_distortion_coeffs.push_back(0.);
516 fixed_distortion_coeffs.push_back(distortion_coeffs[j++]);
518 check /= dividerForRightShift;
527 std::cout <<
"Warning: projection model type doesn't match with any known model !" << std::endl;
535 unsigned int im_width,
unsigned int im_height,
const std::string &additionalInfo,
bool verbose)
537 pugi::xml_document doc;
540 if (!doc.load_file(filename.c_str(), pugi::parse_default | pugi::parse_comments)) {
541 node = doc.append_child(pugi::node_declaration);
542 node.append_attribute(
"version") =
"1.0";
543 node = doc.append_child(LABEL_XML_ROOT);
544 pugi::xml_node nodeComment = node.append_child(pugi::node_comment);
545 nodeComment.set_value(
"This file stores intrinsic camera parameters used\n"
546 " in the vpCameraParameters Class of ViSP available\n"
547 " at https://visp.inria.fr/download/ .\n"
548 " It can be read with the parse method of\n"
549 " the vpXmlParserCamera class.");
552 node = doc.document_element();
559 int nbCamera = count(node, cam_name, cam.
get_projModel(), im_width, im_height, verbose);
564 pugi::xml_node nodeCamera = find_camera(node, cam_name, im_width, im_height);
566 write(node, cam_name, im_width, im_height);
569 write_camera(nodeCamera);
572 if (!additionalInfo.empty()) {
574 nodeCamera = find_camera(node, cam_name, im_width, im_height);
577 pugi::xml_node nodeAdditionalInfo = find_additional_info(nodeCamera);
579 if (!nodeAdditionalInfo) {
581 pugi::xml_node node_comment = nodeCamera.append_child(pugi::node_comment);
582 node_comment.set_value(
"Additional information");
584 nodeAdditionalInfo = nodeCamera.append_child(LABEL_XML_ADDITIONAL_INFO);
587 if (nodeAdditionalInfo) {
589 pugi::xml_document tmpDoc;
590 if (tmpDoc.load_string(additionalInfo.c_str())) {
591 for (node = tmpDoc.first_child(); node; node = node.next_sibling()) {
592 nodeAdditionalInfo.append_copy(node);
598 doc.save_file(filename.c_str(), PUGIXML_TEXT(
" "));
621 int count(
const pugi::xml_node &node_,
const std::string &cam_name,
623 unsigned int im_height,
bool verbose,
unsigned int subsampl_width = 0,
unsigned int subsampl_height = 0)
628 for (pugi::xml_node node = node_.first_child(); node; node = node.next_sibling()) {
629 if (node.type() == pugi::node_element) {
630 if (
SEQUENCE_OK != str2xmlcode(node.name(), prop)) {
631 prop = CODE_XML_OTHER;
634 if (prop == CODE_XML_CAMERA) {
635 if (
SEQUENCE_OK == read_camera(node, cam_name, projModel, im_width, im_height, subsampl_width, subsampl_height, verbose)) {
661 pugi::xml_node find_camera(
const pugi::xml_node &node_,
const std::string &cam_name,
unsigned int im_width,
662 unsigned int im_height,
unsigned int subsampl_width = 0,
unsigned int subsampl_height = 0)
665 pugi::xml_node resNode = pugi::xml_node();
667 pugi::xml_node node = node_.first_child();
668 bool hasNotFoundCam =
true;
669 while (node && hasNotFoundCam) {
670 if (node.type() == pugi::node_element) {
671 if (
SEQUENCE_OK != str2xmlcode(node.name(), prop)) {
672 prop = CODE_XML_OTHER;
674 if (prop == CODE_XML_CAMERA) {
675 if (
SEQUENCE_OK == read_camera_header(node, cam_name, im_width, im_height, subsampl_width, subsampl_height)) {
677 hasNotFoundCam =
false;
681 node = node.next_sibling();
701 int read_camera_header(
const pugi::xml_node &node_,
const std::string &cam_name,
unsigned int im_width,
702 unsigned int im_height,
unsigned int subsampl_width = 0,
unsigned int subsampl_height = 0)
706 std::string camera_name_tmp =
"";
707 unsigned int image_height_tmp = 0;
708 unsigned int image_width_tmp = 0;
709 unsigned int subsampling_width_tmp = 0;
710 unsigned int subsampling_height_tmp = 0;
713 for (pugi::xml_node node = node_.first_child(); node; node = node.next_sibling()) {
714 if (node.type() == pugi::node_element) {
715 if (
SEQUENCE_OK != str2xmlcode(node.name(), prop)) {
716 prop = CODE_XML_OTHER;
721 case CODE_XML_CAMERA_NAME:
722 camera_name_tmp = node.text().as_string();
726 image_width_tmp = node.text().as_uint();
729 case CODE_XML_HEIGHT:
730 image_height_tmp = node.text().as_uint();
733 case CODE_XML_SUBSAMPLING_WIDTH:
734 subsampling_width_tmp = node.text().as_uint();
737 case CODE_XML_SUBSAMPLING_HEIGHT:
738 subsampling_height_tmp = node.text().as_uint();
744 case CODE_XML_ADDITIONAL_INFO:
749 case CODE_XML_CAMERA:
750 case CODE_XML_FULL_HEIGHT:
751 case CODE_XML_FULL_WIDTH:
752 case CODE_XML_MODEL_TYPE:
765 bool imHeightOK = (im_height == image_height_tmp) || (im_height == 0);
766 bool imWidthOK = (im_width == image_width_tmp) || (im_width == 0);
767 bool imSizeEqual = imHeightOK && imWidthOK;
768 bool subsampleHeightOK = (subsampl_height == subsampling_height_tmp) || (subsampl_height == 0);
769 bool subsampleWidthOK = (subsampl_width == subsampling_width_tmp) || (subsampl_width == 0);
770 bool subsampleOK = subsampleHeightOK && subsampleWidthOK;
771 if (!((cam_name == camera_name_tmp) && imSizeEqual && subsampleOK)) {
792 int write(pugi::xml_node &node,
const std::string &cam_name,
unsigned int im_width,
unsigned int im_height,
793 unsigned int subsampl_width = 0,
unsigned int subsampl_height = 0)
798 pugi::xml_node node_camera = node.append_child(LABEL_XML_CAMERA);
800 pugi::xml_node node_tmp;
803 if (!cam_name.empty()) {
804 node_tmp = node_camera.append_child(pugi::node_comment);
805 node_tmp.set_value(
"Name of the camera");
806 node_tmp = node_camera.append_child(LABEL_XML_CAMERA_NAME);
807 node_tmp.append_child(pugi::node_pcdata).set_value(cam_name.c_str());
810 if (im_width != 0 || im_height != 0) {
811 node_tmp = node_camera.append_child(pugi::node_comment);
812 node_tmp.set_value(
"Size of the image on which camera "
813 "calibration was performed");
816 node_tmp = node_camera.append_child(LABEL_XML_WIDTH);
817 node_tmp.append_child(pugi::node_pcdata).text() = im_width;
820 node_tmp = node_camera.append_child(LABEL_XML_HEIGHT);
821 node_tmp.append_child(pugi::node_pcdata).text() = im_height;
822 if (subsampling_width != 0 || subsampling_height != 0) {
823 node_tmp = node_camera.append_child(pugi::node_comment);
824 node_tmp.set_value(
"Subsampling used to obtain the "
825 "current size of the image.");
828 node_tmp = node_camera.append_child(LABEL_XML_SUBSAMPLING_WIDTH);
829 node_tmp.append_child(pugi::node_pcdata).text() = subsampl_width;
831 node_tmp = node_camera.append_child(LABEL_XML_SUBSAMPLING_HEIGHT);
832 node_tmp.append_child(pugi::node_pcdata).text() = subsampl_height;
833 node_tmp = node_camera.append_child(pugi::node_comment);
834 node_tmp.set_value(
"The full size is the sensor size actually used to "
835 "grab the image. full_width = subsampling_width * "
839 node_tmp = node_camera.append_child(LABEL_XML_FULL_WIDTH);
840 node_tmp.append_child(pugi::node_pcdata).text() = im_width * subsampl_width;
842 node_tmp = node_camera.append_child(LABEL_XML_FULL_HEIGHT);
843 node_tmp.append_child(pugi::node_pcdata).text() = im_height * subsampl_height;
847 node_tmp = node_camera.append_child(pugi::node_comment);
848 node_tmp.set_value(
"Intrinsic camera parameters "
849 "computed for each projection model");
851 back = write_camera(node_camera);
861 int write_camera(pugi::xml_node &node_camera)
863 pugi::xml_node node_model;
864 pugi::xml_node node_tmp;
868 switch (camera.get_projModel()) {
870 writeCameraWithoutDistortion(node_camera);
874 writeCameraWithDistortion(node_camera);
878 writeCameraWithKannalaBrandt(node_camera);
892 pugi::xml_node find_additional_info(
const pugi::xml_node &node_)
895 pugi::xml_node resNode = pugi::xml_node();
897 pugi::xml_node node = node_.first_child();
898 bool hasNotFoundInfo =
true;
899 while (node && hasNotFoundInfo) {
900 if (node.type() == pugi::node_element) {
901 if (
SEQUENCE_OK != str2xmlcode(node.name(), prop)) {
902 prop = CODE_XML_OTHER;
905 if (prop == CODE_XML_ADDITIONAL_INFO) {
908 hasNotFoundInfo =
false;
912 node = node.next_sibling();
926 vpXmlCodeType val_int = CODE_XML_BAD;
929 if (!strcmp(str, LABEL_XML_CAMERA)) {
930 val_int = CODE_XML_CAMERA;
932 else if (!strcmp(str, LABEL_XML_CAMERA_NAME)) {
933 val_int = CODE_XML_CAMERA_NAME;
935 else if (!strcmp(str, LABEL_XML_MODEL)) {
936 val_int = CODE_XML_MODEL;
938 else if (!strcmp(str, LABEL_XML_MODEL_TYPE)) {
939 val_int = CODE_XML_MODEL_TYPE;
941 else if (!strcmp(str, LABEL_XML_WIDTH)) {
942 val_int = CODE_XML_WIDTH;
944 else if (!strcmp(str, LABEL_XML_HEIGHT)) {
945 val_int = CODE_XML_HEIGHT;
947 else if (!strcmp(str, LABEL_XML_SUBSAMPLING_WIDTH)) {
948 val_int = CODE_XML_SUBSAMPLING_WIDTH;
950 else if (!strcmp(str, LABEL_XML_SUBSAMPLING_HEIGHT)) {
951 val_int = CODE_XML_SUBSAMPLING_HEIGHT;
953 else if (!strcmp(str, LABEL_XML_FULL_WIDTH)) {
954 val_int = CODE_XML_FULL_WIDTH;
956 else if (!strcmp(str, LABEL_XML_FULL_HEIGHT)) {
957 val_int = CODE_XML_FULL_HEIGHT;
959 else if (!strcmp(str, LABEL_XML_U0)) {
960 val_int = CODE_XML_U0;
962 else if (!strcmp(str, LABEL_XML_V0)) {
963 val_int = CODE_XML_V0;
965 else if (!strcmp(str, LABEL_XML_PX)) {
966 val_int = CODE_XML_PX;
968 else if (!strcmp(str, LABEL_XML_PY)) {
969 val_int = CODE_XML_PY;
971 else if (!strcmp(str, LABEL_XML_KUD)) {
972 val_int = CODE_XML_KUD;
974 else if (!strcmp(str, LABEL_XML_KDU)) {
975 val_int = CODE_XML_KDU;
977 else if (!strcmp(str, LABEL_XML_K1)) {
978 val_int = CODE_XML_K1;
980 else if (!strcmp(str, LABEL_XML_K2)) {
981 val_int = CODE_XML_K2;
983 else if (!strcmp(str, LABEL_XML_K3)) {
984 val_int = CODE_XML_K3;
986 else if (!strcmp(str, LABEL_XML_K4)) {
987 val_int = CODE_XML_K4;
989 else if (!strcmp(str, LABEL_XML_K5)) {
990 val_int = CODE_XML_K5;
992 else if (!strcmp(str, LABEL_XML_ADDITIONAL_INFO)) {
993 val_int = CODE_XML_ADDITIONAL_INFO;
996 val_int = CODE_XML_OTHER;
1005 unsigned int getHeight()
const {
return image_height; }
1008 unsigned int getWidth()
const {
return image_width; }
1010 void setCameraName(
const std::string &name) { camera_name = name; }
1011 void setHeight(
unsigned int height) { image_height = height; }
1014 void setWidth(
unsigned int width) { image_width = width; }
1021 void writeCameraWithoutDistortion(pugi::xml_node &node_camera)
1023 pugi::xml_node node_model;
1024 pugi::xml_node node_tmp;
1026 node_model = node_camera.append_child(LABEL_XML_MODEL);
1027 node_tmp = node_model.append_child(pugi::node_comment);
1028 node_tmp.set_value(
"Projection model type");
1031 node_tmp = node_model.append_child(LABEL_XML_MODEL_TYPE);
1032 node_tmp.append_child(pugi::node_pcdata).set_value(LABEL_XML_MODEL_WITHOUT_DISTORTION);
1034 node_tmp = node_model.append_child(pugi::node_comment);
1035 node_tmp.set_value(
"Pixel ratio");
1037 node_tmp = node_model.append_child(LABEL_XML_PX);
1038 node_tmp.append_child(pugi::node_pcdata).text() = camera.get_px();
1040 node_tmp = node_model.append_child(LABEL_XML_PY);
1041 node_tmp.append_child(pugi::node_pcdata).text() = camera.get_py();
1043 node_tmp = node_model.append_child(pugi::node_comment);
1044 node_tmp.set_value(
"Principal point");
1047 node_tmp = node_model.append_child(LABEL_XML_U0);
1048 node_tmp.append_child(pugi::node_pcdata).text() = camera.get_u0();
1050 node_tmp = node_model.append_child(LABEL_XML_V0);
1051 node_tmp.append_child(pugi::node_pcdata).text() = camera.get_v0();
1058 void writeCameraWithDistortion(pugi::xml_node &node_camera)
1060 pugi::xml_node node_model;
1061 pugi::xml_node node_tmp;
1063 node_model = node_camera.append_child(LABEL_XML_MODEL);
1064 node_tmp = node_model.append_child(pugi::node_comment);
1065 node_tmp.set_value(
"Projection model type");
1067 node_tmp = node_model.append_child(LABEL_XML_MODEL_TYPE);
1068 node_tmp.append_child(pugi::node_pcdata).set_value(LABEL_XML_MODEL_WITH_DISTORTION);
1070 node_tmp = node_model.append_child(pugi::node_comment);
1071 node_tmp.set_value(
"Pixel ratio");
1073 node_tmp = node_model.append_child(LABEL_XML_PX);
1074 node_tmp.append_child(pugi::node_pcdata).text() = camera.get_px();
1076 node_tmp = node_model.append_child(LABEL_XML_PY);
1077 node_tmp.append_child(pugi::node_pcdata).text() = camera.get_py();
1079 node_tmp = node_model.append_child(pugi::node_comment);
1080 node_tmp.set_value(
"Principal point");
1082 node_tmp = node_model.append_child(LABEL_XML_U0);
1083 node_tmp.append_child(pugi::node_pcdata).text() = camera.get_u0();
1085 node_tmp = node_model.append_child(LABEL_XML_V0);
1086 node_tmp.append_child(pugi::node_pcdata).text() = camera.get_v0();
1089 node_tmp = node_model.append_child(pugi::node_comment);
1090 node_tmp.set_value(
"Undistorted to distorted distortion parameter");
1091 node_tmp = node_model.append_child(LABEL_XML_KUD);
1092 node_tmp.append_child(pugi::node_pcdata).text() = camera.get_kud();
1095 node_tmp = node_model.append_child(pugi::node_comment);
1096 node_tmp.set_value(
"Distorted to undistorted distortion parameter");
1097 node_tmp = node_model.append_child(LABEL_XML_KDU);
1098 node_tmp.append_child(pugi::node_pcdata).text() = camera.get_kdu();
1105 void writeCameraWithKannalaBrandt(pugi::xml_node &node_camera)
1107 const unsigned int index_0 = 0;
1108 const unsigned int index_1 = 1;
1109 const unsigned int index_2 = 2;
1110 const unsigned int index_3 = 3;
1111 const unsigned int index_4 = 4;
1112 const unsigned int requiredNbCoeff = 5;
1113 pugi::xml_node node_model;
1114 pugi::xml_node node_tmp;
1116 node_model = node_camera.append_child(LABEL_XML_MODEL);
1117 node_tmp = node_model.append_child(pugi::node_comment);
1118 node_tmp.set_value(
"Projection model type");
1120 node_tmp = node_model.append_child(LABEL_XML_MODEL_TYPE);
1121 node_tmp.append_child(pugi::node_pcdata).set_value(LABEL_XML_MODEL_WITH_KANNALA_BRANDT_DISTORTION);
1123 node_tmp = node_model.append_child(pugi::node_comment);
1124 node_tmp.set_value(
"Pixel ratio");
1126 node_tmp = node_model.append_child(LABEL_XML_PX);
1127 node_tmp.append_child(pugi::node_pcdata).text() = camera.get_px();
1129 node_tmp = node_model.append_child(LABEL_XML_PY);
1130 node_tmp.append_child(pugi::node_pcdata).text() = camera.get_py();
1132 node_tmp = node_model.append_child(pugi::node_comment);
1133 node_tmp.set_value(
"Principal point");
1135 node_tmp = node_model.append_child(LABEL_XML_U0);
1136 node_tmp.append_child(pugi::node_pcdata).text() = camera.get_u0();
1138 node_tmp = node_model.append_child(LABEL_XML_V0);
1139 node_tmp.append_child(pugi::node_pcdata).text() = camera.get_v0();
1141 std::vector<double> distortion_coefs = camera.getKannalaBrandtDistortionCoefficients();
1143 if (distortion_coefs.size() != requiredNbCoeff) {
1144 std::cout <<
"Make sure to have 5 distortion coefficients for Kannala-Brandt distortions." << std::endl;
1147 node_tmp = node_model.append_child(pugi::node_comment);
1148 node_tmp.set_value(
"Distortion coefficients");
1149 node_tmp = node_model.append_child(LABEL_XML_K1);
1150 distortion_coefs.size() == index_0 ? (node_tmp.append_child(pugi::node_pcdata).text() = 0)
1151 : (node_tmp.append_child(pugi::node_pcdata).text() = distortion_coefs[index_0]);
1152 node_tmp = node_model.append_child(LABEL_XML_K2);
1153 distortion_coefs.size() <= index_1 ? (node_tmp.append_child(pugi::node_pcdata).text() = 0)
1154 : (node_tmp.append_child(pugi::node_pcdata).text() = distortion_coefs[index_1]);
1155 node_tmp = node_model.append_child(LABEL_XML_K3);
1156 distortion_coefs.size() <= index_2 ? (node_tmp.append_child(pugi::node_pcdata).text() = 0)
1157 : (node_tmp.append_child(pugi::node_pcdata).text() = distortion_coefs[index_2]);
1158 node_tmp = node_model.append_child(LABEL_XML_K4);
1159 distortion_coefs.size() <= index_3 ? (node_tmp.append_child(pugi::node_pcdata).text() = 0)
1160 : (node_tmp.append_child(pugi::node_pcdata).text() = distortion_coefs[index_3]);
1161 node_tmp = node_model.append_child(LABEL_XML_K5);
1162 distortion_coefs.size() <= index_4 ? (node_tmp.append_child(pugi::node_pcdata).text() = 0)
1163 : (node_tmp.append_child(pugi::node_pcdata).text() = distortion_coefs[index_4]);
1167 std::string camera_name;
1168 unsigned int image_width;
1169 unsigned int image_height;
1170 unsigned int subsampling_width;
1171 unsigned int subsampling_height;
1172 unsigned int full_width;
1173 unsigned int full_height;
1177 static const int allowedPixelDiffOnImageSize = 15;
1202 unsigned int im_height,
bool verbose)
1204 return m_impl->parse(cam, filename, cam_name, projModel, im_width, im_height, verbose);
1256 unsigned int im_width,
unsigned int im_height,
const std::string &additionalInfo,
bool verbose)
1258 return m_impl->save(cam, filename, cam_name, im_width, im_height, additionalInfo, verbose);
1283 #elif !defined(VISP_BUILD_SHARED_LIBS)
1285 void dummy_vpXmlParserCamera() { };
Generic class defining intrinsic camera parameters.
void initPersProjWithoutDistortion(double px, double py, double u0, double v0)
vpCameraParametersProjType
@ perspectiveProjWithDistortion
Perspective projection with distortion model.
@ ProjWithKannalaBrandtDistortion
Projection with Kannala-Brandt distortion model.
@ perspectiveProjWithoutDistortion
Perspective projection without distortion model.
void initPersProjWithDistortion(double px, double py, double u0, double v0, double kud, double kdu)
vpCameraParametersProjType get_projModel() const
void initProjWithKannalaBrandtDistortion(double px, double py, double u0, double v0, const std::vector< double > &distortion_coefficients)
void setSubsampling_width(unsigned int subsampling)
void setWidth(unsigned int width)
unsigned int getHeight() const
int save(const vpCameraParameters &cam, const std::string &filename, const std::string &camera_name, unsigned int image_width=0, unsigned int image_height=0, const std::string &additionalInfo="", bool verbose=true)
vpCameraParameters getCameraParameters() const
unsigned int getWidth() const
void setSubsampling_height(unsigned int subsampling)
void setCameraName(const std::string &name)
void setHeight(unsigned int height)
unsigned int getSubsampling_height() const
unsigned int getSubsampling_width() const
int parse(vpCameraParameters &cam, const std::string &filename, const std::string &camera_name, const vpCameraParameters::vpCameraParametersProjType &projModel, unsigned int image_width=0, unsigned int image_height=0, bool verbose=true)
std::string getCameraName() const