diff --git a/src/examples/feature_detection.cpp b/src/examples/feature_detection.cpp index 63278867d21348c3ef8a020c5507d8297f72068b..24cfb716a9646b1eb9fbc82f2fb5b17881682796 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 baf805b4c9a518a700e4b011df8aa213d0bb850c..e427d9379c44d58fc835b6383eb0e1d60b0a85bd 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 761668311735e0a541fb4639c4e9f7ab916243a0..0d0325ba19ff563ea426d9528b863667fa495de7 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&);