From 4f77b5140c9240d1b80f46e0e2f6781140f5a3ee Mon Sep 17 00:00:00 2001 From: angelsantamaria <somriu@gmail.com> Date: Sun, 30 Jul 2017 13:33:04 +0200 Subject: [PATCH] Added initial matcher structure. match not yet prepared --- .settings/language.settings.xml | 4 +- src/examples/feature_detectors.cpp | 6 +- .../feature_detectors_and_descriptors.cpp | 14 +- src/feature_descriptor/feature_descriptor.cpp | 14 +- src/feature_descriptor/feature_descriptor.h | 16 +-- src/feature_detector/feature_detector.cpp | 8 +- src/feature_detector/feature_detector.h | 8 +- src/feature_matcher/feature_matcher.cpp | 133 +++++++++++++++++- src/feature_matcher/feature_matcher.h | 101 ++++++++++++- 9 files changed, 261 insertions(+), 43 deletions(-) diff --git a/.settings/language.settings.xml b/.settings/language.settings.xml index ca971ab..c588c28 100644 --- a/.settings/language.settings.xml +++ b/.settings/language.settings.xml @@ -4,8 +4,8 @@ <extension point="org.eclipse.cdt.core.LanguageSettingsProvider"> <provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/> <provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/> - <provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuildCommandParser" id="org.eclipse.cdt.managedbuilder.core.GCCBuildCommandParser" keep-relative-paths="false" name="CDT GCC Build Output Parser" parameter="(g?cc)|([gc]\+\+)|(clang)" prefer-non-shared="true"/> - <provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="1504749124108071272" id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true"> + <provider copy-of="extension" id="org.eclipse.cdt.managedbuilder.core.GCCBuildCommandParser"/> + <provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="1476617952823822664" id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true"> <language-scope id="org.eclipse.cdt.core.gcc"/> <language-scope id="org.eclipse.cdt.core.g++"/> </provider> diff --git a/src/examples/feature_detectors.cpp b/src/examples/feature_detectors.cpp index 650dbcf..93e48e4 100644 --- a/src/examples/feature_detectors.cpp +++ b/src/examples/feature_detectors.cpp @@ -9,7 +9,7 @@ int main(int argc, char *argv[]) { CFeature_Detector detector; std::vector<detector::Type> detectors_list; - detectors_list = detector.listDetectors(); + detectors_list = detector.list(); std::cout << "----------------------------------------" << std::endl; std::cout << "| Feature detector example |" << std::endl; @@ -22,7 +22,7 @@ int main(int argc, char *argv[]) std::cout << std::endl << "Which DETECTOR do you want to test?: "; int feat_type; std::cin >> feat_type; - detector.setDetectorType(feat_type); + detector.setType(feat_type); std::cout << std::endl << "Testing: " << detectors_list[feat_type] << std::endl; // Open camera @@ -62,7 +62,7 @@ int main(int argc, char *argv[]) detector.drawKeyFeatures(frame, keypoints); } - std::cout << "\e[A" << "Detection time: " << detector.getDetectionTime() << std::endl; + std::cout << "\e[A" << "Detection time: " << detector.getTime() << std::endl; // Show NEW frame cv::imshow("Detections", frame); diff --git a/src/examples/feature_detectors_and_descriptors.cpp b/src/examples/feature_detectors_and_descriptors.cpp index ca11eb2..432aea8 100644 --- a/src/examples/feature_detectors_and_descriptors.cpp +++ b/src/examples/feature_detectors_and_descriptors.cpp @@ -9,7 +9,7 @@ int main(int argc, char *argv[]) { CFeature_Detector detector; std::vector<detector::Type> detectors_list; - detectors_list = detector.listDetectors(); + detectors_list = detector.list(); std::cout << "---------------------------------------------------------" << std::endl; std::cout << "| Feature detectors and descriptors example |" << std::endl; @@ -25,11 +25,11 @@ int main(int argc, char *argv[]) std::cout << std::endl << "Which DETECTOR do you want to test?: "; int feat_type; std::cin >> feat_type; - detector.setDetectorType(feat_type); + detector.setType(feat_type); CFeature_Descriptor descriptor; std::vector<descriptor::Type> descriptor_list; - descriptor_list = descriptor.listDescriptors(); + descriptor_list = descriptor.list(); for (unsigned int ii=0; ii<descriptor_list.size(); ii++) std::cout << "[" << ii << "]: " << descriptor_list[ii] << std::endl; @@ -37,7 +37,7 @@ int main(int argc, char *argv[]) std::cout << std::endl << "Which DESCRIPTOR do you want to test?: "; int desc_type; std::cin >> desc_type; - descriptor.setDescriptorType(desc_type); + descriptor.setType(desc_type); std::cout << std::endl << "Testing: " << detectors_list[feat_type] << " + " << descriptor_list[feat_type] << " (DETECTOR + DESCRIPTOR)" << std::endl; // Open camera @@ -74,9 +74,9 @@ int main(int argc, char *argv[]) detector.drawKeyFeatures(frame, keypoints); std::cout << "\e[A" << - "Detection time: " << detector.getDetectionTime() << " " << - "Description time: " << descriptor.getDescriptorTime() << " " << - "TOTAL time: " << detector.getDetectionTime() + descriptor.getDescriptorTime() << std::endl; + "Detection time: " << detector.getTime() << " " << + "Description time: " << descriptor.getTime() << " " << + "TOTAL time: " << detector.getTime() + descriptor.getTime() << std::endl; // Show NEW frame cv::imshow("Detections", frame); diff --git a/src/feature_descriptor/feature_descriptor.cpp b/src/feature_descriptor/feature_descriptor.cpp index 4ef6c37..3ab6871 100644 --- a/src/feature_descriptor/feature_descriptor.cpp +++ b/src/feature_descriptor/feature_descriptor.cpp @@ -15,7 +15,7 @@ CFeature_Descriptor::CFeature_Descriptor(const descriptor::Type& _type) : CFeature_Descriptor::CFeature_Descriptor(const int&_type) : type_(descriptor::__DELIM__), is_init_(false), descript_time_(0.0) { - is_init_ = init(intToDescriptorType(_type)); + is_init_ = init(intToType(_type)); if (!is_init_) { std::cerr @@ -31,7 +31,7 @@ CFeature_Descriptor::CFeature_Descriptor() : CFeature_Descriptor::~CFeature_Descriptor() { } -std::vector<descriptor::Type> CFeature_Descriptor::listDescriptors(void) +std::vector<descriptor::Type> CFeature_Descriptor::list(void) { std::vector<descriptor::Type> list; @@ -43,19 +43,19 @@ std::vector<descriptor::Type> CFeature_Descriptor::listDescriptors(void) return list; } -bool CFeature_Descriptor::setDescriptorType(const descriptor::Type& _type) +bool CFeature_Descriptor::setType(const descriptor::Type& _type) { is_init_ = init(_type); return is_init_; } -bool CFeature_Descriptor::setDescriptorType(const int& _type) +bool CFeature_Descriptor::setType(const int& _type) { - is_init_ = init(intToDescriptorType(_type)); + is_init_ = init(intToType(_type)); return is_init_; } -double CFeature_Descriptor::getDescriptorTime(void) +double CFeature_Descriptor::getTime(void) { return descript_time_; } @@ -142,7 +142,7 @@ cv::Mat CFeature_Descriptor::getDescriptor(const cv::Mat& _image, CFeature_Descr return descriptors; } -descriptor::Type CFeature_Descriptor::intToDescriptorType( +descriptor::Type CFeature_Descriptor::intToType( const unsigned int _i) { descriptor::Type type; diff --git a/src/feature_descriptor/feature_descriptor.h b/src/feature_descriptor/feature_descriptor.h index 0a88c02..d895cac 100644 --- a/src/feature_descriptor/feature_descriptor.h +++ b/src/feature_descriptor/feature_descriptor.h @@ -18,7 +18,7 @@ typedef cv::Ptr<cv::DescriptorExtractor> FeatureDescriptorPtr; namespace descriptor { /** - * \brief MACROS to generate all detector types and their corresponding strings + * \brief MACROS to generate all descriptor types and their corresponding strings */ #define FOREACH_DESCRIPTOR(DESCRIPTOR) \ DESCRIPTOR(ORB) \ @@ -66,20 +66,20 @@ public: ~CFeature_Descriptor(void); /** - * \brief List the defined detector types + * \brief List the defined types */ - std::vector<descriptor::Type> listDescriptors(void); + std::vector<descriptor::Type> list(void); /** - * \brief Set descriptor type + * \brief Set type */ - bool setDescriptorType(const descriptor::Type& _type); - bool setDescriptorType(const int& _type); + bool setType(const descriptor::Type& _type); + bool setType(const int& _type); /** * \brief Get detection duration */ - double getDescriptorTime(void); + double getTime(void); /** * \brief Get descriptors @@ -108,7 +108,7 @@ private: * * By default return ORB. */ - descriptor::Type intToDescriptorType(const unsigned int _i); + descriptor::Type intToType(const unsigned int _i); }; diff --git a/src/feature_detector/feature_detector.cpp b/src/feature_detector/feature_detector.cpp index 7535472..3e1b93e 100644 --- a/src/feature_detector/feature_detector.cpp +++ b/src/feature_detector/feature_detector.cpp @@ -34,7 +34,7 @@ CFeature_Detector::~CFeature_Detector() { } -std::vector<detector::Type> CFeature_Detector::listDetectors(void) +std::vector<detector::Type> CFeature_Detector::list(void) { std::vector<detector::Type> list; @@ -46,13 +46,13 @@ std::vector<detector::Type> CFeature_Detector::listDetectors(void) return list; } -bool CFeature_Detector::setDetectorType(const detector::Type& _type) +bool CFeature_Detector::setType(const detector::Type& _type) { is_init_ = init(_type); return is_init_; } -bool CFeature_Detector::setDetectorType(const int& _type) +bool CFeature_Detector::setType(const int& _type) { detector::Type type; intToType(_type, type); @@ -60,7 +60,7 @@ bool CFeature_Detector::setDetectorType(const int& _type) return is_init_; } -double CFeature_Detector::getDetectionTime(void) +double CFeature_Detector::getTime(void) { return detect_time_; } diff --git a/src/feature_detector/feature_detector.h b/src/feature_detector/feature_detector.h index fb283a1..6400c96 100644 --- a/src/feature_detector/feature_detector.h +++ b/src/feature_detector/feature_detector.h @@ -89,18 +89,18 @@ class CFeature_Detector /** * \brief List the defined detector types */ - std::vector<detector::Type> listDetectors(void); + std::vector<detector::Type> list(void); /** * \brief Set detector type */ - bool setDetectorType(const detector::Type& _type); - bool setDetectorType(const int& _type); + bool setType(const detector::Type& _type); + bool setType(const int& _type); /** * \brief Get detection duration */ - double getDetectionTime(void); + double getTime(void); /** * \brief Inform if the detector searches points or lines diff --git a/src/feature_matcher/feature_matcher.cpp b/src/feature_matcher/feature_matcher.cpp index d4d34fb..205cb68 100644 --- a/src/feature_matcher/feature_matcher.cpp +++ b/src/feature_matcher/feature_matcher.cpp @@ -1,10 +1,139 @@ #include "feature_matcher.h" -CFeature_Matcher::CFeature_Matcher() +CFeature_Matcher::CFeature_Matcher(const matcher::Type& _type) : + type_(matcher::__DELIM__), is_init_(false), match_time_(0.0) +{ + + is_init_ = init(_type); + + if (!is_init_) + { + std::cerr << "[Feature Matcher]: Something went wrong during initialization! Feature Matcher not initialized." + << std::endl; + } +} + +CFeature_Matcher::CFeature_Matcher(const int& _type) : + type_(matcher::__DELIM__), is_init_(false), match_time_(0.0) +{ + + is_init_ = init(intToType(_type)); + + if (!is_init_) + { + std::cerr << "[Feature Matcher]: Something went wrong during initialization! Feature Matcher not initialized." + << std::endl; + } +} + +CFeature_Matcher::CFeature_Matcher(void) : + type_(matcher::__DELIM__), is_init_(false), match_time_(0.0) { } -CFeature_Matcher::~CFeature_Matcher() +CFeature_Matcher::~CFeature_Matcher(void) { } +std::vector<matcher::Type> CFeature_Matcher::list(void) +{ + std::vector<matcher::Type> list; + + for (int ii = 0; ii < matcher::__DELIM__; ii++) + { + list.push_back(static_cast<matcher::Type>(ii)); + } + + return list; +} + +bool CFeature_Matcher::setType(const matcher::Type& _type) +{ + is_init_ = init(_type); + return is_init_; +} + +bool CFeature_Matcher::setType(const int& _type) +{ + is_init_ = init(intToType(_type)); + return is_init_; +} + +double CFeature_Matcher::getTime(void) +{ + return match_time_; +} + +bool CFeature_Matcher::init(matcher::Type _type) { + if (is_init_) + std::cerr + << "[CFeature_Matcher::init]: Matcher already initialized." + << std::endl; + + bool success = false; + + // TODO: Set parameters for each matcher type + switch (_type) { + case matcher::BF_NORM_L1: + feature_matcher_ = cv::DescriptorMatcher::create("BF_NORM_L1"); + success = true; + break; + case matcher::BF_NORM_L2: + feature_matcher_ = cv::DescriptorMatcher::create("BF_NORM_L2"); + success = true; + break; + case matcher::BF_NORM_HAMMING: + feature_matcher_ = cv::DescriptorMatcher::create("BF_NORM_HAMMING"); + success = true; + break; + case matcher::BF_NORM_HAMMING2: + feature_matcher_ = cv::DescriptorMatcher::create("BF_NORM_HAMMING2"); + success = true; + break; + case matcher::FlannBased: + feature_matcher_ = cv::DescriptorMatcher::create("FlannBased"); + success = true; + break; + case matcher::__DELIM__: + success = false; + break; + } + + if (success) + type_ = _type; + else + std::cerr << "[Feature Matcher]: mathcer_type " << _type + << " doesn't exist !" << std::endl; + + return success; +} + + +// TODO: Match features and process matches (e.g. https://github.com/kipr/opencv/blob/master/samples/cpp/detector_descriptor_matcher_evaluation.cpp) + +//cv::Mat CFeature_Matcher::match(const cv::Mat& _image, CFeature_Descriptor::KeyPointVector& _kpts) +//{ +// if (!is_init_) +// std::cerr << "[CFeature_Matcher::match]: Matcher non initialized." << std::endl; +// +// cv::Mat descriptors; +// +// clock_t tStart = clock(); +// feature_matcher_->compute(_image, _kpts, descriptors); +// match_time_ = (double)(clock() - tStart) / CLOCKS_PER_SEC; +// +// return descriptors; +//} + +matcher::Type CFeature_Matcher::intToType( + const unsigned int _i) { + matcher::Type type; + + for (unsigned int ii = 0; ii < matcher::__DELIM__; ii++) { + if (ii == _i) + type = static_cast<matcher::Type>(ii); + } + + return type; +} + diff --git a/src/feature_matcher/feature_matcher.h b/src/feature_matcher/feature_matcher.h index a8eecc2..ac956ea 100644 --- a/src/feature_matcher/feature_matcher.h +++ b/src/feature_matcher/feature_matcher.h @@ -1,17 +1,106 @@ #ifndef _FEATURE_MATCHER_H #define _FEATURE_MATCHER_H -// Matcher types -enum MATCHER_TYPE -{ - BF_NORM_L2, BF_NORM_HAMMING, BF_NORM_HAMMING2 +#include <time.h> + +// OpenCV stuff +#include <opencv2/core/core.hpp> +#include <opencv2/core/types.hpp> +#include <opencv2/imgproc/imgproc.hpp> +#include <opencv2/highgui/highgui.hpp> +#include <opencv2/features2d/features2d.hpp> +#include <opencv2/xfeatures2d/nonfree.hpp> +#include <opencv2/xfeatures2d.hpp> +#include <opencv2/line_descriptor/descriptor.hpp> + +typedef cv::Ptr<cv::DescriptorMatcher> FeatureMatcherPtr; + +namespace matcher { + +/** + * \brief MACROS to generate all matcher types and their corresponding strings + */ +#define FOREACH_MATCHER(MATCHER) \ + MATCHER(BF_NORM_L1) \ + MATCHER(BF_NORM_L2) \ + MATCHER(BF_NORM_HAMMING) \ + MATCHER(BF_NORM_HAMMING2) \ + MATCHER(FlannBased) \ + MATCHER(__DELIM__) \ + +#define GENERATE_ENUM(ENUM) ENUM, +#define GENERATE_STRING(STRING) #STRING, +enum Type { + FOREACH_MATCHER(GENERATE_ENUM) }; +static const char *MATCHER_TYPE_STRING[] = { FOREACH_MATCHER( + GENERATE_STRING) }; + +/** + * \brief Stream operator for the matcher flags. + */ +inline std::ostream& operator<<(std::ostream& _os, Type _f) { + _os << MATCHER_TYPE_STRING[_f]; + return _os; +} + +} // end of namespace class CFeature_Matcher { public: - CFeature_Matcher(); - ~CFeature_Matcher(); + + CFeature_Matcher(const matcher::Type& _type); + CFeature_Matcher(const int& _type); + CFeature_Matcher(void); + + ~CFeature_Matcher(void); + + /** + * \brief List the defined types + */ + std::vector<matcher::Type> list(void); + + /** + * \brief Set type + */ + bool setType(const matcher::Type& _type); + bool setType(const int& _type); + + /** + * \brief Get match duration + */ + double getTime(void); + + /** + * \brief Match + */ +// cv::Mat match(const cv::Mat& _image, +// CFeature_Descriptor::KeyPointVector& _kpts); + + private: + + matcher::Type type_; + + // Flags + bool is_init_; + + double match_time_; // Match time + + FeatureMatcherPtr feature_matcher_; // Feature matcher + + /** + * \brief Initialize matcher + */ + bool init(matcher::Type _type); + + /** + * \brief Convert an integer to its corresponding descriptor flag. + * + */ + matcher::Type intToType(const unsigned int _i); + + }; #endif -- GitLab