From 6887c2dddee52f1fcb3bb70215fa2730be0ca57b Mon Sep 17 00:00:00 2001 From: angelsantamaria <somriu@gmail.com> Date: Mon, 1 May 2017 14:46:51 +0200 Subject: [PATCH] feature detector almost finished. initialization bug must be fixed --- .cproject | 39 ++++++- src/CMakeLists.txt | 14 +++ src/examples/capture.cpp | 1 - src/examples/feature_detection.cpp | 15 ++- src/feature_detector/feature_detector.cpp | 135 +++++++++++++++++++++- src/feature_detector/feature_detector.h | 105 ++++++++++++++++- src/vision_utils.h | 3 + 7 files changed, 296 insertions(+), 16 deletions(-) diff --git a/.cproject b/.cproject index 5ec25d8..60ad581 100644 --- a/.cproject +++ b/.cproject @@ -18,12 +18,30 @@ <folderInfo id="cdt.managedbuild.toolchain.gnu.base.1819918851.1318867162" name="/" resourcePath=""> <toolChain id="cdt.managedbuild.toolchain.gnu.base.1801134637" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.base"> <targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.GNU_ELF" id="cdt.managedbuild.target.gnu.platform.base.479045570" name="Debug Platform" osList="linux,hpux,aix,qnx" superClass="cdt.managedbuild.target.gnu.platform.base"/> - <builder arguments="-j4" buildPath="${workspace_loc:/vision_utils/build}" command="make" id="cdt.managedbuild.target.gnu.builder.base.1436699615" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.base"/> + <builder arguments="-j4" buildPath="${workspace_loc:/vision_utils/build}" command="make" id="cdt.managedbuild.target.gnu.builder.base.1436699615" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.base"> + <outputEntries> + <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="outputPath" name="build"/> + </outputEntries> + </builder> <tool id="cdt.managedbuild.tool.gnu.archiver.base.401435208" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/> <tool id="cdt.managedbuild.tool.gnu.cpp.compiler.base.1649772065" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.base"> + <option id="gnu.cpp.compiler.option.include.paths.408388440" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath"> + <listOptionValue builtIn="false" value="/usr/include/eigen3"/> + <listOptionValue builtIn="false" value="/usr/include/pcl-1.7"/> + <listOptionValue builtIn="false" value="/opt/ros/kinetic/include"/> + <listOptionValue builtIn="false" value="/home/asantamaria/git/asantamaria_cpp/vision_utils"/> + <listOptionValue builtIn="false" value="/opt/ros/kinetic/include/opencv-3.2.0"/> + </option> <inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.146329834" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/> </tool> <tool id="cdt.managedbuild.tool.gnu.c.compiler.base.593702953" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.base"> + <option id="gnu.c.compiler.option.include.paths.516367413" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath"> + <listOptionValue builtIn="false" value="/usr/include/eigen3"/> + <listOptionValue builtIn="false" value="/usr/include/pcl-1.7"/> + <listOptionValue builtIn="false" value="/opt/ros/kinetic/include"/> + <listOptionValue builtIn="false" value="/home/asantamaria/git/asantamaria_cpp/vision_utils"/> + <listOptionValue builtIn="false" value="/opt/ros/kinetic/include/opencv-3.2.0"/> + </option> <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.392834553" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/> </tool> <tool id="cdt.managedbuild.tool.gnu.c.linker.base.1306470347" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.base"/> @@ -34,6 +52,13 @@ </inputType> </tool> <tool id="cdt.managedbuild.tool.gnu.assembler.base.1501387796" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.base"> + <option id="gnu.both.asm.option.include.paths.849039713" name="Include paths (-I)" superClass="gnu.both.asm.option.include.paths" valueType="includePath"> + <listOptionValue builtIn="false" value="/usr/include/eigen3"/> + <listOptionValue builtIn="false" value="/usr/include/pcl-1.7"/> + <listOptionValue builtIn="false" value="/opt/ros/kinetic/include"/> + <listOptionValue builtIn="false" value="/home/asantamaria/git/asantamaria_cpp/vision_utils"/> + <listOptionValue builtIn="false" value="/opt/ros/kinetic/include/opencv-3.2.0"/> + </option> <inputType id="cdt.managedbuild.tool.gnu.assembler.input.1737692358" superClass="cdt.managedbuild.tool.gnu.assembler.input"/> </tool> </toolChain> @@ -46,9 +71,6 @@ <storageModule moduleId="cdtBuildSystem" version="4.0.0"> <project id="vision_utils.null.883408120" name="vision_utils"/> </storageModule> - <storageModule moduleId="scannerConfiguration"> - <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/> - </storageModule> <storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/> <storageModule moduleId="refreshScope" versionNumber="2"> <configuration configurationName="Default"> @@ -56,4 +78,13 @@ </configuration> </storageModule> <storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/> + <storageModule moduleId="scannerConfiguration"> + <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/> + <scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.base.1819918851;cdt.managedbuild.toolchain.gnu.base.1819918851.1318867162;cdt.managedbuild.tool.gnu.cpp.compiler.base.1649772065;cdt.managedbuild.tool.gnu.cpp.compiler.input.146329834"> + <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/> + </scannerConfigBuildInfo> + <scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.base.1819918851;cdt.managedbuild.toolchain.gnu.base.1819918851.1318867162;cdt.managedbuild.tool.gnu.c.compiler.base.593702953;cdt.managedbuild.tool.gnu.c.compiler.input.392834553"> + <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/> + </scannerConfigBuildInfo> + </storageModule> </cproject> diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d5f0287..e92ae5f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -8,6 +8,20 @@ SET(headers vision_utils.h cam_utils/cam_utils.h feature_detector/feature_detect FIND_PACKAGE(Eigen3 REQUIRED) FIND_PACKAGE(OpenCV REQUIRED) +if (OpenCV_FOUND) + if (${OpenCV_VERSION_MAJOR} GREATER 2) + message("-- [INFO] Found OpenCV ${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR} support") + ADD_DEFINITIONS(-DHAVE_OPENCV_H) + SET(USE_CV true) + else(${OpenCV_VERSION_MAJOR} GREATER 2) + message("[WARN] OpenCV support not installed. Minimum 3.0 version required.") + message("[WARN] Current version ${OpenCV_VERSION_MAJOR}") + endif(${OpenCV_VERSION_MAJOR} GREATER 2) +else(OpenCV_FOUND) + message("[WARN] OpenCV support not installed. Minimum 3.0 version required.") +endif(OpenCV_FOUND) + + # add the necessary include directories INCLUDE_DIRECTORIES(. ${EIGEN3_INCLUDE_DIR} ${OpenCV_INCLUDE_DIRS}) diff --git a/src/examples/capture.cpp b/src/examples/capture.cpp index a35f5d7..a546369 100644 --- a/src/examples/capture.cpp +++ b/src/examples/capture.cpp @@ -1,5 +1,4 @@ // OWN stuff -#include "cam_utils/cam_utils.h" #include "vision_utils.h" // STD stuff diff --git a/src/examples/feature_detection.cpp b/src/examples/feature_detection.cpp index 5d510ee..72925c3 100644 --- a/src/examples/feature_detection.cpp +++ b/src/examples/feature_detection.cpp @@ -1,5 +1,4 @@ // OWN stuff -#include "cam_utils/cam_utils.h" #include "vision_utils.h" // STD stuff @@ -21,14 +20,20 @@ int main(int argc, char *argv[]) cam_fc.getFrame(cam, frame); // Show ORIGINAL frame - cv::namedWindow("Cam Test"); - cam_fc.showFrame("Cam Test", frame); - - // Detect features + cv::namedWindow("Original image"); + cam_fc.showFrame("Original image", frame); + // Detect features (keypoints) + CFeature_Detector detector(ORB); + CFeature_Detector::KeyPointVector keypoints; + keypoints = detector.detectKeyPoints(frame); // Show frame with features + detector.drawKeyFeatures(frame, keypoints); + // Show NEW frame + cv::namedWindow("Detections"); + cam_fc.showFrame("Detections", frame); if (cv::waitKey(30) >= 0) break; diff --git a/src/feature_detector/feature_detector.cpp b/src/feature_detector/feature_detector.cpp index 4d8ed66..760b488 100644 --- a/src/feature_detector/feature_detector.cpp +++ b/src/feature_detector/feature_detector.cpp @@ -1,10 +1,143 @@ #include "feature_detector.h" -CFeature_Detector::CFeature_Detector() +CFeature_Detector::CFeature_Detector(DETECTOR_TYPE _type) : + is_init_(false), is_line_(false), is_limited_(false), keypoints_limit_(-1), detect_time_(0.0) { + init(_type); + + if (!is_init_) + { + std::cerr << "[Feature Detector]: Something went wrong during initialization! Feature Detector not initialized." + << std::endl; + } } CFeature_Detector::~CFeature_Detector() { } +bool CFeature_Detector::init(DETECTOR_TYPE _type) +{ + bool success = false; + + switch (_type) + { + case ORB: + feature_detector_ = cv::ORB::create(); + success = true; + break; + case SIFT: + feature_detector_ = cv::xfeatures2d::SIFT::create(); + success = true; + break; + case SURF: + 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(); + success = true; + break; + case BRISK: + feature_detector_ = cv::BRISK::create(); + success = true; + break; + case MSER: + feature_detector_ = cv::MSER::create(); + success = true; + break; + case FAST: + feature_detector_ = cv::FastFeatureDetector::create(); + success = true; + break; + case AGAST: + feature_detector_ = cv::AgastFeatureDetector::create(); + success = true; + break; + case LSD: + lsd_detector_ = cv::line_descriptor::LSDDetector::createLSDDetector(); + is_line_ = true; + success = true; + break; + case ED: + ed_detector_ = cv::line_descriptor::BinaryDescriptor::createBinaryDescriptor(); + is_line_ = true; + success = true; + break; + } + + if (success) + type_ = _type; + else + std::cerr << "[Feature Detector]: detector_type " << _type << " doesn't exist !" << std::endl; + + return success; +} + +CFeature_Detector::KeyPointVector CFeature_Detector::detectKeyPoints(const cv::Mat& _image) +{ + KeyPointVector kpts; + + feature_detector_->detect(_image, kpts); + + if (this->isLimited()) + { + cv::KeyPointsFilter filter; + filter.retainBest(kpts, this->getKeyPointsLimit()); + } + + return kpts; +} + +CFeature_Detector::KeyLineVector CFeature_Detector::detectKeyLines(const cv::Mat& _image) +{ + KeyLineVector kls; + KeyLineVector kls2; + + if (type_ == LSD) + lsd_detector_->detect(_image, kls, SCALE_FACTOR_LINE_DETECTOR, NUM_OCTAVE_LINE_DETECTOR); + else + ed_detector_->detect(_image, kls2); + kls.insert(kls.end(), kls2.begin(), kls2.end()); + + return kls; +} + +bool CFeature_Detector::limitKeypts(unsigned int _nFeatures) +{ + if (!is_init_) + return false; + + if (_nFeatures > 0) + { + keypoints_limit_ = _nFeatures; + return is_limited_ = true; + } + + return false; +} + +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); + + return img_out; +} + +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); + + return img_out; +} + diff --git a/src/feature_detector/feature_detector.h b/src/feature_detector/feature_detector.h index 01c2c39..ec88477 100644 --- a/src/feature_detector/feature_detector.h +++ b/src/feature_detector/feature_detector.h @@ -1,17 +1,112 @@ #ifndef _FEATURE_DETECTOR_H #define _FEATURE_DETECTOR_H -// Descriptor types -enum DETECTOR_TYPE +// 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/line_descriptor/descriptor.hpp> + +#define SCALE_FACTOR_LINE_DETECTOR 2 +#define NUM_OCTAVE_LINE_DETECTOR 1 + +typedef cv::Ptr<cv::FeatureDetector> FeatureDetectorPtr; +typedef cv::Ptr<cv::line_descriptor::LSDDetector> LSDDetector; +typedef cv::Ptr<cv::line_descriptor::BinaryDescriptor> EDDetector; + +/** + * brief Descriptor types + */ +enum DETECTOR_TYPE { ORB, SIFT, SURF, AKAZE, KAZE, BRISK, MSER, FAST, LSD, ED, AGAST }; + +/** + * \brief Stream operator for the detector flags. + */ +inline std::ostream& operator<<(std::ostream& _os, DETECTOR_TYPE _f) { - ORB, SIFT, SURF, AKAZE, KAZE, BRISK, MSER, FAST, LSD, ED, AGAST -}; + switch (_f) + { + case ORB: + _os << "ORB"; + break; + case SIFT: + _os << "SIFT"; + break; + case SURF: + _os << "SURF"; + break; + case AKAZE: + _os << "AKAZE"; + break; + case KAZE: + _os << "KAZE"; + break; + case BRISK: + _os << "BRISK"; + break; + case MSER: + _os << "MSER"; + break; + case FAST: + _os << "FAST"; + break; + case LSD: + _os << "LSD"; + break; + case ED: + _os << "ED"; + break; + case AGAST: + _os << "AGAST"; + break; + default: + _os.setstate(std::ios_base::failbit); + } + return _os; +} class CFeature_Detector { public: - CFeature_Detector(); + + typedef std::vector<cv::KeyPoint> KeyPointVector; + typedef std::vector<cv::line_descriptor::KeyLine> KeyLineVector; + + bool getDetectionTime() { return detect_time_; }; + + bool isLine() { return is_line_; }; + bool isLimited() { return is_limited_; }; + int getKeyPointsLimit() { return keypoints_limit_; }; + bool limitKeypts(unsigned int _nFeatures); + + CFeature_Detector(DETECTOR_TYPE _type); ~CFeature_Detector(); + + 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 ); + + private: + + DETECTOR_TYPE type_; + + bool is_init_; + bool is_line_; + bool is_limited_; + unsigned int keypoints_limit_; + + double detect_time_; + + FeatureDetectorPtr feature_detector_; + LSDDetector lsd_detector_; + EDDetector ed_detector_; + + bool init(DETECTOR_TYPE _type); }; #endif diff --git a/src/vision_utils.h b/src/vision_utils.h index de32e48..57df788 100644 --- a/src/vision_utils.h +++ b/src/vision_utils.h @@ -1,6 +1,9 @@ #ifndef _VISION_UTILS_H #define _VISION_UTILS_H +#include "cam_utils/cam_utils.h" +#include "feature_detector/feature_detector.h" + class CVision_Utils { public: -- GitLab