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 | #include <opencv2/objdetect/aruco_dictionary.hpp> |
7 | |
8 | #include <iostream> |
9 | |
10 | template <typename T> |
11 | static bool readFromNode(cv::FileNode node, T& value) |
12 | { |
13 | if(!node.isNone()) { |
14 | node >> value; |
15 | return true; |
16 | } |
17 | else |
18 | return false; |
19 | } |
20 | |
21 | static bool checkAssertion(bool value, const std::string& msg) |
22 | { |
23 | if(!value) |
24 | std::cerr << "Error: " << msg << std::endl; |
25 | |
26 | return value; |
27 | } |
28 | |
29 | bool calib::parametersController::loadFromFile(const std::string &inputFileName) |
30 | { |
31 | cv::FileStorage reader; |
32 | reader.open(filename: inputFileName, flags: cv::FileStorage::READ); |
33 | |
34 | if(!reader.isOpened()) { |
35 | std::cerr << "Warning: Unable to open " << inputFileName << |
36 | " Application started with default advanced parameters" << std::endl; |
37 | return true; |
38 | } |
39 | |
40 | if (readFromNode(node: reader["charuco_square_lenght" ], value&: mCapParams.charucoSquareLength)) { |
41 | std::cout << "DEPRECATION: Parameter 'charuco_square_lenght' has been deprecated (typo). Use 'charuco_square_length' instead." << std::endl; |
42 | } |
43 | readFromNode(node: reader["charuco_square_length" ], value&: mCapParams.charucoSquareLength); |
44 | readFromNode(node: reader["charuco_marker_size" ], value&: mCapParams.charucoMarkerSize); |
45 | readFromNode(node: reader["camera_resolution" ], value&: mCapParams.cameraResolution); |
46 | readFromNode(node: reader["calibration_step" ], value&: mCapParams.calibrationStep); |
47 | readFromNode(node: reader["max_frames_num" ], value&: mCapParams.maxFramesNum); |
48 | readFromNode(node: reader["min_frames_num" ], value&: mCapParams.minFramesNum); |
49 | readFromNode(node: reader["solver_eps" ], value&: mInternalParameters.solverEps); |
50 | readFromNode(node: reader["solver_max_iters" ], value&: mInternalParameters.solverMaxIters); |
51 | readFromNode(node: reader["fast_solver" ], value&: mInternalParameters.fastSolving); |
52 | readFromNode(node: reader["frame_filter_conv_param" ], value&: mInternalParameters.filterAlpha); |
53 | |
54 | bool retValue = |
55 | checkAssertion(value: mCapParams.charucoMarkerSize > 0, msg: "Marker size must be positive" ) && |
56 | checkAssertion(value: mCapParams.charucoSquareLength > 0, msg: "Square size must be positive" ) && |
57 | checkAssertion(value: mCapParams.minFramesNum > 1, msg: "Minimal number of frames for calibration < 1" ) && |
58 | checkAssertion(value: mCapParams.calibrationStep > 0, msg: "Calibration step must be positive" ) && |
59 | checkAssertion(value: mCapParams.maxFramesNum > mCapParams.minFramesNum, msg: "maxFramesNum < minFramesNum" ) && |
60 | checkAssertion(value: mInternalParameters.solverEps > 0, msg: "Solver precision must be positive" ) && |
61 | checkAssertion(value: mInternalParameters.solverMaxIters > 0, msg: "Max solver iterations number must be positive" ) && |
62 | checkAssertion(value: mInternalParameters.filterAlpha >=0 && mInternalParameters.filterAlpha <=1 , |
63 | msg: "Frame filter convolution parameter must be in [0,1] interval" ) && |
64 | checkAssertion(value: mCapParams.cameraResolution.width > 0 && mCapParams.cameraResolution.height > 0, |
65 | msg: "Wrong camera resolution values" ); |
66 | |
67 | reader.release(); |
68 | return retValue; |
69 | } |
70 | |
71 | calib::parametersController::parametersController() |
72 | { |
73 | } |
74 | |
75 | calib::captureParameters calib::parametersController::getCaptureParameters() const |
76 | { |
77 | return mCapParams; |
78 | } |
79 | |
80 | calib::internalParameters calib::parametersController::getInternalParameters() const |
81 | { |
82 | return mInternalParameters; |
83 | } |
84 | |
85 | bool calib::parametersController::loadFromParser(cv::CommandLineParser &parser) |
86 | { |
87 | mCapParams.flipVertical = parser.get<bool>(name: "flip" ); |
88 | mCapParams.captureDelay = parser.get<float>(name: "d" ); |
89 | mCapParams.squareSize = parser.get<float>(name: "sz" ); |
90 | mCapParams.templDst = parser.get<float>(name: "dst" ); |
91 | mCapParams.saveFrames = parser.get<bool>(name: "save_frames" ); |
92 | mCapParams.zoom = parser.get<float>(name: "zoom" ); |
93 | mCapParams.forceReopen = parser.get<bool>(name: "force_reopen" ); |
94 | |
95 | if(!checkAssertion(value: mCapParams.squareSize > 0, msg: "Distance between corners or circles must be positive" )) |
96 | return false; |
97 | if(!checkAssertion(value: mCapParams.templDst > 0, msg: "Distance between parts of dual template must be positive" )) |
98 | return false; |
99 | |
100 | if (parser.has(name: "v" )) { |
101 | mCapParams.source = File; |
102 | mCapParams.videoFileName = parser.get<std::string>(name: "v" ); |
103 | } |
104 | else { |
105 | mCapParams.source = Camera; |
106 | mCapParams.camID = parser.get<int>(name: "ci" ); |
107 | } |
108 | |
109 | std::string templateType = parser.get<std::string>(name: "t" ); |
110 | |
111 | if(templateType.find(s: "symcircles" , pos: 0) == 0) { |
112 | mCapParams.board = CirclesGrid; |
113 | mCapParams.boardSizeUnits = cv::Size(4, 11); |
114 | } |
115 | else if(templateType.find(s: "circles" , pos: 0) == 0) { |
116 | mCapParams.board = AcirclesGrid; |
117 | mCapParams.boardSizeUnits = cv::Size(4, 11); |
118 | } |
119 | else if(templateType.find(s: "chessboard" , pos: 0) == 0) { |
120 | mCapParams.board = Chessboard; |
121 | mCapParams.boardSizeUnits = cv::Size(7, 7); |
122 | } |
123 | else if(templateType.find(s: "dualcircles" , pos: 0) == 0) { |
124 | mCapParams.board = DoubleAcirclesGrid; |
125 | mCapParams.boardSizeUnits = cv::Size(4, 11); |
126 | } |
127 | else if(templateType.find(s: "charuco" , pos: 0) == 0) { |
128 | mCapParams.board = ChArUco; |
129 | mCapParams.boardSizeUnits = cv::Size(5, 7); |
130 | mCapParams.charucoDictFile = parser.get<std::string>(name: "fad" ); |
131 | std::string arucoDictName = parser.get<std::string>(name: "ad" ); |
132 | |
133 | if (arucoDictName == "DICT_4X4_50" ) { mCapParams.charucoDictName = cv::aruco::DICT_4X4_50; } |
134 | else if (arucoDictName == "DICT_4X4_100" ) { mCapParams.charucoDictName = cv::aruco::DICT_4X4_100; } |
135 | else if (arucoDictName == "DICT_4X4_250" ) { mCapParams.charucoDictName = cv::aruco::DICT_4X4_250; } |
136 | else if (arucoDictName == "DICT_4X4_1000" ) { mCapParams.charucoDictName = cv::aruco::DICT_4X4_1000; } |
137 | else if (arucoDictName == "DICT_5X5_50" ) { mCapParams.charucoDictName = cv::aruco::DICT_5X5_50; } |
138 | else if (arucoDictName == "DICT_5X5_100" ) { mCapParams.charucoDictName = cv::aruco::DICT_5X5_100; } |
139 | else if (arucoDictName == "DICT_5X5_250" ) { mCapParams.charucoDictName = cv::aruco::DICT_5X5_250; } |
140 | else if (arucoDictName == "DICT_5X5_1000" ) { mCapParams.charucoDictName = cv::aruco::DICT_5X5_1000; } |
141 | else if (arucoDictName == "DICT_6X6_50" ) { mCapParams.charucoDictName = cv::aruco::DICT_6X6_50; } |
142 | else if (arucoDictName == "DICT_6X6_100" ) { mCapParams.charucoDictName = cv::aruco::DICT_6X6_100; } |
143 | else if (arucoDictName == "DICT_6X6_250" ) { mCapParams.charucoDictName = cv::aruco::DICT_6X6_250; } |
144 | else if (arucoDictName == "DICT_6X6_1000" ) { mCapParams.charucoDictName = cv::aruco::DICT_6X6_1000; } |
145 | else if (arucoDictName == "DICT_7X7_50" ) { mCapParams.charucoDictName = cv::aruco::DICT_7X7_50; } |
146 | else if (arucoDictName == "DICT_7X7_100" ) { mCapParams.charucoDictName = cv::aruco::DICT_7X7_100; } |
147 | else if (arucoDictName == "DICT_7X7_250" ) { mCapParams.charucoDictName = cv::aruco::DICT_7X7_250; } |
148 | else if (arucoDictName == "DICT_7X7_1000" ) { mCapParams.charucoDictName = cv::aruco::DICT_7X7_1000; } |
149 | else if (arucoDictName == "DICT_ARUCO_ORIGINAL" ) { mCapParams.charucoDictName = cv::aruco::DICT_ARUCO_ORIGINAL; } |
150 | else if (arucoDictName == "DICT_APRILTAG_16h5" ) { mCapParams.charucoDictName = cv::aruco::DICT_APRILTAG_16h5; } |
151 | else if (arucoDictName == "DICT_APRILTAG_25h9" ) { mCapParams.charucoDictName = cv::aruco::DICT_APRILTAG_25h9; } |
152 | else if (arucoDictName == "DICT_APRILTAG_36h10" ) { mCapParams.charucoDictName = cv::aruco::DICT_APRILTAG_36h10; } |
153 | else if (arucoDictName == "DICT_APRILTAG_36h11" ) { mCapParams.charucoDictName = cv::aruco::DICT_APRILTAG_36h11; } |
154 | else { |
155 | std::cout << "incorrect name of aruco dictionary \n" ; |
156 | return false; |
157 | } |
158 | mCapParams.charucoSquareLength = 200; |
159 | mCapParams.charucoMarkerSize = 100; |
160 | } |
161 | else { |
162 | std::cerr << "Wrong template name\n" ; |
163 | return false; |
164 | } |
165 | |
166 | if(parser.has(name: "w" ) && parser.has(name: "h" )) { |
167 | mCapParams.inputBoardSize = cv::Size(parser.get<int>(name: "w" ), parser.get<int>(name: "h" )); |
168 | //only for chessboard pattern board size given in inner corners |
169 | if (templateType != "chessboard" ) { |
170 | mCapParams.boardSizeUnits = mCapParams.inputBoardSize; |
171 | } |
172 | else { |
173 | mCapParams.boardSizeInnerCorners = mCapParams.inputBoardSize; |
174 | } |
175 | if(!checkAssertion(value: mCapParams.inputBoardSize.width > 0 || mCapParams.inputBoardSize.height > 0, |
176 | msg: "Board size must be positive" )) |
177 | return false; |
178 | } |
179 | |
180 | if(!checkAssertion(value: parser.get<std::string>(name: "of" ).find(s: ".xml" ) > 0, |
181 | msg: "Wrong output file name: correct format is [name].xml" )) |
182 | return false; |
183 | |
184 | loadFromFile(inputFileName: parser.get<std::string>(name: "pf" )); |
185 | return true; |
186 | } |
187 | |