48 #include <visp3/vision/vpXmlConfigParserKeyPoint.h>
51 #include <pugixml.hpp>
53 #include <visp3/core/vpException.h>
55 #ifndef DOXYGEN_SHOULD_SKIP_THIS
56 class vpXmlConfigParserKeyPoint::Impl
60 : m_detectorName(
"ORB"), m_extractorName(
"ORB"), m_matcherName(
"BruteForce-Hamming"),
62 m_nbRansacIterations(200), m_nbRansacMinInlierCount(100), m_ransacConsensusPercentage(20.0),
63 m_ransacReprojectionError(6.0), m_ransacThreshold(0.01), m_useRansacConsensusPercentage(false),
74 m_nodeMap[
"conf"] = conf;
75 m_nodeMap[
"detector"] = detector;
76 m_nodeMap[
"extractor"] = extractor;
77 m_nodeMap[
"matcher"] = matcher;
78 m_nodeMap[
"name"] = name;
79 m_nodeMap[
"matching_method"] = matching_method;
80 m_nodeMap[
"constantFactorDistanceThreshold"] = constant_factor_distance_threshold;
81 m_nodeMap[
"stdDistanceThreshold"] = std_distance_threshold;
82 m_nodeMap[
"ratioDistanceThreshold"] = ratio_distance_threshold;
83 m_nodeMap[
"stdAndRatioDistanceThreshold"] = std_and_ratio_distance_threshold;
84 m_nodeMap[
"noFilterMatching"] = no_filter_matching;
85 m_nodeMap[
"matchingFactorThreshold"] = matching_factor_threshold;
86 m_nodeMap[
"matchingRatioThreshold"] = matching_ratio_threshold;
87 m_nodeMap[
"ransac"] = ransac;
88 m_nodeMap[
"useRansacVVS"] = use_ransac_vvs;
89 m_nodeMap[
"useRansacConsensusPercentage"] = use_ransac_consensus_percentage;
90 m_nodeMap[
"nbRansacIterations"] = nb_ransac_iterations;
91 m_nodeMap[
"ransacReprojectionError"] = ransac_reprojection_error;
92 m_nodeMap[
"nbRansacMinInlierCount"] = nb_ransac_min_inlier_count;
93 m_nodeMap[
"ransacThreshold"] = ransac_threshold;
94 m_nodeMap[
"ransacConsensusPercentage"] = ransac_consensus_percentage;
97 void parse(
const std::string &filename)
99 pugi::xml_document doc;
100 if (!doc.load_file(filename.c_str())) {
104 bool detector_node =
false;
105 bool extractor_node =
false;
106 bool matcher_node =
false;
108 pugi::xml_node root_node = doc.document_element();
109 for (pugi::xml_node dataNode = root_node.first_child(); dataNode; dataNode = dataNode.next_sibling()) {
110 if (dataNode.type() == pugi::node_element) {
111 std::map<std::string, int>::iterator iter_data = m_nodeMap.find(dataNode.name());
112 if (iter_data != m_nodeMap.end()) {
113 switch (iter_data->second) {
115 read_detector(dataNode);
116 detector_node =
true;
120 read_extractor(dataNode);
121 extractor_node =
true;
125 read_matcher(dataNode);
130 read_ransac(dataNode);
140 if (!detector_node) {
141 std::cout <<
"detector: name: " << m_detectorName <<
" (default)" << std::endl;
144 if (!extractor_node) {
145 std::cout <<
"extractor: name: " << m_extractorName <<
" (default)" << std::endl;
149 std::cout <<
"matcher: name: " << m_matcherName <<
" (default)" << std::endl;
158 void read_detector(
const pugi::xml_node &node)
160 bool detector_name_node =
false;
162 for (pugi::xml_node dataNode = node.first_child(); dataNode; dataNode = dataNode.next_sibling()) {
163 if (dataNode.type() == pugi::node_element) {
164 std::map<std::string, int>::iterator iter_data = m_nodeMap.find(dataNode.name());
165 if (iter_data != m_nodeMap.end()) {
166 switch (iter_data->second) {
168 m_detectorName = dataNode.text().as_string();
169 detector_name_node =
true;
179 if (!detector_name_node)
180 std::cout <<
"detector : Name : " << m_detectorName <<
" (default)" << std::endl;
182 std::cout <<
"detector : Name : " << m_detectorName << std::endl;
190 void read_extractor(
const pugi::xml_node &node)
192 bool extractor_name_node =
false;
194 for (pugi::xml_node dataNode = node.first_child(); dataNode; dataNode = dataNode.next_sibling()) {
195 if (dataNode.type() == pugi::node_element) {
196 std::map<std::string, int>::iterator iter_data = m_nodeMap.find(dataNode.name());
197 if (iter_data != m_nodeMap.end()) {
198 switch (iter_data->second) {
200 m_extractorName = dataNode.text().as_string();
201 extractor_name_node =
true;
211 if (!extractor_name_node)
212 std::cout <<
"extractor : Name : " << m_extractorName <<
" (default)" << std::endl;
214 std::cout <<
"extractor : Name : " << m_extractorName << std::endl;
222 void read_matcher(
const pugi::xml_node &node)
224 bool matcher_name_node =
false;
225 bool matching_method_node =
false;
226 std::string matchingMethodName =
"ratioDistanceThreshold";
227 bool matching_factor_threshold_node =
false;
228 bool matching_ratio_threshold_node =
false;
230 for (pugi::xml_node dataNode = node.first_child(); dataNode; dataNode = dataNode.next_sibling()) {
231 if (dataNode.type() == pugi::node_element) {
232 std::map<std::string, int>::iterator iter_data = m_nodeMap.find(dataNode.name());
233 if (iter_data != m_nodeMap.end()) {
234 switch (iter_data->second) {
236 m_matcherName = dataNode.text().as_string();
237 matcher_name_node =
true;
240 case matching_method: {
241 matchingMethodName = dataNode.text().as_string();
243 std::map<std::string, int>::iterator iter_data2 = m_nodeMap.find(matchingMethodName);
244 if (iter_data2 != m_nodeMap.end()) {
245 matching_method_node =
true;
246 switch (iter_data2->second) {
247 case constant_factor_distance_threshold:
251 case std_distance_threshold:
255 case ratio_distance_threshold:
259 case std_and_ratio_distance_threshold:
263 case no_filter_matching:
268 matching_method_node =
false;
275 case matching_factor_threshold:
276 m_matchingFactorThreshold = dataNode.text().as_double();
277 matching_factor_threshold_node =
true;
280 case matching_ratio_threshold:
281 m_matchingRatioThreshold = dataNode.text().as_double();
282 matching_ratio_threshold_node =
true;
292 if (!matcher_name_node)
293 std::cout <<
"matcher : Name : " << m_matcherName <<
" (default)" << std::endl;
295 std::cout <<
"matcher : Name : " << m_matcherName << std::endl;
297 if (!matching_method_node)
298 std::cout <<
"matcher : Filter method : " << matchingMethodName <<
" (default)" << std::endl;
300 std::cout <<
"matcher : Filter method : " << matchingMethodName << std::endl;
302 if (!matching_factor_threshold_node)
303 std::cout <<
"matcher : matching factor threshold : " << m_matchingFactorThreshold <<
" (default)" << std::endl;
305 std::cout <<
"matcher : matching factor threshold : " << m_matchingFactorThreshold << std::endl;
307 if (!matching_ratio_threshold_node)
308 std::cout <<
"matcher : matching ratio threshold : " << m_matchingRatioThreshold <<
" (default)" << std::endl;
310 std::cout <<
"matcher : matching ratio threshold : " << m_matchingRatioThreshold << std::endl;
318 void read_ransac(
const pugi::xml_node &node)
320 bool use_ransac_vvs_node =
false;
321 bool use_ransac_consensus_percentage_node =
false;
322 bool nb_ransac_iterations_node =
false;
323 bool ransac_reprojection_error_node =
false;
324 bool nb_ransac_min_inlier_count_node =
false;
325 bool ransac_threshold_node =
false;
326 bool ransac_consensus_percentage_node =
false;
328 for (pugi::xml_node dataNode = node.first_child(); dataNode; dataNode = dataNode.next_sibling()) {
329 if (dataNode.type() == pugi::node_element) {
330 std::map<std::string, int>::iterator iter_data = m_nodeMap.find(dataNode.name());
331 if (iter_data != m_nodeMap.end()) {
332 switch (iter_data->second) {
334 m_useRansacVVS = dataNode.text().as_int() != 0;
335 use_ransac_vvs_node =
true;
338 case use_ransac_consensus_percentage:
339 m_useRansacConsensusPercentage = dataNode.text().as_int() != 0;
340 use_ransac_consensus_percentage_node =
true;
343 case nb_ransac_iterations:
344 m_nbRansacIterations = dataNode.text().as_int();
345 nb_ransac_iterations_node =
true;
348 case ransac_reprojection_error:
349 m_ransacReprojectionError = dataNode.text().as_double();
350 ransac_reprojection_error_node =
true;
353 case nb_ransac_min_inlier_count:
354 m_nbRansacMinInlierCount = dataNode.text().as_int();
355 nb_ransac_min_inlier_count_node =
true;
358 case ransac_threshold:
359 m_ransacThreshold = dataNode.text().as_double();
360 ransac_threshold_node =
true;
363 case ransac_consensus_percentage:
364 m_ransacConsensusPercentage = dataNode.text().as_double();
365 ransac_consensus_percentage_node =
true;
375 if (!use_ransac_vvs_node)
376 std::cout <<
"ransac: use ransac vvs pose estimation: " << m_useRansacVVS <<
" (default)" << std::endl;
378 std::cout <<
"ransac: use ransac vvs pose estimation: " << m_useRansacVVS << std::endl;
380 if (!use_ransac_consensus_percentage_node)
381 std::cout <<
"ransac: use consensus percentage: " << m_useRansacConsensusPercentage <<
" (default)" << std::endl;
383 std::cout <<
"ransac: use consensus percentage: " << m_useRansacConsensusPercentage << std::endl;
385 if (!nb_ransac_iterations_node)
386 std::cout <<
"ransac: nb ransac iterations: " << m_nbRansacIterations <<
" (default)" << std::endl;
388 std::cout <<
"ransac: nb ransac iterations: " << m_nbRansacIterations << std::endl;
390 if (!ransac_reprojection_error_node)
391 std::cout <<
"ransac: ransac reprojection error in pixel (for OpenCV "
393 << m_ransacReprojectionError <<
" (default)" << std::endl;
395 std::cout <<
"ransac: ransac reprojection error in pixel (for OpenCV "
397 << m_ransacReprojectionError << std::endl;
399 if (!nb_ransac_min_inlier_count_node)
400 std::cout <<
"ransac: nb ransac min inlier count: " << m_nbRansacMinInlierCount <<
" (default)" << std::endl;
402 std::cout <<
"ransac: nb ransac min inlier count: " << m_nbRansacMinInlierCount << std::endl;
404 if (!ransac_threshold_node)
405 std::cout <<
"ransac: ransac threshold in meter (for ViSP function): " << m_ransacThreshold <<
" (default)"
408 std::cout <<
"ransac: ransac threshold in meter (for ViSP function): " << m_ransacThreshold << std::endl;
410 if (!ransac_consensus_percentage_node)
411 std::cout <<
"ransac: consensus percentage: " << m_ransacConsensusPercentage <<
" (default)" << std::endl;
413 std::cout <<
"ransac: consensus percentage: " << m_ransacConsensusPercentage << std::endl;
434 enum vpNodeIdentifier {
441 constant_factor_distance_threshold,
444 std_distance_threshold,
446 ratio_distance_threshold,
448 std_and_ratio_distance_threshold,
453 matching_factor_threshold,
455 matching_ratio_threshold,
459 use_ransac_consensus_percentage,
462 nb_ransac_iterations,
464 ransac_reprojection_error,
466 nb_ransac_min_inlier_count,
470 ransac_consensus_percentage
475 std::string m_detectorName;
477 std::string m_extractorName;
479 std::string m_matcherName;
481 double m_matchingFactorThreshold;
485 double m_matchingRatioThreshold;
487 int m_nbRansacIterations;
489 int m_nbRansacMinInlierCount;
491 double m_ransacConsensusPercentage;
494 double m_ransacReprojectionError;
497 double m_ransacThreshold;
501 bool m_useRansacConsensusPercentage;
505 std::map<std::string, int> m_nodeMap;
555 return m_impl->getMatchingMethod();
586 return m_impl->getRansacConsensusPercentage();
612 return m_impl->getUseRansacConsensusPercentage();
623 return m_impl->getUseRansacVVSPoseEstimation();
error that can be emited by ViSP classes.
std::string getDetectorName() const
~vpXmlConfigParserKeyPoint()
vpXmlConfigParserKeyPoint()
double getMatchingRatioThreshold() const
std::string getExtractorName() const
void parse(const std::string &filename)
double getRansacReprojectionError() const
bool getUseRansacVVSPoseEstimation() const
double getMatchingFactorThreshold() const
int getNbRansacMinInlierCount() const
bool getUseRansacConsensusPercentage() const
std::string getMatcherName() const
int getNbRansacIterations() const
double getRansacConsensusPercentage() const
@ stdAndRatioDistanceThreshold
@ constantFactorDistanceThreshold
vpMatchingMethodEnum getMatchingMethod() const
double getRansacThreshold() const