ebec850323f270062bb875e7f948fc376f2c6175
[platform/upstream/opencv.git] / apps / interactive-calibration / parametersController.cpp
1 // This file is part of OpenCV project.
2 // It is subject to the license terms in the LICENSE file found in the top-level directory
3 // of this distribution and at http://opencv.org/license.html.
4
5 #include "parametersController.hpp"
6
7 #include <iostream>
8
9 template <typename T>
10 static bool readFromNode(cv::FileNode node, T& value)
11 {
12     if(!node.isNone()) {
13         node >> value;
14         return true;
15     }
16     else
17         return false;
18 }
19
20 static bool checkAssertion(bool value, const std::string& msg)
21 {
22     if(!value)
23         std::cerr << "Error: " << msg << std::endl;
24
25     return value;
26 }
27
28 bool calib::parametersController::loadFromFile(const std::string &inputFileName)
29 {
30     cv::FileStorage reader;
31     reader.open(inputFileName, cv::FileStorage::READ);
32
33     if(!reader.isOpened()) {
34         std::cerr << "Warning: Unable to open " << inputFileName <<
35                      " Application started with default advanced parameters" << std::endl;
36         return true;
37     }
38
39     readFromNode(reader["charuco_dict"], mCapParams.charucoDictName);
40     if (readFromNode(reader["charuco_square_lenght"], mCapParams.charucoSquareLength)) {
41         std::cout << "DEPRECATION: Parameter 'charuco_square_lenght' has been deprecated (typo). Use 'charuco_square_length' instead." << std::endl;
42     }
43     readFromNode(reader["charuco_square_length"], mCapParams.charucoSquareLength);
44     readFromNode(reader["charuco_marker_size"], mCapParams.charucoMarkerSize);
45     readFromNode(reader["camera_resolution"], mCapParams.cameraResolution);
46     readFromNode(reader["calibration_step"], mCapParams.calibrationStep);
47     readFromNode(reader["max_frames_num"], mCapParams.maxFramesNum);
48     readFromNode(reader["min_frames_num"], mCapParams.minFramesNum);
49     readFromNode(reader["solver_eps"], mInternalParameters.solverEps);
50     readFromNode(reader["solver_max_iters"], mInternalParameters.solverMaxIters);
51     readFromNode(reader["fast_solver"], mInternalParameters.fastSolving);
52     readFromNode(reader["frame_filter_conv_param"], mInternalParameters.filterAlpha);
53
54     bool retValue =
55             checkAssertion(mCapParams.charucoDictName >= 0, "Dict name must be >= 0") &&
56             checkAssertion(mCapParams.charucoMarkerSize > 0, "Marker size must be positive") &&
57             checkAssertion(mCapParams.charucoSquareLength > 0, "Square size must be positive") &&
58             checkAssertion(mCapParams.minFramesNum > 1, "Minimal number of frames for calibration < 1") &&
59             checkAssertion(mCapParams.calibrationStep > 0, "Calibration step must be positive") &&
60             checkAssertion(mCapParams.maxFramesNum > mCapParams.minFramesNum, "maxFramesNum < minFramesNum") &&
61             checkAssertion(mInternalParameters.solverEps > 0, "Solver precision must be positive") &&
62             checkAssertion(mInternalParameters.solverMaxIters > 0, "Max solver iterations number must be positive") &&
63             checkAssertion(mInternalParameters.filterAlpha >=0 && mInternalParameters.filterAlpha <=1 ,
64                            "Frame filter convolution parameter must be in [0,1] interval") &&
65             checkAssertion(mCapParams.cameraResolution.width > 0 && mCapParams.cameraResolution.height > 0,
66                            "Wrong camera resolution values");
67
68     reader.release();
69     return retValue;
70 }
71
72 calib::parametersController::parametersController()
73 {
74 }
75
76 calib::captureParameters calib::parametersController::getCaptureParameters() const
77 {
78     return mCapParams;
79 }
80
81 calib::internalParameters calib::parametersController::getInternalParameters() const
82 {
83     return mInternalParameters;
84 }
85
86 bool calib::parametersController::loadFromParser(cv::CommandLineParser &parser)
87 {
88     mCapParams.flipVertical = parser.get<bool>("flip");
89     mCapParams.captureDelay = parser.get<float>("d");
90     mCapParams.squareSize = parser.get<float>("sz");
91     mCapParams.templDst = parser.get<float>("dst");
92     mCapParams.saveFrames = parser.get<bool>("save_frames");
93     mCapParams.zoom = parser.get<float>("zoom");
94     mCapParams.forceReopen = parser.get<bool>("force_reopen");
95
96     if(!checkAssertion(mCapParams.squareSize > 0, "Distance between corners or circles must be positive"))
97         return false;
98     if(!checkAssertion(mCapParams.templDst > 0, "Distance between parts of dual template must be positive"))
99         return false;
100
101     if (parser.has("v")) {
102         mCapParams.source = File;
103         mCapParams.videoFileName = parser.get<std::string>("v");
104     }
105     else {
106         mCapParams.source = Camera;
107         mCapParams.camID = parser.get<int>("ci");
108     }
109
110     std::string templateType = parser.get<std::string>("t");
111
112     if(templateType.find("symcircles", 0) == 0) {
113         mCapParams.board = CirclesGrid;
114         mCapParams.boardSize = cv::Size(4, 11);
115     }
116     else if(templateType.find("circles", 0) == 0) {
117         mCapParams.board = AcirclesGrid;
118         mCapParams.boardSize = cv::Size(4, 11);
119     }
120     else if(templateType.find("chessboard", 0) == 0) {
121         mCapParams.board = Chessboard;
122         mCapParams.boardSize = cv::Size(7, 7);
123     }
124     else if(templateType.find("dualcircles", 0) == 0) {
125         mCapParams.board = DoubleAcirclesGrid;
126         mCapParams.boardSize = cv::Size(4, 11);
127     }
128     else if(templateType.find("charuco", 0) == 0) {
129         mCapParams.board = chAruco;
130         mCapParams.boardSize = cv::Size(6, 8);
131         mCapParams.charucoDictName = 0;
132         mCapParams.charucoSquareLength = 200;
133         mCapParams.charucoMarkerSize = 100;
134     }
135     else {
136         std::cerr << "Wrong template name\n";
137         return false;
138     }
139
140     if(parser.has("w") && parser.has("h")) {
141         mCapParams.boardSize = cv::Size(parser.get<int>("w"), parser.get<int>("h"));
142         if(!checkAssertion(mCapParams.boardSize.width > 0 || mCapParams.boardSize.height > 0,
143                            "Board size must be positive"))
144             return false;
145     }
146
147     if(!checkAssertion(parser.get<std::string>("of").find(".xml") > 0,
148                        "Wrong output file name: correct format is [name].xml"))
149         return false;
150
151     loadFromFile(parser.get<std::string>("pf"));
152     return true;
153 }