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 &quot;${INPUTS}&quot;" 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 &quot;${INPUTS}&quot;" 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