43 #include <visp3/vision/vpXmlConfigParserKeyPoint.h>
46 #include <pugixml.hpp>
48 #include <visp3/core/vpException.h>
50 #ifndef DOXYGEN_SHOULD_SKIP_THIS
51 class vpXmlConfigParserKeyPoint::Impl
55 : m_detectorName(
"ORB"), m_extractorName(
"ORB"), m_matcherName(
"BruteForce-Hamming"),
57 m_nbRansacIterations(200), m_nbRansacMinInlierCount(100), m_ransacConsensusPercentage(20.0),
58 m_ransacReprojectionError(6.0), m_ransacThreshold(0.01), m_useRansacConsensusPercentage(false),
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;
92 void parse(
const std::string &filename)
94 pugi::xml_document doc;
95 if (!doc.load_file(filename.c_str())) {
99 bool detector_node =
false;
100 bool extractor_node =
false;
101 bool matcher_node =
false;
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) {
110 read_detector(dataNode);
111 detector_node =
true;
115 read_extractor(dataNode);
116 extractor_node =
true;
120 read_matcher(dataNode);
125 read_ransac(dataNode);
135 if (!detector_node) {
136 std::cout <<
"detector: name: " << m_detectorName <<
" (default)" << std::endl;
139 if (!extractor_node) {
140 std::cout <<
"extractor: name: " << m_extractorName <<
" (default)" << std::endl;
144 std::cout <<
"matcher: name: " << m_matcherName <<
" (default)" << std::endl;
153 void read_detector(
const pugi::xml_node &node)
155 bool detector_name_node =
false;
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) {
163 m_detectorName = dataNode.text().as_string();
164 detector_name_node =
true;
174 if (!detector_name_node)
175 std::cout <<
"detector : Name : " << m_detectorName <<
" (default)" << std::endl;
177 std::cout <<
"detector : Name : " << m_detectorName << std::endl;
185 void read_extractor(
const pugi::xml_node &node)
187 bool extractor_name_node =
false;
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) {
195 m_extractorName = dataNode.text().as_string();
196 extractor_name_node =
true;
206 if (!extractor_name_node)
207 std::cout <<
"extractor : Name : " << m_extractorName <<
" (default)" << std::endl;
209 std::cout <<
"extractor : Name : " << m_extractorName << std::endl;
217 void read_matcher(
const pugi::xml_node &node)
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;
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) {
231 m_matcherName = dataNode.text().as_string();
232 matcher_name_node =
true;
235 case matching_method: {
236 matchingMethodName = dataNode.text().as_string();
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:
246 case std_distance_threshold:
250 case ratio_distance_threshold:
254 case std_and_ratio_distance_threshold:
258 case no_filter_matching:
263 matching_method_node =
false;
270 case matching_factor_threshold:
271 m_matchingFactorThreshold = dataNode.text().as_double();
272 matching_factor_threshold_node =
true;
275 case matching_ratio_threshold:
276 m_matchingRatioThreshold = dataNode.text().as_double();
277 matching_ratio_threshold_node =
true;
287 if (!matcher_name_node)
288 std::cout <<
"matcher : Name : " << m_matcherName <<
" (default)" << std::endl;
290 std::cout <<
"matcher : Name : " << m_matcherName << std::endl;
292 if (!matching_method_node)
293 std::cout <<
"matcher : Filter method : " << matchingMethodName <<
" (default)" << std::endl;
295 std::cout <<
"matcher : Filter method : " << matchingMethodName << std::endl;
297 if (!matching_factor_threshold_node)
298 std::cout <<
"matcher : matching factor threshold : " << m_matchingFactorThreshold <<
" (default)" << std::endl;
300 std::cout <<
"matcher : matching factor threshold : " << m_matchingFactorThreshold << std::endl;
302 if (!matching_ratio_threshold_node)
303 std::cout <<
"matcher : matching ratio threshold : " << m_matchingRatioThreshold <<
" (default)" << std::endl;
305 std::cout <<
"matcher : matching ratio threshold : " << m_matchingRatioThreshold << std::endl;
313 void read_ransac(
const pugi::xml_node &node)
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;
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) {
329 m_useRansacVVS = dataNode.text().as_int() != 0;
330 use_ransac_vvs_node =
true;
333 case use_ransac_consensus_percentage:
334 m_useRansacConsensusPercentage = dataNode.text().as_int() != 0;
335 use_ransac_consensus_percentage_node =
true;
338 case nb_ransac_iterations:
339 m_nbRansacIterations = dataNode.text().as_int();
340 nb_ransac_iterations_node =
true;
343 case ransac_reprojection_error:
344 m_ransacReprojectionError = dataNode.text().as_double();
345 ransac_reprojection_error_node =
true;
348 case nb_ransac_min_inlier_count:
349 m_nbRansacMinInlierCount = dataNode.text().as_int();
350 nb_ransac_min_inlier_count_node =
true;
353 case ransac_threshold:
354 m_ransacThreshold = dataNode.text().as_double();
355 ransac_threshold_node =
true;
358 case ransac_consensus_percentage:
359 m_ransacConsensusPercentage = dataNode.text().as_double();
360 ransac_consensus_percentage_node =
true;
370 if (!use_ransac_vvs_node)
371 std::cout <<
"ransac: use ransac vvs pose estimation: " << m_useRansacVVS <<
" (default)" << std::endl;
373 std::cout <<
"ransac: use ransac vvs pose estimation: " << m_useRansacVVS << std::endl;
375 if (!use_ransac_consensus_percentage_node)
376 std::cout <<
"ransac: use consensus percentage: " << m_useRansacConsensusPercentage <<
" (default)" << std::endl;
378 std::cout <<
"ransac: use consensus percentage: " << m_useRansacConsensusPercentage << std::endl;
380 if (!nb_ransac_iterations_node)
381 std::cout <<
"ransac: nb ransac iterations: " << m_nbRansacIterations <<
" (default)" << std::endl;
383 std::cout <<
"ransac: nb ransac iterations: " << m_nbRansacIterations << std::endl;
385 if (!ransac_reprojection_error_node)
386 std::cout <<
"ransac: ransac reprojection error in pixel (for OpenCV "
388 << m_ransacReprojectionError <<
" (default)" << std::endl;
390 std::cout <<
"ransac: ransac reprojection error in pixel (for OpenCV "
392 << m_ransacReprojectionError << std::endl;
394 if (!nb_ransac_min_inlier_count_node)
395 std::cout <<
"ransac: nb ransac min inlier count: " << m_nbRansacMinInlierCount <<
" (default)" << std::endl;
397 std::cout <<
"ransac: nb ransac min inlier count: " << m_nbRansacMinInlierCount << std::endl;
399 if (!ransac_threshold_node)
400 std::cout <<
"ransac: ransac threshold in meter (for ViSP function): " << m_ransacThreshold <<
" (default)"
403 std::cout <<
"ransac: ransac threshold in meter (for ViSP function): " << m_ransacThreshold << std::endl;
405 if (!ransac_consensus_percentage_node)
406 std::cout <<
"ransac: consensus percentage: " << m_ransacConsensusPercentage <<
" (default)" << std::endl;
408 std::cout <<
"ransac: consensus percentage: " << m_ransacConsensusPercentage << std::endl;
429 enum vpNodeIdentifier {
436 constant_factor_distance_threshold,
439 std_distance_threshold,
441 ratio_distance_threshold,
443 std_and_ratio_distance_threshold,
448 matching_factor_threshold,
450 matching_ratio_threshold,
454 use_ransac_consensus_percentage,
457 nb_ransac_iterations,
459 ransac_reprojection_error,
461 nb_ransac_min_inlier_count,
465 ransac_consensus_percentage
470 std::string m_detectorName;
472 std::string m_extractorName;
474 std::string m_matcherName;
476 double m_matchingFactorThreshold;
480 double m_matchingRatioThreshold;
482 int m_nbRansacIterations;
484 int m_nbRansacMinInlierCount;
486 double m_ransacConsensusPercentage;
489 double m_ransacReprojectionError;
492 double m_ransacThreshold;
496 bool m_useRansacConsensusPercentage;
500 std::map<std::string, int> m_nodeMap;
550 return m_impl->getMatchingMethod();
581 return m_impl->getRansacConsensusPercentage();
607 return m_impl->getUseRansacConsensusPercentage();
618 return m_impl->getUseRansacVVSPoseEstimation();
error that can be emitted 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