40#include <visp3/core/vpXmlParserCamera.h>
42#if defined(VISP_HAVE_PUGIXML)
52#define LABEL_XML_ROOT "root"
53#define LABEL_XML_CAMERA "camera"
54#define LABEL_XML_CAMERA_NAME "name"
55#define LABEL_XML_WIDTH "image_width"
56#define LABEL_XML_HEIGHT "image_height"
57#define LABEL_XML_SUBSAMPLING_WIDTH "subsampling_width"
58#define LABEL_XML_SUBSAMPLING_HEIGHT "subsampling_height"
59#define LABEL_XML_FULL_WIDTH "full_width"
60#define LABEL_XML_FULL_HEIGHT "full_height"
61#define LABEL_XML_MODEL "model"
62#define LABEL_XML_MODEL_TYPE "type"
63#define LABEL_XML_U0 "u0"
64#define LABEL_XML_V0 "v0"
65#define LABEL_XML_PX "px"
66#define LABEL_XML_PY "py"
67#define LABEL_XML_KUD "kud"
68#define LABEL_XML_KDU "kdu"
69#define LABEL_XML_K1 "k1"
70#define LABEL_XML_K2 "k2"
71#define LABEL_XML_K3 "k3"
72#define LABEL_XML_K4 "k4"
73#define LABEL_XML_K5 "k5"
75#define LABEL_XML_MODEL_WITHOUT_DISTORTION "perspectiveProjWithoutDistortion"
76#define LABEL_XML_MODEL_WITH_DISTORTION "perspectiveProjWithDistortion"
77#define LABEL_XML_MODEL_WITH_KANNALA_BRANDT_DISTORTION "ProjWithKannalaBrandtDistortion"
79#define LABEL_XML_ADDITIONAL_INFO "additional_information"
82#ifndef DOXYGEN_SHOULD_SKIP_THIS
83class vpXmlParserCamera::Impl
95 CODE_XML_SUBSAMPLING_WIDTH,
96 CODE_XML_SUBSAMPLING_HEIGHT,
112 CODE_XML_ADDITIONAL_INFO
116 : camera(),
camera_name(), image_width(0), image_height(0), subsampling_width(0), subsampling_height(0),
117 full_width(0), full_height(0)
120 int parse(vpCameraParameters &cam,
const std::string &filename,
const std::string &cam_name,
122 unsigned int im_height,
bool verbose)
124 pugi::xml_document doc;
125 if (!doc.load_file(
filename.c_str())) {
126 return SEQUENCE_ERROR;
129 pugi::xml_node node = doc.document_element();
131 return SEQUENCE_ERROR;
134 int ret = read(node, cam_name, projModel, im_width, im_height, verbose);
158 int read(
const pugi::xml_node &node_,
const std::string &cam_name,
160 unsigned int im_height,
bool verbose,
unsigned int subsampl_width = 0,
unsigned int subsampl_height = 0)
163 vpXmlCodeSequenceType back = SEQUENCE_OK;
164 unsigned int nbCamera = 0;
166 for (pugi::xml_node node = node_.first_child(); node; node = node.next_sibling()) {
167 if (node.type() == pugi::node_element) {
168 if (SEQUENCE_OK != str2xmlcode(node.name(), prop)) {
169 prop = CODE_XML_OTHER;
170 back = SEQUENCE_ERROR;
172 if (prop == CODE_XML_CAMERA) {
173 if (SEQUENCE_OK == read_camera(node, cam_name, projModel, im_width, im_height, subsampl_width, subsampl_height, verbose)) {
178 back = SEQUENCE_ERROR;
184 back = SEQUENCE_ERROR;
185 std::cout <<
"Warning: No camera parameters is available" << std::endl <<
"with your specifications" << std::endl;
187 else if (nbCamera > 1) {
188 back = SEQUENCE_ERROR;
189 std::cout <<
"Warning: " << nbCamera <<
" sets of camera parameters are available" << std::endl
190 <<
"with your specifications : " << std::endl
191 <<
"precise your choice..." << std::endl;
214 int read_camera(
const pugi::xml_node &node_,
const std::string &cam_name,
216 unsigned int im_height,
unsigned int subsampl_width,
unsigned int subsampl_height,
bool verbose)
220 std::string camera_name_tmp =
"";
221 unsigned int image_height_tmp = 0;
222 unsigned int image_width_tmp = 0;
223 unsigned int subsampling_width_tmp = 0;
224 unsigned int subsampling_height_tmp = 0;
225 vpCameraParameters cam_tmp;
226 vpCameraParameters cam_tmp_model;
227 bool same_proj_model =
false;
228 vpXmlCodeSequenceType back = SEQUENCE_OK;
230 for (pugi::xml_node node = node_.first_child(); node; node = node.next_sibling()) {
231 if (node.type() == pugi::node_element) {
232 if (SEQUENCE_OK != str2xmlcode(node.name(), prop)) {
233 prop = CODE_XML_OTHER;
234 back = SEQUENCE_ERROR;
238 case CODE_XML_CAMERA_NAME: {
239 camera_name_tmp = node.text().as_string();
241 std::cout <<
"Found camera with name: \"" << camera_name_tmp <<
"\"" << std::endl;
246 image_width_tmp = node.text().as_uint();
249 case CODE_XML_HEIGHT:
250 image_height_tmp = node.text().as_uint();
252 case CODE_XML_SUBSAMPLING_WIDTH:
253 subsampling_width_tmp = node.text().as_uint();
255 case CODE_XML_SUBSAMPLING_HEIGHT:
256 subsampling_height_tmp = node.text().as_uint();
260 back = read_camera_model(node, cam_tmp_model);
262 cam_tmp = cam_tmp_model;
263 same_proj_model =
true;
267 case CODE_XML_ADDITIONAL_INFO:
272 case CODE_XML_CAMERA:
273 case CODE_XML_FULL_HEIGHT:
274 case CODE_XML_FULL_WIDTH:
275 case CODE_XML_MODEL_TYPE:
288 back = SEQUENCE_ERROR;
295 bool test_subsampling_width =
true;
296 bool test_subsampling_height =
true;
298 if (subsampling_width) {
299 test_subsampling_width = (abs(
static_cast<int>(subsampl_width) -
static_cast<int>(subsampling_width_tmp)) <
300 (allowedPixelDiffOnImageSize *
static_cast<int>(subsampling_width_tmp / subsampling_width)));
302 if (subsampling_height) {
303 test_subsampling_height = (abs(
static_cast<int>(subsampl_height) -
static_cast<int>(subsampling_height_tmp)) <
304 (allowedPixelDiffOnImageSize *
static_cast<int>(subsampling_height_tmp / subsampling_height)));
308 bool same_name = (cam_name.empty() || (cam_name == camera_name_tmp));
309 bool imWidthOk = (abs(
static_cast<int>(im_width) -
static_cast<int>(image_width_tmp)) < allowedPixelDiffOnImageSize) || (im_width == 0);
310 bool imHeightOk = (abs(
static_cast<int>(im_height) -
static_cast<int>(image_height_tmp)) < allowedPixelDiffOnImageSize) || (im_height == 0);
311 bool imSizeOk = imWidthOk && imHeightOk;
312 bool same_img_size = imSizeOk && test_subsampling_width && test_subsampling_height;
313 if (same_name && same_img_size && same_proj_model) {
317 image_width = image_width_tmp;
318 image_height = image_height_tmp;
319 subsampling_width = subsampling_width_tmp;
320 subsampling_height = subsampling_height_tmp;
321 full_width = subsampling_width_tmp * image_width_tmp;
322 full_height = subsampling_height_tmp * image_height_tmp;
326 back = SEQUENCE_ERROR;
329 if (!((projModelFound ==
true) &&
330 (abs(
static_cast<int>(im_width) -
static_cast<int>(image_width_tmp)) < allowedPixelDiffOnImageSize || im_width == 0) &&
331 (abs(
static_cast<int>(im_height) -
static_cast<int>(image_height_tmp)) < allowedPixelDiffOnImageSize || im_height == 0) &&
332 (test_subsampling_width) && (test_subsampling_height))) {
334 if (!cam_name.empty() && (cam_name != camera_name_tmp)) {
335 back = SEQUENCE_ERROR;
344 image_width = image_width_tmp;
345 image_height = image_height_tmp;
346 subsampling_width = subsampling_width_tmp;
347 subsampling_height = subsampling_height_tmp;
348 full_width = subsampling_width_tmp * image_width_tmp;
349 full_height = subsampling_height_tmp * image_height_tmp;
350 back = SEQUENCE_ERROR;
362 vpXmlCodeSequenceType read_camera_model(
const pugi::xml_node &node_, vpCameraParameters &cam_tmp)
369 std::string model_type =
"";
370 double u0 = cam_tmp.
get_u0();
371 double v0 = cam_tmp.
get_v0();
372 double px = cam_tmp.
get_px();
373 double py = cam_tmp.
get_py();
374 double kud = cam_tmp.
get_kud();
375 double kdu = cam_tmp.
get_kdu();
376 std::vector<double> distortion_coeffs;
377 vpXmlCodeSequenceType back = SEQUENCE_OK;
378 unsigned int validation = 0;
380 for (pugi::xml_node node = node_.first_child(); node; node = node.next_sibling()) {
381 if (node.type() == pugi::node_element) {
382 if (SEQUENCE_OK != str2xmlcode(node.name(), prop)) {
383 prop = CODE_XML_OTHER;
384 back = SEQUENCE_ERROR;
388 case CODE_XML_MODEL_TYPE: {
389 model_type = node.text().as_string();
391 validation = validation | 0x01;
394 u0 = node.text().as_double();
396 validation = validation | 0x02;
399 v0 = node.text().as_double();
401 validation = validation | 0x04;
404 px = node.text().as_double();
406 validation = validation | 0x08;
409 py = node.text().as_double();
411 validation = validation | 0x10;
414 kud = node.text().as_double();
416 validation = validation | 0x20;
419 kdu = node.text().as_double();
421 validation = validation | 0x40;
424 distortion_coeffs.push_back(node.text().as_double());
426 validation = validation | 0x20;
429 distortion_coeffs.push_back(node.text().as_double());
431 validation = validation | 0x40;
434 distortion_coeffs.push_back(node.text().as_double());
436 validation = validation | 0x80;
439 distortion_coeffs.push_back(node.text().as_double());
441 validation = validation | 0x100;
444 distortion_coeffs.push_back(node.text().as_double());
446 validation = validation | 0x200;
450 case CODE_XML_CAMERA:
451 case CODE_XML_CAMERA_NAME:
452 case CODE_XML_HEIGHT:
454 case CODE_XML_SUBSAMPLING_WIDTH:
455 case CODE_XML_SUBSAMPLING_HEIGHT:
456 case CODE_XML_FULL_HEIGHT:
457 case CODE_XML_FULL_WIDTH:
459 case CODE_XML_ADDITIONAL_INFO:
461 back = SEQUENCE_ERROR;
467 if (model_type.empty()) {
468 std::cout <<
"Warning: projection model type doesn't match with any known model !" << std::endl;
469 return SEQUENCE_ERROR;
472 if (!strcmp(model_type.c_str(), LABEL_XML_MODEL_WITHOUT_DISTORTION)) {
473 if ((nb != 5) || (validation != 0x001F)) {
474 std::cout <<
"ERROR in 'model' field:\n";
475 std::cout <<
"it must contain 5 parameters\n";
477 return SEQUENCE_ERROR;
481 else if (!strcmp(model_type.c_str(), LABEL_XML_MODEL_WITH_DISTORTION)) {
482 if ((nb != 7) || (validation != 0x7F)) {
483 std::cout <<
"ERROR in 'model' field:\n";
484 std::cout <<
"it must contain 7 parameters\n";
486 return SEQUENCE_ERROR;
490 else if (!strcmp(model_type.c_str(), LABEL_XML_MODEL_WITH_KANNALA_BRANDT_DISTORTION)) {
491 if ((nb != 10) || (validation != 0x3FF)) {
492 std::cout <<
"ERROR in 'model' field:\n";
493 std::cout <<
"it must contain 10 parameters\n";
495 std::vector<double> fixed_distortion_coeffs;
501 const int dividerForBitCheck = 32;
502 int check = validation / dividerForBitCheck;
505 const int nbRemainingBits = 5;
506 const int moduloForOddity = 2;
507 const int dividerForRightShift = 2;
508 for (
size_t i = 0;
i < nbRemainingBits; ++
i) {
509 int bit = check % moduloForOddity;
511 fixed_distortion_coeffs.push_back(0.);
514 fixed_distortion_coeffs.push_back(distortion_coeffs[j++]);
516 check /= dividerForRightShift;
520 return SEQUENCE_ERROR;
525 std::cout <<
"Warning: projection model type doesn't match with any known model !" << std::endl;
527 return SEQUENCE_ERROR;
532 int save(
const vpCameraParameters &cam,
const std::string &filename,
const std::string &cam_name,
533 unsigned int im_width,
unsigned int im_height,
const std::string &additionalInfo,
bool verbose)
535 pugi::xml_document doc;
538 if (!doc.load_file(
filename.c_str(), pugi::parse_default | pugi::parse_comments)) {
539 node = doc.append_child(pugi::node_declaration);
540 node.append_attribute(
"version") =
"1.0";
541 node = doc.append_child(LABEL_XML_ROOT);
542 pugi::xml_node nodeComment = node.append_child(pugi::node_comment);
543 nodeComment.set_value(
"This file stores intrinsic camera parameters used\n"
544 " in the vpCameraParameters Class of ViSP available\n"
545 " at https://visp.inria.fr/download/ .\n"
546 " It can be read with the parse method of\n"
547 " the vpXmlParserCamera class.");
550 node = doc.document_element();
552 return SEQUENCE_ERROR;
557 int nbCamera = count(node, cam_name,
cam.get_projModel(), im_width, im_height, verbose);
559 return SEQUENCE_ERROR;
562 pugi::xml_node nodeCamera = find_camera(node, cam_name, im_width, im_height);
564 write(node, cam_name, im_width, im_height);
567 write_camera(nodeCamera);
570 if (!additionalInfo.empty()) {
572 nodeCamera = find_camera(node, cam_name, im_width, im_height);
575 pugi::xml_node nodeAdditionalInfo = find_additional_info(nodeCamera);
577 if (!nodeAdditionalInfo) {
579 pugi::xml_node node_comment = nodeCamera.append_child(pugi::node_comment);
580 node_comment.set_value(
"Additional information");
582 nodeAdditionalInfo = nodeCamera.append_child(LABEL_XML_ADDITIONAL_INFO);
585 if (nodeAdditionalInfo) {
587 pugi::xml_document tmpDoc;
588 if (tmpDoc.load_string(additionalInfo.c_str())) {
589 for (node = tmpDoc.first_child(); node; node = node.next_sibling()) {
590 nodeAdditionalInfo.append_copy(node);
596 doc.save_file(
filename.c_str(), PUGIXML_TEXT(
" "));
619 int count(
const pugi::xml_node &node_,
const std::string &cam_name,
621 unsigned int im_height,
bool verbose,
unsigned int subsampl_width = 0,
unsigned int subsampl_height = 0)
626 for (pugi::xml_node node = node_.first_child(); node; node = node.next_sibling()) {
627 if (node.type() == pugi::node_element) {
628 if (SEQUENCE_OK != str2xmlcode(node.name(), prop)) {
629 prop = CODE_XML_OTHER;
632 if (prop == CODE_XML_CAMERA) {
633 if (SEQUENCE_OK == read_camera(node, cam_name, projModel, im_width, im_height, subsampl_width, subsampl_height, verbose)) {
659 pugi::xml_node find_camera(
const pugi::xml_node &node_,
const std::string &cam_name,
unsigned int im_width,
660 unsigned int im_height,
unsigned int subsampl_width = 0,
unsigned int subsampl_height = 0)
663 pugi::xml_node resNode = pugi::xml_node();
665 pugi::xml_node node = node_.first_child();
666 bool hasNotFoundCam =
true;
667 while (node && hasNotFoundCam) {
668 if (node.type() == pugi::node_element) {
669 if (SEQUENCE_OK != str2xmlcode(node.name(), prop)) {
670 prop = CODE_XML_OTHER;
672 if (prop == CODE_XML_CAMERA) {
673 if (SEQUENCE_OK == read_camera_header(node, cam_name, im_width, im_height, subsampl_width, subsampl_height)) {
675 hasNotFoundCam =
false;
679 node = node.next_sibling();
699 int read_camera_header(
const pugi::xml_node &node_,
const std::string &cam_name,
unsigned int im_width,
700 unsigned int im_height,
unsigned int subsampl_width = 0,
unsigned int subsampl_height = 0)
704 std::string camera_name_tmp =
"";
705 unsigned int image_height_tmp = 0;
706 unsigned int image_width_tmp = 0;
707 unsigned int subsampling_width_tmp = 0;
708 unsigned int subsampling_height_tmp = 0;
709 vpXmlCodeSequenceType back = SEQUENCE_OK;
711 for (pugi::xml_node node = node_.first_child(); node; node = node.next_sibling()) {
712 if (node.type() == pugi::node_element) {
713 if (SEQUENCE_OK != str2xmlcode(node.name(), prop)) {
714 prop = CODE_XML_OTHER;
715 back = SEQUENCE_ERROR;
719 case CODE_XML_CAMERA_NAME:
720 camera_name_tmp = node.text().as_string();
724 image_width_tmp = node.text().as_uint();
727 case CODE_XML_HEIGHT:
728 image_height_tmp = node.text().as_uint();
731 case CODE_XML_SUBSAMPLING_WIDTH:
732 subsampling_width_tmp = node.text().as_uint();
735 case CODE_XML_SUBSAMPLING_HEIGHT:
736 subsampling_height_tmp = node.text().as_uint();
739 case CODE_XML_ADDITIONAL_INFO:
742 case CODE_XML_CAMERA:
743 case CODE_XML_FULL_HEIGHT:
744 case CODE_XML_FULL_WIDTH:
746 case CODE_XML_MODEL_TYPE:
759 back = SEQUENCE_ERROR;
764 bool imHeightOK = (im_height == image_height_tmp) || (im_height == 0);
765 bool imWidthOK = (im_width == image_width_tmp) || (im_width == 0);
766 bool imSizeEqual = imHeightOK && imWidthOK;
767 bool subsampleHeightOK = (subsampl_height == subsampling_height_tmp) || (subsampl_height == 0);
768 bool subsampleWidthOK = (subsampl_width == subsampling_width_tmp) || (subsampl_width == 0);
769 bool subsampleOK = subsampleHeightOK && subsampleWidthOK;
770 if (!((cam_name == camera_name_tmp) && imSizeEqual && subsampleOK)) {
771 back = SEQUENCE_ERROR;
791 int write(pugi::xml_node &node,
const std::string &cam_name,
unsigned int im_width,
unsigned int im_height,
792 unsigned int subsampl_width = 0,
unsigned int subsampl_height = 0)
794 int back = SEQUENCE_OK;
797 pugi::xml_node node_camera = node.append_child(LABEL_XML_CAMERA);
799 pugi::xml_node node_tmp;
802 if (!cam_name.empty()) {
803 node_tmp = node_camera.append_child(pugi::node_comment);
804 node_tmp.set_value(
"Name of the camera");
805 node_tmp = node_camera.append_child(LABEL_XML_CAMERA_NAME);
806 node_tmp.append_child(pugi::node_pcdata).set_value(cam_name.c_str());
809 if ((im_width != 0) || (im_height != 0)) {
810 node_tmp = node_camera.append_child(pugi::node_comment);
811 node_tmp.set_value(
"Size of the image on which camera "
812 "calibration was performed");
815 node_tmp = node_camera.append_child(LABEL_XML_WIDTH);
816 node_tmp.append_child(pugi::node_pcdata).text() = im_width;
819 node_tmp = node_camera.append_child(LABEL_XML_HEIGHT);
820 node_tmp.append_child(pugi::node_pcdata).text() = im_height;
821 if ((subsampling_width != 0) || (subsampling_height != 0)) {
822 node_tmp = node_camera.append_child(pugi::node_comment);
823 node_tmp.set_value(
"Subsampling used to obtain the "
824 "current size of the image.");
827 node_tmp = node_camera.append_child(LABEL_XML_SUBSAMPLING_WIDTH);
828 node_tmp.append_child(pugi::node_pcdata).text() = subsampl_width;
830 node_tmp = node_camera.append_child(LABEL_XML_SUBSAMPLING_HEIGHT);
831 node_tmp.append_child(pugi::node_pcdata).text() = subsampl_height;
832 node_tmp = node_camera.append_child(pugi::node_comment);
833 node_tmp.set_value(
"The full size is the sensor size actually used to "
834 "grab the image. full_width = subsampling_width * "
838 node_tmp = node_camera.append_child(LABEL_XML_FULL_WIDTH);
839 node_tmp.append_child(pugi::node_pcdata).text() = im_width * subsampl_width;
841 node_tmp = node_camera.append_child(LABEL_XML_FULL_HEIGHT);
842 node_tmp.append_child(pugi::node_pcdata).text() = im_height * subsampl_height;
846 node_tmp = node_camera.append_child(pugi::node_comment);
847 node_tmp.set_value(
"Intrinsic camera parameters "
848 "computed for each projection model");
850 back = write_camera(node_camera);
860 int write_camera(pugi::xml_node &node_camera)
862 pugi::xml_node node_model;
863 pugi::xml_node node_tmp;
865 int back = SEQUENCE_OK;
867 switch (camera.get_projModel()) {
869 writeCameraWithoutDistortion(node_camera);
873 writeCameraWithDistortion(node_camera);
877 writeCameraWithKannalaBrandt(node_camera);
880 throw(vpException(
vpException::fatalError,
"Unsupported camera projection model in vpXmlParserCamera::write_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();
924 vpXmlCodeSequenceType str2xmlcode(
const char *str, vpXmlCodeType &res)
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;
1003 std::string getCameraName()
const {
return camera_name; }
1004 vpCameraParameters getCameraParameters()
const {
return camera; }
1005 unsigned int getHeight()
const {
return image_height; }
1006 unsigned int getSubsampling_width()
const {
return subsampling_width; }
1007 unsigned int getSubsampling_height()
const {
return subsampling_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; }
1012 void setSubsampling_width(
unsigned int subsampling) { subsampling_width = subsampling; }
1013 void setSubsampling_height(
unsigned int subsampling) { subsampling_height = subsampling; }
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]);
1166 vpCameraParameters camera;
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)
1285void 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