From 623c9c8f93b80fe28602d7a7755126ea64a8dd41 Mon Sep 17 00:00:00 2001
From: angelsantamaria <somriu@gmail.com>
Date: Mon, 1 May 2017 20:11:25 +0200
Subject: [PATCH] main feature detectors. Brute force and default parameters

---
 src/examples/feature_detection.cpp        |  30 ++----
 src/feature_detector/feature_detector.cpp | 106 ++++++++++++++++++----
 src/feature_detector/feature_detector.h   |  94 ++++++++++---------
 3 files changed, 146 insertions(+), 84 deletions(-)

diff --git a/src/examples/feature_detection.cpp b/src/examples/feature_detection.cpp
index 6327886..24cfb71 100644
--- a/src/examples/feature_detection.cpp
+++ b/src/examples/feature_detection.cpp
@@ -6,32 +6,23 @@
 
 int main(int argc, char *argv[])
 {
+    CFeature_Detector detector;
+    std::vector<DETECTOR_TYPE> detectors_list;
+    detectors_list = detector.listDetectors();
+
     std::cout << "----------------------------------------" << std::endl;
     std::cout << "|       Feature detector example       |" << std::endl;
     std::cout << "----------------------------------------" << std::endl;
     std::cout << std::endl;
 
-    std::vector<std::string> options;
-    options.resize(11);
-    options[0] = "ORB";
-    options[1] = "SIFT";
-    options[2] = "SURF";
-    options[3] = "AKAZE";
-    options[4] = "KAZE";
-    options[5] = "BRISK";
-    options[6] = "MSER";
-    options[7] = "FAST";
-    options[8] = "LSD";
-    options[9] = "ED";
-    options[10] = "AGAST";
-
-    for (unsigned int ii=0; ii<options.size(); ii++)
-        std::cout << "[" << ii << "]: " << options[ii] << std::endl;
+    for (unsigned int ii=0; ii<detectors_list.size(); ii++)
+        std::cout << "[" << ii << "]: " << detectors_list[ii] << std::endl;
 
     std::cout << std::endl << "Which feature do you want to test?: ";
     int feat_type;
     std::cin >> feat_type;
-    std::cout << std::endl << "Testing: " << options[feat_type] << std::endl;
+    detector.setDetectorType(feat_type);
+    std::cout << std::endl << "Testing: " << detectors_list[feat_type] << std::endl;
 
     // Open camera
     cv::VideoCapture cam;
@@ -55,10 +46,7 @@ int main(int argc, char *argv[])
         // Show ORIGINAL frame
         cv::imshow("Original image", frame);
 
-        // Detect features (keypoints)
-        CFeature_Detector detector(feat_type);
-
-        if (feat_type!=8 && feat_type!=9)
+        if (!detector.isLine())
         {
             CFeature_Detector::KeyPointVector keypoints;
             keypoints = detector.detectKeyPoints(frame);
diff --git a/src/feature_detector/feature_detector.cpp b/src/feature_detector/feature_detector.cpp
index baf805b..e427d93 100644
--- a/src/feature_detector/feature_detector.cpp
+++ b/src/feature_detector/feature_detector.cpp
@@ -15,7 +15,7 @@ CFeature_Detector::CFeature_Detector(const DETECTOR_TYPE& _type) :
 CFeature_Detector::CFeature_Detector(const int&_type) :
         is_init_(false), is_line_(false), is_limited_(false), keypoints_limit_(-1), detect_time_(0.0)
 {
-    is_init_ = init( intToDetectorType(_type) );
+    is_init_ = init(intToDetectorType(_type));
 
     if (!is_init_)
     {
@@ -24,19 +24,69 @@ CFeature_Detector::CFeature_Detector(const int&_type) :
     }
 }
 
+CFeature_Detector::CFeature_Detector(void) :
+        is_init_(false), is_line_(false), is_limited_(false), keypoints_limit_(-1), detect_time_(0.0)
+{
+}
 
 CFeature_Detector::~CFeature_Detector()
 {
 }
 
+std::vector<DETECTOR_TYPE> CFeature_Detector::listDetectors(void)
+{
+    std::vector<DETECTOR_TYPE> list;
+
+    for(int ii = 0; ii < ED+1; ii++){
+        list.push_back(static_cast<DETECTOR_TYPE>(ii));
+    }
+
+    return list;
+}
+
+bool CFeature_Detector::setDetectorType(const DETECTOR_TYPE& _type)
+{
+    is_init_ = init( _type );
+    return is_init_;
+}
+
+bool CFeature_Detector::setDetectorType(const int& _type)
+{
+    is_init_ = init( intToDetectorType(_type) );
+    return is_init_;
+}
+
+double CFeature_Detector::getDetectionTime(void)
+{
+    return detect_time_;
+}
+
+bool CFeature_Detector::isLine(void)
+{
+    return is_line_;
+}
+
+bool CFeature_Detector::isLimited(void)
+{
+    return is_limited_;
+}
+
+int CFeature_Detector::getKeyPointsLimit(void)
+{
+    return keypoints_limit_;
+}
+
 bool CFeature_Detector::init(DETECTOR_TYPE _type)
 {
+    if (is_init_)
+         std::cerr << "[CFeature_Detector::init]: Detector already initialized." << std::endl;
+
     bool success = false;
 
     switch (_type)
     {
-        case ORB:
-            feature_detector_ = cv::ORB::create();
+        case FAST:
+            feature_detector_ = cv::FastFeatureDetector::create();
             success = true;
             break;
         case SIFT:
@@ -47,12 +97,8 @@ bool CFeature_Detector::init(DETECTOR_TYPE _type)
             feature_detector_ = cv::xfeatures2d::SURF::create();
             success = true;
             break;
-        case AKAZE:
-            feature_detector_ = cv::AKAZE::create();
-            success = true;
-            break;
-        case KAZE:
-            feature_detector_ = cv::KAZE::create();
+        case ORB:
+            feature_detector_ = cv::ORB::create();
             success = true;
             break;
         case BRISK:
@@ -63,8 +109,24 @@ bool CFeature_Detector::init(DETECTOR_TYPE _type)
             feature_detector_ = cv::MSER::create();
             success = true;
             break;
-        case FAST:
-            feature_detector_ = cv::FastFeatureDetector::create();
+        case GFTT:
+            feature_detector_ = cv::GFTTDetector::create(1000,0.01,1.0,3,false,0.04);
+            success = true;
+            break;
+        case HARRIS:
+            feature_detector_ = cv::GFTTDetector::create(1000,0.01,1.0,3,true,0.04);
+            success = true;
+            break;
+        case SBD:
+            feature_detector_ = cv::SimpleBlobDetector::create();
+            success = true;
+            break;
+        case KAZE:
+            feature_detector_ = cv::KAZE::create();
+            success = true;
+            break;
+        case AKAZE:
+            feature_detector_ = cv::AKAZE::create();
             success = true;
             break;
         case AGAST:
@@ -93,11 +155,14 @@ bool CFeature_Detector::init(DETECTOR_TYPE _type)
 
 CFeature_Detector::KeyPointVector CFeature_Detector::detectKeyPoints(const cv::Mat& _image)
 {
+    if (!is_init_)
+         std::cerr << "[CFeature_Detector::detectKeyPoints]: Detector non initialized." << std::endl;
+
     KeyPointVector kpts;
 
     clock_t tStart = clock();
     feature_detector_->detect(_image, kpts);
-    detect_time_ = (double)(clock() - tStart)/CLOCKS_PER_SEC;
+    detect_time_ = (double)(clock() - tStart) / CLOCKS_PER_SEC;
 
     if (this->isLimited())
     {
@@ -110,6 +175,9 @@ CFeature_Detector::KeyPointVector CFeature_Detector::detectKeyPoints(const cv::M
 
 CFeature_Detector::KeyLineVector CFeature_Detector::detectKeyLines(const cv::Mat& _image)
 {
+    if (!is_init_)
+         std::cerr << "[CFeature_Detector::detectKeyLines]: Detector non initialized." << std::endl;
+
     KeyLineVector kls;
     KeyLineVector kls2;
 
@@ -118,7 +186,7 @@ CFeature_Detector::KeyLineVector CFeature_Detector::detectKeyLines(const cv::Mat
         lsd_detector_->detect(_image, kls, SCALE_FACTOR_LINE_DETECTOR, NUM_OCTAVE_LINE_DETECTOR);
     else
         ed_detector_->detect(_image, kls2);
-    detect_time_ = (double)(clock() - tStart)/CLOCKS_PER_SEC;
+    detect_time_ = (double)(clock() - tStart) / CLOCKS_PER_SEC;
     kls.insert(kls.end(), kls2.begin(), kls2.end());
 
     return kls;
@@ -126,9 +194,6 @@ CFeature_Detector::KeyLineVector CFeature_Detector::detectKeyLines(const cv::Mat
 
 bool CFeature_Detector::limitKeypts(unsigned int _nFeatures)
 {
-    if (!is_init_)
-        return false;
-
     if (_nFeatures > 0)
     {
         keypoints_limit_ = _nFeatures;
@@ -138,22 +203,23 @@ bool CFeature_Detector::limitKeypts(unsigned int _nFeatures)
     return false;
 }
 
-cv::Mat CFeature_Detector::drawKeyFeatures( const cv::Mat& _image, const std::vector<cv::KeyPoint>& _kp_vec )
+cv::Mat CFeature_Detector::drawKeyFeatures(const cv::Mat& _image, const std::vector<cv::KeyPoint>& _kp_vec)
 {
     cv::Mat img_out(_image);
 
     for (unsigned int ii = 0; ii < _kp_vec.size(); ++ii)
-        cv::circle(img_out, _kp_vec[ii].pt, 5, cv::Scalar(128,128,255), -1);
+        cv::circle(img_out, _kp_vec[ii].pt, 5, cv::Scalar(128, 128, 255), -1);
 
     return img_out;
 }
 
-cv::Mat CFeature_Detector::drawKeyFeatures( const cv::Mat& _image, const std::vector<cv::line_descriptor::KeyLine>& _kl_vec )
+cv::Mat CFeature_Detector::drawKeyFeatures(const cv::Mat& _image,
+                                           const std::vector<cv::line_descriptor::KeyLine>& _kl_vec)
 {
     cv::Mat img_out(_image);
 
     for (unsigned int ii = 0; ii < _kl_vec.size(); ++ii)
-        cv::line(img_out, _kl_vec[ii].getStartPoint(), _kl_vec[ii].getEndPoint(), cv::Scalar(128,128,255), 3);
+        cv::line(img_out, _kl_vec[ii].getStartPoint(), _kl_vec[ii].getEndPoint(), cv::Scalar(128, 128, 255), 3);
 
     return img_out;
 }
diff --git a/src/feature_detector/feature_detector.h b/src/feature_detector/feature_detector.h
index 7616683..0d0325b 100644
--- a/src/feature_detector/feature_detector.h
+++ b/src/feature_detector/feature_detector.h
@@ -24,7 +24,7 @@ typedef cv::Ptr<cv::line_descriptor::BinaryDescriptor> EDDetector;
  */
 enum DETECTOR_TYPE
 {
-    ORB, SIFT, SURF, AKAZE, KAZE, BRISK, MSER, FAST, LSD, ED, AGAST
+    FAST, SIFT, SURF, ORB, BRISK, MSER, GFTT, HARRIS, SBD, KAZE, AKAZE, AGAST, LSD, ED
 };
 
 /**
@@ -34,8 +34,8 @@ inline std::ostream& operator<<(std::ostream& _os, DETECTOR_TYPE _f)
 {
     switch (_f)
     {
-        case ORB:
-            _os << "ORB";
+        case FAST:
+            _os << "FAST";
             break;
         case SIFT:
             _os << "SIFT";
@@ -43,20 +43,32 @@ inline std::ostream& operator<<(std::ostream& _os, DETECTOR_TYPE _f)
         case SURF:
             _os << "SURF";
             break;
-        case AKAZE:
-            _os << "AKAZE";
-            break;
-        case KAZE:
-            _os << "KAZE";
+        case ORB:
+            _os << "ORB";
             break;
         case BRISK:
             _os << "BRISK";
             break;
         case MSER:
-            _os << "MSER";
+            _os << "MSER (Maximally Stable Extremal Region Extractor)";
             break;
-        case FAST:
-            _os << "FAST";
+        case GFTT:
+            _os << "GFTT (Good Features To Track)";
+            break;
+        case HARRIS:
+            _os << "HARRIS (GFTT using Harris)";
+            break;
+        case SBD:
+            _os << "SBD (Simple Blob Detector)";
+            break;
+        case KAZE:
+            _os << "KAZE";
+            break;
+        case AKAZE:
+            _os << "AKAZE";
+            break;
+        case AGAST:
+            _os << "AGAST";
             break;
         case LSD:
             _os << "LSD";
@@ -64,9 +76,6 @@ inline std::ostream& operator<<(std::ostream& _os, DETECTOR_TYPE _f)
         case ED:
             _os << "ED";
             break;
-        case AGAST:
-            _os << "AGAST";
-            break;
         default:
             _os.setstate(std::ios_base::failbit);
     }
@@ -83,27 +92,33 @@ inline DETECTOR_TYPE intToDetectorType(const unsigned int _i)
     switch (_i)
     {
         case 0:
-            return ORB;
+            return FAST;
         case 1:
             return SIFT;
         case 2:
             return SURF;
         case 3:
-            return AKAZE;
+            return ORB;
         case 4:
-            return KAZE;
-        case 5:
             return BRISK;
-        case 6:
+        case 5:
             return MSER;
+        case 6:
+            return GFTT;
         case 7:
-            return FAST;
+            return HARRIS;
         case 8:
-            return LSD;
+            return SBD;
         case 9:
-            return ED;
+            return KAZE;
         case 10:
+            return AKAZE;
+        case 11:
             return AGAST;
+        case 12:
+            return LSD;
+        case 13:
+            return ED;
         default:
             return ORB;
     }
@@ -118,29 +133,22 @@ class CFeature_Detector
 
         CFeature_Detector(const DETECTOR_TYPE& _type);
         CFeature_Detector(const int& _type);
+        CFeature_Detector(void);
         ~CFeature_Detector();
 
-        double getDetectionTime()
-        {
-            return detect_time_;
-        }
-        ;
-
-        bool isLine()
-        {
-            return is_line_;
-        }
-        ;
-        bool isLimited()
-        {
-            return is_limited_;
-        }
-        ;
-        int getKeyPointsLimit()
-        {
-            return keypoints_limit_;
-        }
-        ;
+        std::vector<DETECTOR_TYPE> listDetectors(void);
+
+        bool setDetectorType(const DETECTOR_TYPE& _type);
+        bool setDetectorType(const int& _type);
+
+        double getDetectionTime(void);
+
+        bool isLine(void);
+
+        bool isLimited(void);
+
+        int getKeyPointsLimit(void);
+
         bool limitKeypts(unsigned int _nFeatures);
 
         KeyPointVector detectKeyPoints(const cv::Mat&);
-- 
GitLab