Skip to content
Snippets Groups Projects
Commit 652927ff authored by angelsantamaria's avatar angelsantamaria
Browse files

Reduced hardcoded ENUM. Added a macro to generate it also as string

parent 623c9c8f
No related branches found
No related tags found
No related merge requests found
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
// STD stuff // STD stuff
#include <string> #include <string>
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
CFeature_Detector detector; CFeature_Detector detector;
...@@ -71,3 +72,6 @@ int main(int argc, char *argv[]) ...@@ -71,3 +72,6 @@ int main(int argc, char *argv[])
cv::destroyAllWindows(); cv::destroyAllWindows();
} }
#include "feature_detector.h" #include "feature_detector.h"
CFeature_Detector::CFeature_Detector(const DETECTOR_TYPE& _type) : 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); is_init_ = init(_type);
...@@ -13,7 +13,7 @@ CFeature_Detector::CFeature_Detector(const DETECTOR_TYPE& _type) : ...@@ -13,7 +13,7 @@ CFeature_Detector::CFeature_Detector(const DETECTOR_TYPE& _type) :
} }
CFeature_Detector::CFeature_Detector(const int&_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)); is_init_ = init(intToDetectorType(_type));
...@@ -25,7 +25,7 @@ CFeature_Detector::CFeature_Detector(const int&_type) : ...@@ -25,7 +25,7 @@ CFeature_Detector::CFeature_Detector(const int&_type) :
} }
CFeature_Detector::CFeature_Detector(void) : 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) ...@@ -37,7 +37,8 @@ std::vector<DETECTOR_TYPE> CFeature_Detector::listDetectors(void)
{ {
std::vector<DETECTOR_TYPE> list; 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)); list.push_back(static_cast<DETECTOR_TYPE>(ii));
} }
...@@ -46,13 +47,13 @@ std::vector<DETECTOR_TYPE> CFeature_Detector::listDetectors(void) ...@@ -46,13 +47,13 @@ std::vector<DETECTOR_TYPE> CFeature_Detector::listDetectors(void)
bool CFeature_Detector::setDetectorType(const DETECTOR_TYPE& _type) bool CFeature_Detector::setDetectorType(const DETECTOR_TYPE& _type)
{ {
is_init_ = init( _type ); is_init_ = init(_type);
return is_init_; return is_init_;
} }
bool CFeature_Detector::setDetectorType(const int& _type) bool CFeature_Detector::setDetectorType(const int& _type)
{ {
is_init_ = init( intToDetectorType(_type) ); is_init_ = init(intToDetectorType(_type));
return is_init_; return is_init_;
} }
...@@ -79,10 +80,11 @@ int CFeature_Detector::getKeyPointsLimit(void) ...@@ -79,10 +80,11 @@ int CFeature_Detector::getKeyPointsLimit(void)
bool CFeature_Detector::init(DETECTOR_TYPE _type) bool CFeature_Detector::init(DETECTOR_TYPE _type)
{ {
if (is_init_) 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; bool success = false;
// TODO: Set parameters for each detector type
switch (_type) switch (_type)
{ {
case FAST: case FAST:
...@@ -110,11 +112,11 @@ bool CFeature_Detector::init(DETECTOR_TYPE _type) ...@@ -110,11 +112,11 @@ bool CFeature_Detector::init(DETECTOR_TYPE _type)
success = true; success = true;
break; break;
case GFTT: 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; success = true;
break; break;
case HARRIS: 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; success = true;
break; break;
case SBD: case SBD:
...@@ -143,6 +145,9 @@ bool CFeature_Detector::init(DETECTOR_TYPE _type) ...@@ -143,6 +145,9 @@ bool CFeature_Detector::init(DETECTOR_TYPE _type)
is_line_ = true; is_line_ = true;
success = true; success = true;
break; break;
case __DELIM__:
success = false;
break;
} }
if (success) if (success)
...@@ -156,15 +161,19 @@ bool CFeature_Detector::init(DETECTOR_TYPE _type) ...@@ -156,15 +161,19 @@ bool CFeature_Detector::init(DETECTOR_TYPE _type)
CFeature_Detector::KeyPointVector CFeature_Detector::detectKeyPoints(const cv::Mat& _image) CFeature_Detector::KeyPointVector CFeature_Detector::detectKeyPoints(const cv::Mat& _image)
{ {
if (!is_init_) 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; KeyPointVector kpts;
clock_t tStart = clock(); clock_t tStart = clock();
feature_detector_->detect(_image, kpts); feature_detector_->detect(_image, kpts, mask_);
detect_time_ = (double)(clock() - tStart) / CLOCKS_PER_SEC; detect_time_ = (double)(clock() - tStart) / CLOCKS_PER_SEC;
if (this->isLimited()) if (isLimited())
{ {
cv::KeyPointsFilter filter; cv::KeyPointsFilter filter;
filter.retainBest(kpts, this->getKeyPointsLimit()); filter.retainBest(kpts, this->getKeyPointsLimit());
...@@ -176,23 +185,27 @@ CFeature_Detector::KeyPointVector CFeature_Detector::detectKeyPoints(const cv::M ...@@ -176,23 +185,27 @@ CFeature_Detector::KeyPointVector CFeature_Detector::detectKeyPoints(const cv::M
CFeature_Detector::KeyLineVector CFeature_Detector::detectKeyLines(const cv::Mat& _image) CFeature_Detector::KeyLineVector CFeature_Detector::detectKeyLines(const cv::Mat& _image)
{ {
if (!is_init_) 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 kls;
KeyLineVector kls2; 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(); clock_t tStart = clock();
if (type_ == LSD) 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 else
ed_detector_->detect(_image, kls2); ed_detector_->detect(_image, kls2, mask_);
detect_time_ = (double)(clock() - tStart) / CLOCKS_PER_SEC; detect_time_ = (double)(clock() - tStart) / CLOCKS_PER_SEC;
kls.insert(kls.end(), kls2.begin(), kls2.end()); kls.insert(kls.end(), kls2.begin(), kls2.end());
return kls; return kls;
} }
bool CFeature_Detector::limitKeypts(unsigned int _nFeatures) bool CFeature_Detector::setLimitKeypts(unsigned int _nFeatures)
{ {
if (_nFeatures > 0) if (_nFeatures > 0)
{ {
...@@ -203,7 +216,7 @@ bool CFeature_Detector::limitKeypts(unsigned int _nFeatures) ...@@ -203,7 +216,7 @@ bool CFeature_Detector::limitKeypts(unsigned int _nFeatures)
return false; 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); cv::Mat img_out(_image);
...@@ -213,8 +226,7 @@ cv::Mat CFeature_Detector::drawKeyFeatures(const cv::Mat& _image, const std::vec ...@@ -213,8 +226,7 @@ cv::Mat CFeature_Detector::drawKeyFeatures(const cv::Mat& _image, const std::vec
return img_out; return img_out;
} }
cv::Mat CFeature_Detector::drawKeyFeatures(const cv::Mat& _image, cv::Mat CFeature_Detector::drawKeyFeatures(const cv::Mat& _image, const KeyLineVector& _kl_vec)
const std::vector<cv::line_descriptor::KeyLine>& _kl_vec)
{ {
cv::Mat img_out(_image); cv::Mat img_out(_image);
...@@ -224,3 +236,15 @@ cv::Mat CFeature_Detector::drawKeyFeatures(const cv::Mat& _image, ...@@ -224,3 +236,15 @@ cv::Mat CFeature_Detector::drawKeyFeatures(const cv::Mat& _image,
return img_out; 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;
}
...@@ -20,110 +20,45 @@ typedef cv::Ptr<cv::line_descriptor::LSDDetector> LSDDetector; ...@@ -20,110 +20,45 @@ typedef cv::Ptr<cv::line_descriptor::LSDDetector> LSDDetector;
typedef cv::Ptr<cv::line_descriptor::BinaryDescriptor> EDDetector; 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 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. * \brief Stream operator for the detector flags.
*/ */
inline std::ostream& operator<<(std::ostream& _os, DETECTOR_TYPE _f) inline std::ostream& operator<<(std::ostream& _os, DETECTOR_TYPE _f)
{ {
switch (_f) _os << DETECTOR_TYPE_STRING[_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);
}
return _os; return _os;
} }
/** /**
* \brief Convert an integer to its corresponding descriptor flag. * \brief Main feature detector class
*
* By default return L2.
*/ */
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 class CFeature_Detector
{ {
public: public:
...@@ -131,48 +66,97 @@ class CFeature_Detector ...@@ -131,48 +66,97 @@ class CFeature_Detector
typedef std::vector<cv::KeyPoint> KeyPointVector; typedef std::vector<cv::KeyPoint> KeyPointVector;
typedef std::vector<cv::line_descriptor::KeyLine> KeyLineVector; typedef std::vector<cv::line_descriptor::KeyLine> KeyLineVector;
/**
* \brief Constructor
*/
CFeature_Detector(const DETECTOR_TYPE& _type); CFeature_Detector(const DETECTOR_TYPE& _type);
CFeature_Detector(const int& _type); CFeature_Detector(const int& _type);
CFeature_Detector(void); CFeature_Detector(void);
/**
* \brief Destructor
*/
~CFeature_Detector(); ~CFeature_Detector();
/**
* \brief List the defined detector types
*/
std::vector<DETECTOR_TYPE> listDetectors(void); std::vector<DETECTOR_TYPE> listDetectors(void);
/**
* \brief Set detector type
*/
bool setDetectorType(const DETECTOR_TYPE& _type); bool setDetectorType(const DETECTOR_TYPE& _type);
bool setDetectorType(const int& _type); bool setDetectorType(const int& _type);
/**
* \brief Get detection duration
*/
double getDetectionTime(void); double getDetectionTime(void);
/**
* \brief Inform if the detector searches points or lines
*/
bool isLine(void); bool isLine(void);
/**
* \brief Inform if there is a maximum number of features to be detected
*/
bool isLimited(void); bool isLimited(void);
/**
* \brief Get number of maximum keypoints allowed
*/
int getKeyPointsLimit(void); 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&); KeyPointVector detectKeyPoints(const cv::Mat&);
KeyLineVector detectKeyLines(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: private:
DETECTOR_TYPE type_; DETECTOR_TYPE type_;
// Flags
bool is_init_; bool is_init_;
bool is_line_; bool is_line_;
bool is_limited_; bool is_limited_;
unsigned int keypoints_limit_;
double detect_time_; unsigned int keypoints_limit_; // Max. number of keypoints (saturation)
FeatureDetectorPtr feature_detector_; double detect_time_; // Detection time
LSDDetector lsd_detector_;
EDDetector ed_detector_;
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); 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 #endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment