From 8b44cd445c7ccc856b6ecdca5939668d13719896 Mon Sep 17 00:00:00 2001 From: asantamaria <asantamaria@iri.upc.edu> Date: Thu, 27 Jul 2017 19:57:09 +0200 Subject: [PATCH] Added descriptors --- .cproject | 71 ++++----- .settings/language.settings.xml | 6 +- src/examples/CMakeLists.txt | 6 +- ...re_detection.cpp => feature_detectors.cpp} | 4 +- .../feature_detectors_and_descriptors.cpp | 91 +++++++++++ src/feature_descriptor/feature_descriptor.cpp | 149 +++++++++++++++++- src/feature_descriptor/feature_descriptor.h | 116 ++++++++++++-- src/feature_detector/feature_detector.cpp | 60 +++---- src/feature_detector/feature_detector.h | 23 +-- src/vision_utils.h | 1 + 10 files changed, 430 insertions(+), 97 deletions(-) rename src/examples/{feature_detection.cpp => feature_detectors.cpp} (94%) create mode 100644 src/examples/feature_detectors_and_descriptors.cpp diff --git a/.cproject b/.cproject index 60ad581..83fa9b6 100644 --- a/.cproject +++ b/.cproject @@ -1,8 +1,8 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage"> <storageModule moduleId="org.eclipse.cdt.core.settings"> - <cconfiguration id="cdt.managedbuild.toolchain.gnu.base.1819918851"> - <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.toolchain.gnu.base.1819918851" moduleId="org.eclipse.cdt.core.settings" name="Default"> + <cconfiguration id="cdt.managedbuild.toolchain.gnu.base.1736073220"> + <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.toolchain.gnu.base.1736073220" moduleId="org.eclipse.cdt.core.settings" name="Default"> <externalSettings/> <extensions> <extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/> @@ -14,52 +14,36 @@ </extensions> </storageModule> <storageModule moduleId="cdtBuildSystem" version="4.0.0"> - <configuration buildProperties="" description="" id="cdt.managedbuild.toolchain.gnu.base.1819918851" name="Default" parent="org.eclipse.cdt.build.core.emptycfg"> - <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"> - <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"/> + <configuration artifactName="${ProjName}" buildProperties="" description="" id="cdt.managedbuild.toolchain.gnu.base.1736073220" name="Default" parent="org.eclipse.cdt.build.core.emptycfg"> + <folderInfo id="cdt.managedbuild.toolchain.gnu.base.1736073220.1390770886" name="/" resourcePath=""> + <toolChain id="cdt.managedbuild.toolchain.gnu.base.17239869" 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.298476915" name="Debug Platform" osList="linux,hpux,aix,qnx" superClass="cdt.managedbuild.target.gnu.platform.base"/> + <builder buildPath="${workspace_loc:/vision_utils/build}" id="cdt.managedbuild.target.gnu.builder.base.1164932087" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="cdt.managedbuild.target.gnu.builder.base"/> + <tool id="cdt.managedbuild.tool.gnu.archiver.base.1361884017" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/> + <tool id="cdt.managedbuild.tool.gnu.cpp.compiler.base.1526891046" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.base"> + <option id="gnu.cpp.compiler.option.include.paths.2083804297" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath"> + <listOptionValue builtIn="false" value="/usr/include/opencv2"/> </option> - <inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.146329834" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/> + <inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1116382079" 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"/> + <tool id="cdt.managedbuild.tool.gnu.c.compiler.base.1459107576" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.base"> + <option id="gnu.c.compiler.option.include.paths.770636594" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath"> + <listOptionValue builtIn="false" value="/usr/include/opencv2"/> </option> - <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.392834553" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/> + <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1695301683" 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"/> - <tool id="cdt.managedbuild.tool.gnu.cpp.linker.base.537733253" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.base"> - <inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.1810403800" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input"> + <tool id="cdt.managedbuild.tool.gnu.c.linker.base.343771141" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.base"/> + <tool id="cdt.managedbuild.tool.gnu.cpp.linker.base.439006778" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.base"> + <inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.258372498" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input"> <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/> <additionalInput kind="additionalinput" paths="$(LIBS)"/> </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"/> + <tool id="cdt.managedbuild.tool.gnu.assembler.base.1551405489" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.base"> + <option id="gnu.both.asm.option.include.paths.458395641" name="Include paths (-I)" superClass="gnu.both.asm.option.include.paths" valueType="includePath"> + <listOptionValue builtIn="false" value="/usr/include/opencv2"/> </option> - <inputType id="cdt.managedbuild.tool.gnu.assembler.input.1737692358" superClass="cdt.managedbuild.tool.gnu.assembler.input"/> + <inputType id="cdt.managedbuild.tool.gnu.assembler.input.1370134559" superClass="cdt.managedbuild.tool.gnu.assembler.input"/> </tool> </toolChain> </folderInfo> @@ -69,7 +53,7 @@ </cconfiguration> </storageModule> <storageModule moduleId="cdtBuildSystem" version="4.0.0"> - <project id="vision_utils.null.883408120" name="vision_utils"/> + <project id="vision_utils.null.1875601072" name="vision_utils"/> </storageModule> <storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/> <storageModule moduleId="refreshScope" versionNumber="2"> @@ -80,11 +64,18 @@ <storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/> <storageModule moduleId="scannerConfiguration"> <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/> + <scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.base.1736073220;cdt.managedbuild.toolchain.gnu.base.1736073220.1390770886;cdt.managedbuild.tool.gnu.c.compiler.base.1459107576;cdt.managedbuild.tool.gnu.c.compiler.input.1695301683"> + <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.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> + <scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.base.1736073220;cdt.managedbuild.toolchain.gnu.base.1736073220.1390770886;cdt.managedbuild.tool.gnu.cpp.compiler.base.1526891046;cdt.managedbuild.tool.gnu.cpp.compiler.input.1116382079"> + <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/> + </scannerConfigBuildInfo> </storageModule> + <storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/> </cproject> diff --git a/.settings/language.settings.xml b/.settings/language.settings.xml index 22477b0..ca971ab 100644 --- a/.settings/language.settings.xml +++ b/.settings/language.settings.xml @@ -1,11 +1,11 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <project> - <configuration id="cdt.managedbuild.toolchain.gnu.base.1819918851" name="Default"> + <configuration id="cdt.managedbuild.toolchain.gnu.base.1736073220" name="Default"> <extension point="org.eclipse.cdt.core.LanguageSettingsProvider"> <provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/> <provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/> - <provider copy-of="extension" id="org.eclipse.cdt.managedbuilder.core.GCCBuildCommandParser"/> - <provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="1476617952823822664" id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true"> + <provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuildCommandParser" id="org.eclipse.cdt.managedbuilder.core.GCCBuildCommandParser" keep-relative-paths="false" name="CDT GCC Build Output Parser" parameter="(g?cc)|([gc]\+\+)|(clang)" prefer-non-shared="true"/> + <provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="1504749124108071272" id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true"> <language-scope id="org.eclipse.cdt.core.gcc"/> <language-scope id="org.eclipse.cdt.core.g++"/> </provider> diff --git a/src/examples/CMakeLists.txt b/src/examples/CMakeLists.txt index c5993b2..35b3b32 100644 --- a/src/examples/CMakeLists.txt +++ b/src/examples/CMakeLists.txt @@ -1,7 +1,9 @@ # create an example application ADD_EXECUTABLE(capture capture.cpp) -ADD_EXECUTABLE(feature_detection feature_detection.cpp) +ADD_EXECUTABLE(feature_detectors feature_detectors.cpp) +ADD_EXECUTABLE(feature_detectors_and_descriptors feature_detectors_and_descriptors.cpp) # link necessary libraries TARGET_LINK_LIBRARIES(capture vision_utils) -TARGET_LINK_LIBRARIES(feature_detection vision_utils) \ No newline at end of file +TARGET_LINK_LIBRARIES(feature_detectors vision_utils) +TARGET_LINK_LIBRARIES(feature_detectors_and_descriptors vision_utils) \ No newline at end of file diff --git a/src/examples/feature_detection.cpp b/src/examples/feature_detectors.cpp similarity index 94% rename from src/examples/feature_detection.cpp rename to src/examples/feature_detectors.cpp index cdb43ef..de818e0 100644 --- a/src/examples/feature_detection.cpp +++ b/src/examples/feature_detectors.cpp @@ -8,7 +8,7 @@ int main(int argc, char *argv[]) { CFeature_Detector detector; - std::vector<DETECTOR_TYPE> detectors_list; + std::vector<Detector::Type> detectors_list; detectors_list = detector.listDetectors(); std::cout << "----------------------------------------" << std::endl; @@ -19,7 +19,7 @@ int main(int argc, char *argv[]) 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?: "; + std::cout << std::endl << "Which DETECTOR do you want to test?: "; int feat_type; std::cin >> feat_type; detector.setDetectorType(feat_type); diff --git a/src/examples/feature_detectors_and_descriptors.cpp b/src/examples/feature_detectors_and_descriptors.cpp new file mode 100644 index 0000000..3c93703 --- /dev/null +++ b/src/examples/feature_detectors_and_descriptors.cpp @@ -0,0 +1,91 @@ +// OWN stuff +#include "vision_utils.h" + +// STD stuff +#include <string> + + +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 detectors and descriptors example |" << std::endl; + std::cout << "---------------------------------------------------------" << std::endl; + std::cout << std::endl; + + for (unsigned int ii=0; ii<detectors_list.size(); ii++) + { + if ( (detectors_list[ii]!= Detector::LSD) && (detectors_list[ii] != Detector::ED) ) + std::cout << "[" << ii << "]: " << detectors_list[ii] << std::endl; + } + + std::cout << std::endl << "Which DETECTOR do you want to test?: "; + int feat_type; + std::cin >> feat_type; + detector.setDetectorType(feat_type); + + CFeature_Descriptor descriptor; + std::vector<Descriptor::Type> descriptor_list; + descriptor_list = descriptor.listDescriptors(); + + for (unsigned int ii=0; ii<descriptor_list.size(); ii++) + std::cout << "[" << ii << "]: " << descriptor_list[ii] << std::endl; + + std::cout << std::endl << "Which DESCRIPTOR do you want to test?: "; + int desc_type; + std::cin >> desc_type; + descriptor.setDescriptorType(desc_type); + std::cout << std::endl << "Testing: " << detectors_list[feat_type] << " + " << descriptor_list[feat_type] << " (DETECTOR + DESCRIPTOR)" << std::endl; + + // Open camera + cv::VideoCapture cam; + CCamUtils cam_fc; + cam_fc.openCamera(0, cam); + + // Create displays + cv::startWindowThread(); + cv::namedWindow("Original image", cv::WINDOW_NORMAL); + cv::namedWindow("Detections", cv::WINDOW_NORMAL); + + // The following line is used to remove the OpenCV "init done" from the terminal + std::cout << "\e[A" << " " << std::endl; + + for (int nframe = 0; nframe < 1000; ++nframe) + { + // Get frame + cv::Mat frame; + cam_fc.getFrame(cam, frame); + + // Show ORIGINAL frame + cv::imshow("Original image", frame); + + // Detector + CFeature_Detector::KeyPointVector keypoints; + keypoints = detector.detectKeyPoints(frame); + + // Descriptor + cv::Mat descriptors; + descriptors = descriptor.getDescriptor(frame,keypoints); + + // Show frame with features + detector.drawKeyFeatures(frame, keypoints); + + std::cout << "\e[A" << + "Detection time: " << detector.getDetectionTime() << " " << + "Description time: " << descriptor.getDescriptorTime() << " " << + "TOTAL time: " << detector.getDetectionTime() + descriptor.getDescriptorTime() << std::endl; + + // Show NEW frame + cv::imshow("Detections", frame); + cv::waitKey(1); + // if (cv::waitKey(30) >= 0) break; + } + + cv::destroyAllWindows(); +} + + + diff --git a/src/feature_descriptor/feature_descriptor.cpp b/src/feature_descriptor/feature_descriptor.cpp index 2b092f9..61855e6 100644 --- a/src/feature_descriptor/feature_descriptor.cpp +++ b/src/feature_descriptor/feature_descriptor.cpp @@ -1,10 +1,155 @@ #include "feature_descriptor.h" -CFeature_Descriptor::CFeature_Descriptor() +CFeature_Descriptor::CFeature_Descriptor(const Descriptor::Type& _type) : + type_(Descriptor::__DELIM__), is_init_(false), descript_time_(0.0) { + + is_init_ = init(_type); + + if (!is_init_) { + std::cerr + << "[Feature Descriptor]: Something went wrong during initialization! Feature Descriptor not initialized." + << std::endl; + } +} + +CFeature_Descriptor::CFeature_Descriptor(const int&_type) : + type_(Descriptor::__DELIM__), is_init_(false), descript_time_(0.0) { + + is_init_ = init(intToDescriptorType(_type)); + + if (!is_init_) { + std::cerr + << "[Feature Descriptor]: Something went wrong during initialization! Feature Descriptor not initialized." + << std::endl; + } +} + +CFeature_Descriptor::CFeature_Descriptor() : + type_(Descriptor::__DELIM__), is_init_(false), descript_time_(0.0) { +} + +CFeature_Descriptor::~CFeature_Descriptor() { +} + +std::vector<Descriptor::Type> CFeature_Descriptor::listDescriptors(void) { + std::vector<Descriptor::Type> list; + + for (int ii = 0; ii < Descriptor::LUCID + 1; ii++) + { + list.push_back(static_cast<Descriptor::Type>(ii)); + } + + return list; } -CFeature_Descriptor::~CFeature_Descriptor() +bool CFeature_Descriptor::setDescriptorType(const Descriptor::Type& _type) { + is_init_ = init(_type); + return is_init_; } +bool CFeature_Descriptor::setDescriptorType(const int& _type) +{ + is_init_ = init(intToDescriptorType(_type)); + return is_init_; +} + +double CFeature_Descriptor::getDescriptorTime(void) +{ + return descript_time_; +} + +bool CFeature_Descriptor::init(Descriptor::Type _type) { + if (is_init_) + std::cerr + << "[CFeature_Descriptor::init]: Descriptor already initialized." + << std::endl; + + bool success = false; + + // TODO: Set parameters for each descriptor type + switch (_type) { + case Descriptor::ORB: + feature_descriptor_ = cv::ORB::create(); + success = true; + break; + case Descriptor::SIFT: + feature_descriptor_ = cv::xfeatures2d::SIFT::create(); + success = true; + break; + case Descriptor::SURF: + feature_descriptor_ = cv::xfeatures2d::SURF::create(); + success = true; + break; + case Descriptor::KAZE: + feature_descriptor_ = cv::KAZE::create(); + success = true; + break; + case Descriptor::AKAZE: + feature_descriptor_ = cv::AKAZE::create(); + success = true; + break; + case Descriptor::BRISK: + feature_descriptor_ = cv::BRISK::create(); + success = true; + break; + case Descriptor::LATCH: + feature_descriptor_ = cv::xfeatures2d::LATCH::create(); + success = true; + break; + case Descriptor::FREAK: + feature_descriptor_ = cv::xfeatures2d::FREAK::create(); + success = true; + break; + case Descriptor::BRIEF: + feature_descriptor_ = cv::xfeatures2d::BriefDescriptorExtractor::create(); + success = true; + break; + case Descriptor::DAISY: + feature_descriptor_ = cv::xfeatures2d::DAISY::create(); + success = true; + break; + case Descriptor::LUCID: + feature_descriptor_ = cv::xfeatures2d::LUCID::create(1,2); + success = true; + break; + case Descriptor::__DELIM__: + success = false; + break; + } + + if (success) + type_ = _type; + else + std::cerr << "[Feature Descriptor]: descriptor_type " << _type + << " doesn't exist !" << std::endl; + + return success; +} + +cv::Mat CFeature_Descriptor::getDescriptor(const cv::Mat& _image, CFeature_Descriptor::KeyPointVector& _kpts) +{ + if (!is_init_) + std::cerr << "[CFeature_Descriptor::getDescriptor]: Descriptor non initialized." << std::endl; + + cv::Mat descriptors; + + clock_t tStart = clock(); + feature_descriptor_->compute(_image, _kpts, descriptors); + descript_time_ = (double)(clock() - tStart) / CLOCKS_PER_SEC; + + return descriptors; +} + +Descriptor::Type CFeature_Descriptor::intToDescriptorType( + const unsigned int _i) { + Descriptor::Type type; + + for (unsigned int ii = 0; ii < Descriptor::__DELIM__; ii++) { + if (ii == _i) + type = static_cast<Descriptor::Type>(ii); + } + + return type; +} diff --git a/src/feature_descriptor/feature_descriptor.h b/src/feature_descriptor/feature_descriptor.h index ecfaea3..df5dbbe 100644 --- a/src/feature_descriptor/feature_descriptor.h +++ b/src/feature_descriptor/feature_descriptor.h @@ -1,17 +1,115 @@ #ifndef _FEATURE_DESCRIPTOR_H #define _FEATURE_DESCRIPTOR_H -// Descriptor types -enum DESCRIPTOR_TYPE -{ - ORB, SIFT, SURF, AKAZE, KAZE, BRISK, LATCH, FREAK, BRIEF, DAISY, LBD, ROOTSIFT +#include <time.h> + +// 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/xfeatures2d.hpp> +#include <opencv2/line_descriptor/descriptor.hpp> + +typedef cv::Ptr<cv::DescriptorExtractor> FeatureDescriptorPtr; + +namespace Descriptor { + +/** + * \brief MACROS to generate all detector types and their corresponding strings + */ +#define FOREACH_DESCRIPTOR(DESCRIPTOR) \ + DESCRIPTOR(ORB) \ + DESCRIPTOR(SIFT) \ + DESCRIPTOR(SURF) \ + DESCRIPTOR(KAZE) \ + DESCRIPTOR(AKAZE) \ + DESCRIPTOR(BRISK) \ + DESCRIPTOR(LATCH) \ + DESCRIPTOR(FREAK) \ + DESCRIPTOR(BRIEF) \ + DESCRIPTOR(DAISY) \ + DESCRIPTOR(LUCID) \ + DESCRIPTOR(__DELIM__) \ + +#define GENERATE_ENUM(ENUM) ENUM, +#define GENERATE_STRING(STRING) #STRING, +enum Type { + FOREACH_DESCRIPTOR(GENERATE_ENUM) }; +static const char *DESCRIPTOR_TYPE_STRING[] = { FOREACH_DESCRIPTOR( + GENERATE_STRING) }; + +/** + * \brief Stream operator for the descriptor flags. + */ +inline std::ostream& operator<<(std::ostream& _os, Type _f) { + _os << DESCRIPTOR_TYPE_STRING[_f]; + return _os; +} + +} // end of namespace + +class CFeature_Descriptor { + +public: + + typedef std::vector<cv::KeyPoint> KeyPointVector; + + //CFeature_Descriptor(const DESCRIPTOR_TYPE& _type); + CFeature_Descriptor(const Descriptor::Type& _type); + CFeature_Descriptor(const int&_type); + CFeature_Descriptor(void); + + ~CFeature_Descriptor(void); + + /** + * \brief List the defined detector types + */ + std::vector<Descriptor::Type> listDescriptors(void); + + /** + * \brief Set descriptor type + */ + bool setDescriptorType(const Descriptor::Type& _type); + bool setDescriptorType(const int& _type); + + /** + * \brief Get detection duration + */ + double getDescriptorTime(void); + + /** + * \brief Get descriptors + */ + cv::Mat getDescriptor(const cv::Mat& _image, + CFeature_Descriptor::KeyPointVector& _kpts); + +private: + + Descriptor::Type type_; + + // Flags + bool is_init_; + + double descript_time_; // Detection time + + FeatureDescriptorPtr feature_descriptor_; // Feature point descriptor + + /** + * \brief Initialize descriptor + */ + bool init(Descriptor::Type _type); + + /** + * \brief Convert an integer to its corresponding descriptor flag. + * + * By default return ORB. + */ + Descriptor::Type intToDescriptorType(const unsigned int _i); -class CFeature_Descriptor -{ - public: - CFeature_Descriptor(); - ~CFeature_Descriptor(); }; #endif diff --git a/src/feature_detector/feature_detector.cpp b/src/feature_detector/feature_detector.cpp index 66b408b..695f6b5 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) : - type_(__DELIM__), is_init_(false), is_line_(false), is_limited_(false), keypoints_limit_(-1), detect_time_(0.0) +CFeature_Detector::CFeature_Detector(const Detector::Type& _type) : + type_(Detector::__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) : - type_(__DELIM__), is_init_(false), is_line_(false), is_limited_(false), keypoints_limit_(-1), detect_time_(0.0) + type_(Detector::__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) : - type_(__DELIM__), is_init_(false), is_line_(false), is_limited_(false), keypoints_limit_(-1), detect_time_(0.0) + type_(Detector::__DELIM__), is_init_(false), is_line_(false), is_limited_(false), keypoints_limit_(-1), detect_time_(0.0) { } @@ -33,19 +33,19 @@ CFeature_Detector::~CFeature_Detector() { } -std::vector<DETECTOR_TYPE> CFeature_Detector::listDetectors(void) +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 < Detector::ED + 1; ii++) { - list.push_back(static_cast<DETECTOR_TYPE>(ii)); + list.push_back(static_cast<Detector::Type>(ii)); } return list; } -bool CFeature_Detector::setDetectorType(const DETECTOR_TYPE& _type) +bool CFeature_Detector::setDetectorType(const Detector::Type& _type) { is_init_ = init(_type); return is_init_; @@ -77,7 +77,7 @@ int CFeature_Detector::getKeyPointsLimit(void) return keypoints_limit_; } -bool CFeature_Detector::init(DETECTOR_TYPE _type) +bool CFeature_Detector::init(Detector::Type _type) { if (is_init_) std::cerr << "[CFeature_Detector::init]: Detector already initialized." << std::endl; @@ -87,65 +87,65 @@ bool CFeature_Detector::init(DETECTOR_TYPE _type) // TODO: Set parameters for each detector type switch (_type) { - case FAST: + case Detector::FAST: feature_detector_ = cv::FastFeatureDetector::create(); success = true; break; - case SIFT: + case Detector::SIFT: feature_detector_ = cv::xfeatures2d::SIFT::create(); success = true; break; - case SURF: + case Detector::SURF: feature_detector_ = cv::xfeatures2d::SURF::create(); success = true; break; - case ORB: + case Detector::ORB: feature_detector_ = cv::ORB::create(); success = true; break; - case BRISK: + case Detector::BRISK: feature_detector_ = cv::BRISK::create(); success = true; break; - case MSER: + case Detector::MSER: feature_detector_ = cv::MSER::create(); success = true; break; - case GFTT: + case Detector::GFTT: feature_detector_ = cv::GFTTDetector::create(1000, 0.01, 1.0, 3, false, 0.04); success = true; break; - case HARRIS: + case Detector::HARRIS: feature_detector_ = cv::GFTTDetector::create(1000, 0.01, 1.0, 3, true, 0.04); success = true; break; - case SBD: + case Detector::SBD: feature_detector_ = cv::SimpleBlobDetector::create(); success = true; break; - case KAZE: + case Detector::KAZE: feature_detector_ = cv::KAZE::create(); success = true; break; - case AKAZE: + case Detector::AKAZE: feature_detector_ = cv::AKAZE::create(); success = true; break; - case AGAST: + case Detector::AGAST: feature_detector_ = cv::AgastFeatureDetector::create(); success = true; break; - case LSD: + case Detector::LSD: lsd_detector_ = cv::line_descriptor::LSDDetector::createLSDDetector(); is_line_ = true; success = true; break; - case ED: + case Detector::ED: ed_detector_ = cv::line_descriptor::BinaryDescriptor::createBinaryDescriptor(); is_line_ = true; success = true; break; - case __DELIM__: + case Detector::__DELIM__: success = false; break; } @@ -195,7 +195,7 @@ CFeature_Detector::KeyLineVector CFeature_Detector::detectKeyLines(const cv::Mat mask_ = cv::Mat::ones(_image.size(), CV_8U); clock_t tStart = clock(); - if (type_ == LSD) + if (type_ == Detector::LSD) lsd_detector_->detect(_image, kls, SCALE_FACTOR_LINE_DETECTOR, NUM_OCTAVE_LINE_DETECTOR, mask_); else ed_detector_->detect(_image, kls2, mask_); @@ -236,14 +236,14 @@ cv::Mat CFeature_Detector::drawKeyFeatures(const cv::Mat& _image, const KeyLineV return img_out; } -DETECTOR_TYPE CFeature_Detector::intToDetectorType(const unsigned int _i) +Detector::Type CFeature_Detector::intToDetectorType(const unsigned int _i) { - DETECTOR_TYPE type; + Detector::Type type; - for (unsigned int ii = 0; ii < __DELIM__; ii++) + for (unsigned int ii = 0; ii < Detector::__DELIM__; ii++) { if (ii == _i) - type = static_cast<DETECTOR_TYPE>(ii); + 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 942d3d3..9fc148a 100644 --- a/src/feature_detector/feature_detector.h +++ b/src/feature_detector/feature_detector.h @@ -19,6 +19,9 @@ typedef cv::Ptr<cv::FeatureDetector> FeatureDetectorPtr; typedef cv::Ptr<cv::line_descriptor::LSDDetector> LSDDetector; typedef cv::Ptr<cv::line_descriptor::BinaryDescriptor> EDDetector; +namespace Detector +{ + /** * \brief MACROS to generate all detector types and their corresponding strings */ @@ -41,7 +44,7 @@ typedef cv::Ptr<cv::line_descriptor::BinaryDescriptor> EDDetector; #define GENERATE_ENUM(ENUM) ENUM, #define GENERATE_STRING(STRING) #STRING, -enum DETECTOR_TYPE +enum Type { FOREACH_DETECTOR(GENERATE_ENUM) }; @@ -50,12 +53,14 @@ 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) +inline std::ostream& operator<<(std::ostream& _os, Type _f) { _os << DETECTOR_TYPE_STRING[_f]; return _os; } +} // End of namespace + /** * \brief Main feature detector class */ @@ -69,7 +74,7 @@ class CFeature_Detector /** * \brief Constructor */ - CFeature_Detector(const DETECTOR_TYPE& _type); + CFeature_Detector(const Detector::Type& _type); CFeature_Detector(const int& _type); CFeature_Detector(void); @@ -81,12 +86,12 @@ class 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); /** @@ -128,7 +133,7 @@ class CFeature_Detector private: - DETECTOR_TYPE type_; + Detector::Type type_; // Flags bool is_init_; @@ -148,14 +153,14 @@ class CFeature_Detector /** * \brief Initialize detector */ - bool init(DETECTOR_TYPE _type); + bool init(Detector::Type _type); /** - * \brief Convert an integer to its corresponding descriptor flag. + * \brief Convert an integer to its corresponding detector flag. * * By default return ORB. */ - DETECTOR_TYPE intToDetectorType(const unsigned int _i); + Detector::Type intToDetectorType(const unsigned int _i); }; diff --git a/src/vision_utils.h b/src/vision_utils.h index 57df788..ec7555f 100644 --- a/src/vision_utils.h +++ b/src/vision_utils.h @@ -3,6 +3,7 @@ #include "cam_utils/cam_utils.h" #include "feature_detector/feature_detector.h" +#include "feature_descriptor/feature_descriptor.h" class CVision_Utils { -- GitLab