diff --git a/src/examples/feature_detection.cpp b/src/examples/feature_detection.cpp
index 24cfb716a9646b1eb9fbc82f2fb5b17881682796..cdb43ef041721ac51402141ff080c16021c83ef4 100644
--- a/src/examples/feature_detection.cpp
+++ b/src/examples/feature_detection.cpp
@@ -4,6 +4,7 @@
 // STD stuff
 #include <string>
 
+
 int main(int argc, char *argv[])
 {
     CFeature_Detector detector;
@@ -71,3 +72,6 @@ int main(int argc, char *argv[])
 
     cv::destroyAllWindows();
 }
+
+
+
diff --git a/src/feature_detector/feature_detector.cpp b/src/feature_detector/feature_detector.cpp
index e427d9379c44d58fc835b6383eb0e1d60b0a85bd..66b408b4597614db3f957e7eae2379dbbd4c6e36 100644
--- a/src/feature_detector/feature_detector.cpp
+++ b/src/feature_detector/feature_detector.cpp
@@ -1,7 +1,7 @@
 #include "feature_detector.h"
 
 CFeature_Detector::CFeature_Detector(const DETECTOR_TYPE& _type) :
-        is_init_(false), is_line_(false), is_limited_(false), keypoints_limit_(-1), detect_time_(0.0)
+        type_(__DELIM__), is_init_(false), is_line_(false), is_limited_(false), keypoints_limit_(-1), detect_time_(0.0)
 {
     is_init_ = init(_type);
 
@@ -13,7 +13,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)
+        type_(__DELIM__), is_init_(false), is_line_(false), is_limited_(false), keypoints_limit_(-1), detect_time_(0.0)
 {
     is_init_ = init(intToDetectorType(_type));
 
@@ -25,7 +25,7 @@ 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)
+        type_(__DELIM__), is_init_(false), is_line_(false), is_limited_(false), keypoints_limit_(-1), detect_time_(0.0)
 {
 }
 
@@ -37,7 +37,8 @@ std::vector<DETECTOR_TYPE> CFeature_Detector::listDetectors(void)
 {
     std::vector<DETECTOR_TYPE> list;
 
-    for(int ii = 0; ii < ED+1; ii++){
+    for (int ii = 0; ii < ED + 1; ii++)
+    {
         list.push_back(static_cast<DETECTOR_TYPE>(ii));
     }
 
@@ -46,13 +47,13 @@ std::vector<DETECTOR_TYPE> CFeature_Detector::listDetectors(void)
 
 bool CFeature_Detector::setDetectorType(const DETECTOR_TYPE& _type)
 {
-    is_init_ = init( _type );
+    is_init_ = init(_type);
     return is_init_;
 }
 
 bool CFeature_Detector::setDetectorType(const int& _type)
 {
-    is_init_ = init( intToDetectorType(_type) );
+    is_init_ = init(intToDetectorType(_type));
     return is_init_;
 }
 
@@ -79,10 +80,11 @@ int CFeature_Detector::getKeyPointsLimit(void)
 bool CFeature_Detector::init(DETECTOR_TYPE _type)
 {
     if (is_init_)
-         std::cerr << "[CFeature_Detector::init]: Detector already initialized." << std::endl;
+        std::cerr << "[CFeature_Detector::init]: Detector already initialized." << std::endl;
 
     bool success = false;
 
+    // TODO: Set parameters for each detector type
     switch (_type)
     {
         case FAST:
@@ -110,11 +112,11 @@ bool CFeature_Detector::init(DETECTOR_TYPE _type)
             success = true;
             break;
         case GFTT:
-            feature_detector_ = cv::GFTTDetector::create(1000,0.01,1.0,3,false,0.04);
+            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);
+            feature_detector_ = cv::GFTTDetector::create(1000, 0.01, 1.0, 3, true, 0.04);
             success = true;
             break;
         case SBD:
@@ -143,6 +145,9 @@ bool CFeature_Detector::init(DETECTOR_TYPE _type)
             is_line_ = true;
             success = true;
             break;
+        case __DELIM__:
+            success = false;
+            break;
     }
 
     if (success)
@@ -156,15 +161,19 @@ 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;
+        std::cerr << "[CFeature_Detector::detectKeyPoints]: Detector non initialized." << std::endl;
+
+    // TODO: Set a clever mask to reduce image search
+    if (mask_.empty())
+        mask_ = cv::Mat::ones(_image.size(), CV_8U);
 
     KeyPointVector kpts;
 
     clock_t tStart = clock();
-    feature_detector_->detect(_image, kpts);
+    feature_detector_->detect(_image, kpts, mask_);
     detect_time_ = (double)(clock() - tStart) / CLOCKS_PER_SEC;
 
-    if (this->isLimited())
+    if (isLimited())
     {
         cv::KeyPointsFilter filter;
         filter.retainBest(kpts, this->getKeyPointsLimit());
@@ -176,23 +185,27 @@ 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;
+        std::cerr << "[CFeature_Detector::detectKeyLines]: Detector non initialized." << std::endl;
 
     KeyLineVector kls;
     KeyLineVector kls2;
 
+    // TODO: Set a clever mask to reduce image search
+    if (mask_.empty())
+        mask_ = cv::Mat::ones(_image.size(), CV_8U);
+
     clock_t tStart = clock();
     if (type_ == LSD)
-        lsd_detector_->detect(_image, kls, SCALE_FACTOR_LINE_DETECTOR, NUM_OCTAVE_LINE_DETECTOR);
+        lsd_detector_->detect(_image, kls, SCALE_FACTOR_LINE_DETECTOR, NUM_OCTAVE_LINE_DETECTOR, mask_);
     else
-        ed_detector_->detect(_image, kls2);
+        ed_detector_->detect(_image, kls2, mask_);
     detect_time_ = (double)(clock() - tStart) / CLOCKS_PER_SEC;
     kls.insert(kls.end(), kls2.begin(), kls2.end());
 
     return kls;
 }
 
-bool CFeature_Detector::limitKeypts(unsigned int _nFeatures)
+bool CFeature_Detector::setLimitKeypts(unsigned int _nFeatures)
 {
     if (_nFeatures > 0)
     {
@@ -203,7 +216,7 @@ 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 KeyPointVector& _kp_vec)
 {
     cv::Mat img_out(_image);
 
@@ -213,8 +226,7 @@ cv::Mat CFeature_Detector::drawKeyFeatures(const cv::Mat& _image, const std::vec
     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 KeyLineVector& _kl_vec)
 {
     cv::Mat img_out(_image);
 
@@ -224,3 +236,15 @@ cv::Mat CFeature_Detector::drawKeyFeatures(const cv::Mat& _image,
     return img_out;
 }
 
+DETECTOR_TYPE CFeature_Detector::intToDetectorType(const unsigned int _i)
+{
+    DETECTOR_TYPE type;
+
+    for (unsigned int ii = 0; ii < __DELIM__; ii++)
+    {
+        if (ii == _i)
+            type = static_cast<DETECTOR_TYPE>(ii);
+    }
+
+    return type;
+}
diff --git a/src/feature_detector/feature_detector.h b/src/feature_detector/feature_detector.h
index 0d0325ba19ff563ea426d9528b863667fa495de7..942d3d3fa165c614a532f82b6184d7da381e47d7 100644
--- a/src/feature_detector/feature_detector.h
+++ b/src/feature_detector/feature_detector.h
@@ -20,110 +20,45 @@ typedef cv::Ptr<cv::line_descriptor::LSDDetector> LSDDetector;
 typedef cv::Ptr<cv::line_descriptor::BinaryDescriptor> EDDetector;
 
 /**
- * brief Descriptor types
+ * \brief MACROS to generate all detector types and their corresponding strings
  */
+#define FOREACH_DETECTOR(DETECTOR) \
+        DETECTOR(FAST)   \
+        DETECTOR(SIFT)  \
+        DETECTOR(SURF)   \
+        DETECTOR(ORB)  \
+        DETECTOR(BRISK)  \
+        DETECTOR(MSER)  \
+        DETECTOR(GFTT)  \
+        DETECTOR(HARRIS)  \
+        DETECTOR(SBD)  \
+        DETECTOR(KAZE)  \
+        DETECTOR(AKAZE)  \
+        DETECTOR(AGAST)  \
+        DETECTOR(LSD)  \
+        DETECTOR(ED)  \
+        DETECTOR(__DELIM__)  \
+
+#define GENERATE_ENUM(ENUM) ENUM,
+#define GENERATE_STRING(STRING) #STRING,
 enum DETECTOR_TYPE
 {
-    FAST, SIFT, SURF, ORB, BRISK, MSER, GFTT, HARRIS, SBD, KAZE, AKAZE, AGAST, LSD, ED
+    FOREACH_DETECTOR(GENERATE_ENUM)
 };
+static const char *DETECTOR_TYPE_STRING[] = {FOREACH_DETECTOR(GENERATE_STRING)};
 
 /**
  * \brief Stream operator for the detector flags.
  */
 inline std::ostream& operator<<(std::ostream& _os, DETECTOR_TYPE _f)
 {
-    switch (_f)
-    {
-        case FAST:
-            _os << "FAST";
-            break;
-        case SIFT:
-            _os << "SIFT";
-            break;
-        case SURF:
-            _os << "SURF";
-            break;
-        case ORB:
-            _os << "ORB";
-            break;
-        case BRISK:
-            _os << "BRISK";
-            break;
-        case MSER:
-            _os << "MSER (Maximally Stable Extremal Region Extractor)";
-            break;
-        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";
-            break;
-        case ED:
-            _os << "ED";
-            break;
-        default:
-            _os.setstate(std::ios_base::failbit);
-    }
+    _os << DETECTOR_TYPE_STRING[_f];
     return _os;
 }
 
 /**
- * \brief Convert an integer to its corresponding descriptor flag.
- *
- * By default return L2.
+ * \brief Main feature detector class
  */
-inline DETECTOR_TYPE intToDetectorType(const unsigned int _i)
-{
-    switch (_i)
-    {
-        case 0:
-            return FAST;
-        case 1:
-            return SIFT;
-        case 2:
-            return SURF;
-        case 3:
-            return ORB;
-        case 4:
-            return BRISK;
-        case 5:
-            return MSER;
-        case 6:
-            return GFTT;
-        case 7:
-            return HARRIS;
-        case 8:
-            return SBD;
-        case 9:
-            return KAZE;
-        case 10:
-            return AKAZE;
-        case 11:
-            return AGAST;
-        case 12:
-            return LSD;
-        case 13:
-            return ED;
-        default:
-            return ORB;
-    }
-}
-
 class CFeature_Detector
 {
     public:
@@ -131,48 +66,97 @@ class CFeature_Detector
         typedef std::vector<cv::KeyPoint> KeyPointVector;
         typedef std::vector<cv::line_descriptor::KeyLine> KeyLineVector;
 
+        /**
+         * \brief Constructor
+         */
         CFeature_Detector(const DETECTOR_TYPE& _type);
         CFeature_Detector(const int& _type);
         CFeature_Detector(void);
+
+        /**
+         * \brief Destructor
+         */
         ~CFeature_Detector();
 
+        /**
+         * \brief List the defined detector types
+         */
         std::vector<DETECTOR_TYPE> listDetectors(void);
 
+        /**
+         * \brief Set detector type
+         */
         bool setDetectorType(const DETECTOR_TYPE& _type);
         bool setDetectorType(const int& _type);
 
+        /**
+         * \brief Get detection duration
+         */
         double getDetectionTime(void);
 
+        /**
+         * \brief Inform if the detector searches points or lines
+         */
         bool isLine(void);
 
+        /**
+         * \brief Inform if there is a maximum number of features to be detected
+         */
         bool isLimited(void);
 
+        /**
+         * \brief Get number of maximum keypoints allowed
+         */
         int getKeyPointsLimit(void);
 
-        bool limitKeypts(unsigned int _nFeatures);
+        /**
+         * \brief Set number of maximum keypoints allowed
+         */
+        bool setLimitKeypts(unsigned int _nFeatures);
 
+        /**
+         * \brief Detect features (points or lines)
+         */
         KeyPointVector detectKeyPoints(const cv::Mat&);
         KeyLineVector detectKeyLines(const cv::Mat&);
 
-        cv::Mat drawKeyFeatures(const cv::Mat& _image, const std::vector<cv::KeyPoint>& _kp_vec);
-        cv::Mat drawKeyFeatures(const cv::Mat& _image, const std::vector<cv::line_descriptor::KeyLine>& _kl_vec);
+        /**
+         * \brief Draw detected features
+         */
+        cv::Mat drawKeyFeatures(const cv::Mat& _image, const KeyPointVector& _kp_vec);
+        cv::Mat drawKeyFeatures(const cv::Mat& _image, const KeyLineVector& _kl_vec);
 
     private:
 
         DETECTOR_TYPE type_;
 
+        // Flags
         bool is_init_;
         bool is_line_;
         bool is_limited_;
-        unsigned int keypoints_limit_;
 
-        double detect_time_;
+        unsigned int keypoints_limit_; // Max. number of keypoints (saturation)
 
-        FeatureDetectorPtr feature_detector_;
-        LSDDetector lsd_detector_;
-        EDDetector ed_detector_;
+        double detect_time_; // Detection time
 
+        cv::Mat mask_; // Mask to reduce image search
+
+        FeatureDetectorPtr feature_detector_; // Feature point detectors
+        LSDDetector lsd_detector_; // Feature line detector
+        EDDetector ed_detector_; // Feature line detector
+
+        /**
+         * \brief Initialize detector
+         */
         bool init(DETECTOR_TYPE _type);
+
+        /**
+         * \brief Convert an integer to its corresponding descriptor flag.
+         *
+         * By default return ORB.
+         */
+        DETECTOR_TYPE intToDetectorType(const unsigned int _i);
+
 };
 
 #endif