Visual Servoing Platform version 3.6.0
Loading...
Searching...
No Matches
vpXmlConfigParserKeyPoint.cpp
1/*
2 * ViSP, open source Visual Servoing Platform software.
3 * Copyright (C) 2005 - 2023 by Inria. All rights reserved.
4 *
5 * This software is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 * See the file LICENSE.txt at the root directory of this source
10 * distribution for additional information about the GNU GPL.
11 *
12 * For using ViSP with software that can not be combined with the GNU
13 * GPL, please contact Inria about acquiring a ViSP Professional
14 * Edition License.
15 *
16 * See https://visp.inria.fr for more information.
17 *
18 * This software was developed at:
19 * Inria Rennes - Bretagne Atlantique
20 * Campus Universitaire de Beaulieu
21 * 35042 Rennes Cedex
22 * France
23 *
24 * If you have questions regarding the use of this file, please contact
25 * Inria at visp@inria.fr
26 *
27 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29 *
30 * Description:
31 * XML parser to load configuration for vpKeyPoint class.
32 */
33
41#include <iostream>
42
43#include <visp3/vision/vpXmlConfigParserKeyPoint.h>
44
45#include <map>
46#include <pugixml.hpp>
47
48#include <visp3/core/vpException.h>
49
50#ifndef DOXYGEN_SHOULD_SKIP_THIS
51class vpXmlConfigParserKeyPoint::Impl
52{
53public:
54 Impl()
55 : m_detectorName("ORB"), m_extractorName("ORB"), m_matcherName("BruteForce-Hamming"),
56 m_matchingFactorThreshold(2.0), m_matchingMethod(ratioDistanceThreshold), m_matchingRatioThreshold(0.85),
57 m_nbRansacIterations(200), m_nbRansacMinInlierCount(100), m_ransacConsensusPercentage(20.0),
58 m_ransacReprojectionError(6.0), m_ransacThreshold(0.01), m_useRansacConsensusPercentage(false),
59 m_useRansacVVS(true)
60 {
61 init();
62 }
63
67 void init()
68 {
69 m_nodeMap["conf"] = conf;
70 m_nodeMap["detector"] = detector;
71 m_nodeMap["extractor"] = extractor;
72 m_nodeMap["matcher"] = matcher;
73 m_nodeMap["name"] = name;
74 m_nodeMap["matching_method"] = matching_method;
75 m_nodeMap["constantFactorDistanceThreshold"] = constant_factor_distance_threshold;
76 m_nodeMap["stdDistanceThreshold"] = std_distance_threshold;
77 m_nodeMap["ratioDistanceThreshold"] = ratio_distance_threshold;
78 m_nodeMap["stdAndRatioDistanceThreshold"] = std_and_ratio_distance_threshold;
79 m_nodeMap["noFilterMatching"] = no_filter_matching;
80 m_nodeMap["matchingFactorThreshold"] = matching_factor_threshold;
81 m_nodeMap["matchingRatioThreshold"] = matching_ratio_threshold;
82 m_nodeMap["ransac"] = ransac;
83 m_nodeMap["useRansacVVS"] = use_ransac_vvs;
84 m_nodeMap["useRansacConsensusPercentage"] = use_ransac_consensus_percentage;
85 m_nodeMap["nbRansacIterations"] = nb_ransac_iterations;
86 m_nodeMap["ransacReprojectionError"] = ransac_reprojection_error;
87 m_nodeMap["nbRansacMinInlierCount"] = nb_ransac_min_inlier_count;
88 m_nodeMap["ransacThreshold"] = ransac_threshold;
89 m_nodeMap["ransacConsensusPercentage"] = ransac_consensus_percentage;
90 }
91
92 void parse(const std::string &filename)
93 {
94 pugi::xml_document doc;
95 if (!doc.load_file(filename.c_str())) {
96 throw vpException(vpException::ioError, "Cannot open file: %s", filename.c_str());
97 }
98
99 bool detector_node = false;
100 bool extractor_node = false;
101 bool matcher_node = false;
102
103 pugi::xml_node root_node = doc.document_element();
104 for (pugi::xml_node dataNode = root_node.first_child(); dataNode; dataNode = dataNode.next_sibling()) {
105 if (dataNode.type() == pugi::node_element) {
106 std::map<std::string, int>::iterator iter_data = m_nodeMap.find(dataNode.name());
107 if (iter_data != m_nodeMap.end()) {
108 switch (iter_data->second) {
109 case detector:
110 read_detector(dataNode);
111 detector_node = true;
112 break;
113
114 case extractor:
115 read_extractor(dataNode);
116 extractor_node = true;
117 break;
118
119 case matcher:
120 read_matcher(dataNode);
121 matcher_node = true;
122 break;
123
124 case ransac:
125 read_ransac(dataNode);
126 break;
127
128 default:
129 break;
130 }
131 }
132 }
133 }
134
135 if (!detector_node) {
136 std::cout << "detector: name: " << m_detectorName << " (default)" << std::endl;
137 }
138
139 if (!extractor_node) {
140 std::cout << "extractor: name: " << m_extractorName << " (default)" << std::endl;
141 }
142
143 if (!matcher_node) {
144 std::cout << "matcher: name: " << m_matcherName << " (default)" << std::endl;
145 }
146 }
147
153 void read_detector(const pugi::xml_node &node)
154 {
155 bool detector_name_node = false;
156
157 for (pugi::xml_node dataNode = node.first_child(); dataNode; dataNode = dataNode.next_sibling()) {
158 if (dataNode.type() == pugi::node_element) {
159 std::map<std::string, int>::iterator iter_data = m_nodeMap.find(dataNode.name());
160 if (iter_data != m_nodeMap.end()) {
161 switch (iter_data->second) {
162 case name:
163 m_detectorName = dataNode.text().as_string();
164 detector_name_node = true;
165 break;
166
167 default:
168 break;
169 }
170 }
171 }
172 }
173
174 if (!detector_name_node)
175 std::cout << "detector : Name : " << m_detectorName << " (default)" << std::endl;
176 else
177 std::cout << "detector : Name : " << m_detectorName << std::endl;
178 }
179
185 void read_extractor(const pugi::xml_node &node)
186 {
187 bool extractor_name_node = false;
188
189 for (pugi::xml_node dataNode = node.first_child(); dataNode; dataNode = dataNode.next_sibling()) {
190 if (dataNode.type() == pugi::node_element) {
191 std::map<std::string, int>::iterator iter_data = m_nodeMap.find(dataNode.name());
192 if (iter_data != m_nodeMap.end()) {
193 switch (iter_data->second) {
194 case name:
195 m_extractorName = dataNode.text().as_string();
196 extractor_name_node = true;
197 break;
198
199 default:
200 break;
201 }
202 }
203 }
204 }
205
206 if (!extractor_name_node)
207 std::cout << "extractor : Name : " << m_extractorName << " (default)" << std::endl;
208 else
209 std::cout << "extractor : Name : " << m_extractorName << std::endl;
210 }
211
217 void read_matcher(const pugi::xml_node &node)
218 {
219 bool matcher_name_node = false;
220 bool matching_method_node = false;
221 std::string matchingMethodName = "ratioDistanceThreshold";
222 bool matching_factor_threshold_node = false;
223 bool matching_ratio_threshold_node = false;
224
225 for (pugi::xml_node dataNode = node.first_child(); dataNode; dataNode = dataNode.next_sibling()) {
226 if (dataNode.type() == pugi::node_element) {
227 std::map<std::string, int>::iterator iter_data = m_nodeMap.find(dataNode.name());
228 if (iter_data != m_nodeMap.end()) {
229 switch (iter_data->second) {
230 case name:
231 m_matcherName = dataNode.text().as_string();
232 matcher_name_node = true;
233 break;
234
235 case matching_method: {
236 matchingMethodName = dataNode.text().as_string();
237
238 std::map<std::string, int>::iterator iter_data2 = m_nodeMap.find(matchingMethodName);
239 if (iter_data2 != m_nodeMap.end()) {
240 matching_method_node = true;
241 switch (iter_data2->second) {
242 case constant_factor_distance_threshold:
243 m_matchingMethod = constantFactorDistanceThreshold;
244 break;
245
246 case std_distance_threshold:
247 m_matchingMethod = stdDistanceThreshold;
248 break;
249
250 case ratio_distance_threshold:
251 m_matchingMethod = ratioDistanceThreshold;
252 break;
253
254 case std_and_ratio_distance_threshold:
255 m_matchingMethod = stdAndRatioDistanceThreshold;
256 break;
257
258 case no_filter_matching:
259 m_matchingMethod = noFilterMatching;
260 break;
261
262 default:
263 matching_method_node = false;
264 break;
265 }
266 }
267 break;
268 }
269
270 case matching_factor_threshold:
271 m_matchingFactorThreshold = dataNode.text().as_double();
272 matching_factor_threshold_node = true;
273 break;
274
275 case matching_ratio_threshold:
276 m_matchingRatioThreshold = dataNode.text().as_double();
277 matching_ratio_threshold_node = true;
278 break;
279
280 default:
281 break;
282 }
283 }
284 }
285 }
286
287 if (!matcher_name_node)
288 std::cout << "matcher : Name : " << m_matcherName << " (default)" << std::endl;
289 else
290 std::cout << "matcher : Name : " << m_matcherName << std::endl;
291
292 if (!matching_method_node)
293 std::cout << "matcher : Filter method : " << matchingMethodName << " (default)" << std::endl;
294 else
295 std::cout << "matcher : Filter method : " << matchingMethodName << std::endl;
296
297 if (!matching_factor_threshold_node)
298 std::cout << "matcher : matching factor threshold : " << m_matchingFactorThreshold << " (default)" << std::endl;
299 else
300 std::cout << "matcher : matching factor threshold : " << m_matchingFactorThreshold << std::endl;
301
302 if (!matching_ratio_threshold_node)
303 std::cout << "matcher : matching ratio threshold : " << m_matchingRatioThreshold << " (default)" << std::endl;
304 else
305 std::cout << "matcher : matching ratio threshold : " << m_matchingRatioThreshold << std::endl;
306 }
307
313 void read_ransac(const pugi::xml_node &node)
314 {
315 bool use_ransac_vvs_node = false;
316 bool use_ransac_consensus_percentage_node = false;
317 bool nb_ransac_iterations_node = false;
318 bool ransac_reprojection_error_node = false;
319 bool nb_ransac_min_inlier_count_node = false;
320 bool ransac_threshold_node = false;
321 bool ransac_consensus_percentage_node = false;
322
323 for (pugi::xml_node dataNode = node.first_child(); dataNode; dataNode = dataNode.next_sibling()) {
324 if (dataNode.type() == pugi::node_element) {
325 std::map<std::string, int>::iterator iter_data = m_nodeMap.find(dataNode.name());
326 if (iter_data != m_nodeMap.end()) {
327 switch (iter_data->second) {
328 case use_ransac_vvs:
329 m_useRansacVVS = dataNode.text().as_int() != 0;
330 use_ransac_vvs_node = true;
331 break;
332
333 case use_ransac_consensus_percentage:
334 m_useRansacConsensusPercentage = dataNode.text().as_int() != 0;
335 use_ransac_consensus_percentage_node = true;
336 break;
337
338 case nb_ransac_iterations:
339 m_nbRansacIterations = dataNode.text().as_int();
340 nb_ransac_iterations_node = true;
341 break;
342
343 case ransac_reprojection_error:
344 m_ransacReprojectionError = dataNode.text().as_double();
345 ransac_reprojection_error_node = true;
346 break;
347
348 case nb_ransac_min_inlier_count:
349 m_nbRansacMinInlierCount = dataNode.text().as_int();
350 nb_ransac_min_inlier_count_node = true;
351 break;
352
353 case ransac_threshold:
354 m_ransacThreshold = dataNode.text().as_double();
355 ransac_threshold_node = true;
356 break;
357
358 case ransac_consensus_percentage:
359 m_ransacConsensusPercentage = dataNode.text().as_double();
360 ransac_consensus_percentage_node = true;
361 break;
362
363 default:
364 break;
365 }
366 }
367 }
368 }
369
370 if (!use_ransac_vvs_node)
371 std::cout << "ransac: use ransac vvs pose estimation: " << m_useRansacVVS << " (default)" << std::endl;
372 else
373 std::cout << "ransac: use ransac vvs pose estimation: " << m_useRansacVVS << std::endl;
374
375 if (!use_ransac_consensus_percentage_node)
376 std::cout << "ransac: use consensus percentage: " << m_useRansacConsensusPercentage << " (default)" << std::endl;
377 else
378 std::cout << "ransac: use consensus percentage: " << m_useRansacConsensusPercentage << std::endl;
379
380 if (!nb_ransac_iterations_node)
381 std::cout << "ransac: nb ransac iterations: " << m_nbRansacIterations << " (default)" << std::endl;
382 else
383 std::cout << "ransac: nb ransac iterations: " << m_nbRansacIterations << std::endl;
384
385 if (!ransac_reprojection_error_node)
386 std::cout << "ransac: ransac reprojection error in pixel (for OpenCV "
387 "function): "
388 << m_ransacReprojectionError << " (default)" << std::endl;
389 else
390 std::cout << "ransac: ransac reprojection error in pixel (for OpenCV "
391 "function): "
392 << m_ransacReprojectionError << std::endl;
393
394 if (!nb_ransac_min_inlier_count_node)
395 std::cout << "ransac: nb ransac min inlier count: " << m_nbRansacMinInlierCount << " (default)" << std::endl;
396 else
397 std::cout << "ransac: nb ransac min inlier count: " << m_nbRansacMinInlierCount << std::endl;
398
399 if (!ransac_threshold_node)
400 std::cout << "ransac: ransac threshold in meter (for ViSP function): " << m_ransacThreshold << " (default)"
401 << std::endl;
402 else
403 std::cout << "ransac: ransac threshold in meter (for ViSP function): " << m_ransacThreshold << std::endl;
404
405 if (!ransac_consensus_percentage_node)
406 std::cout << "ransac: consensus percentage: " << m_ransacConsensusPercentage << " (default)" << std::endl;
407 else
408 std::cout << "ransac: consensus percentage: " << m_ransacConsensusPercentage << std::endl;
409 }
410
411 std::string getDetectorName() const { return m_detectorName; }
412 std::string getExtractorName() const { return m_extractorName; }
413 std::string getMatcherName() const { return m_matcherName; }
414
415 double getMatchingFactorThreshold() const { return m_matchingFactorThreshold; }
416 vpMatchingMethodEnum getMatchingMethod() const { return m_matchingMethod; }
417 double getMatchingRatioThreshold() const { return m_matchingRatioThreshold; }
418
419 int getNbRansacIterations() const { return m_nbRansacIterations; }
420 int getNbRansacMinInlierCount() const { return m_nbRansacMinInlierCount; }
421 double getRansacConsensusPercentage() const { return m_ransacConsensusPercentage; }
422 double getRansacReprojectionError() const { return m_ransacReprojectionError; }
423 double getRansacThreshold() const { return m_ransacThreshold; }
424 bool getUseRansacConsensusPercentage() const { return m_useRansacConsensusPercentage; }
425 bool getUseRansacVVSPoseEstimation() const { return m_useRansacVVS; }
426
427protected:
429 enum vpNodeIdentifier {
430 conf,
431 detector,
432 extractor,
433 matcher,
434 name,
435 matching_method,
436 constant_factor_distance_threshold,
439 std_distance_threshold,
441 ratio_distance_threshold,
443 std_and_ratio_distance_threshold,
446 no_filter_matching,
448 matching_factor_threshold,
450 matching_ratio_threshold,
452 ransac,
453 use_ransac_vvs,
454 use_ransac_consensus_percentage,
457 nb_ransac_iterations,
459 ransac_reprojection_error,
461 nb_ransac_min_inlier_count,
463 ransac_threshold,
465 ransac_consensus_percentage
467 };
468
470 std::string m_detectorName;
472 std::string m_extractorName;
474 std::string m_matcherName;
476 double m_matchingFactorThreshold;
478 vpMatchingMethodEnum m_matchingMethod;
480 double m_matchingRatioThreshold;
482 int m_nbRansacIterations;
484 int m_nbRansacMinInlierCount;
486 double m_ransacConsensusPercentage;
489 double m_ransacReprojectionError;
492 double m_ransacThreshold;
495 // it is based on a fixed number.
496 bool m_useRansacConsensusPercentage;
499 bool m_useRansacVVS;
500 std::map<std::string, int> m_nodeMap;
501};
502#endif // DOXYGEN_SHOULD_SKIP_THIS
503
505
507
512void vpXmlConfigParserKeyPoint::parse(const std::string &filename) { m_impl->parse(filename); }
513
519std::string vpXmlConfigParserKeyPoint::getDetectorName() const { return m_impl->getDetectorName(); }
520
526std::string vpXmlConfigParserKeyPoint::getExtractorName() const { return m_impl->getExtractorName(); }
527
533std::string vpXmlConfigParserKeyPoint::getMatcherName() const { return m_impl->getMatcherName(); }
534
541double vpXmlConfigParserKeyPoint::getMatchingFactorThreshold() const { return m_impl->getMatchingFactorThreshold(); }
542
552
558double vpXmlConfigParserKeyPoint::getMatchingRatioThreshold() const { return m_impl->getMatchingRatioThreshold(); }
559
565int vpXmlConfigParserKeyPoint::getNbRansacIterations() const { return m_impl->getNbRansacIterations(); }
566
572int vpXmlConfigParserKeyPoint::getNbRansacMinInlierCount() const { return m_impl->getNbRansacMinInlierCount(); }
573
580{
581 return m_impl->getRansacConsensusPercentage();
582}
583
590double vpXmlConfigParserKeyPoint::getRansacReprojectionError() const { return m_impl->getRansacReprojectionError(); }
591
597double vpXmlConfigParserKeyPoint::getRansacThreshold() const { return m_impl->getRansacThreshold(); }
598
606{
607 return m_impl->getUseRansacConsensusPercentage();
608}
609
617{
618 return m_impl->getUseRansacVVSPoseEstimation();
619}
error that can be emitted by ViSP classes.
Definition vpException.h:59
@ ioError
I/O error.
Definition vpException.h:79
void parse(const std::string &filename)
vpMatchingMethodEnum getMatchingMethod() const