diff --git a/.cproject b/.cproject index 83fa9b6a72657d079ccb3fa6a58fec2b85041e46..9c0b0f80b66e6fd52b9ad948d7afd3f059c3a9fd 100644 --- a/.cproject +++ b/.cproject @@ -1,9 +1,11 @@ <?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.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/> + <cconfiguration id="cdt.managedbuild.toolchain.gnu.base.727026548"> + <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.toolchain.gnu.base.727026548" moduleId="org.eclipse.cdt.core.settings" name="Default"> + <externalSettings> + <externalSetting/> + </externalSettings> <extensions> <extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/> <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> @@ -14,36 +16,46 @@ </extensions> </storageModule> <storageModule moduleId="cdtBuildSystem" version="4.0.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"/> + <configuration artifactName="${ProjName}" buildProperties="" description="" id="cdt.managedbuild.toolchain.gnu.base.727026548" name="Default" parent="org.eclipse.cdt.build.core.emptycfg"> + <folderInfo id="cdt.managedbuild.toolchain.gnu.base.727026548.1071101131" name="/" resourcePath=""> + <toolChain id="cdt.managedbuild.toolchain.gnu.base.1732291248" 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.1640924025" 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.1544635012" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.base"/> + <tool id="cdt.managedbuild.tool.gnu.archiver.base.646136846" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/> + <tool id="cdt.managedbuild.tool.gnu.cpp.compiler.base.433122623" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.base"> + <option id="gnu.cpp.compiler.option.include.paths.937784075" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath"> + <listOptionValue builtIn="false" value="/usr/local/include"/> + <listOptionValue builtIn="false" value="/usr/include"/> + <listOptionValue builtIn="false" value="/opt/ros/indigo/include/opencv-3.1.0-dev"/> </option> - <inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1116382079" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/> + <inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.341288586" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/> </tool> - <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"/> + <tool id="cdt.managedbuild.tool.gnu.c.compiler.base.61708613" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.base"> + <option id="gnu.c.compiler.option.include.paths.829945653" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath"> + <listOptionValue builtIn="false" value="/usr/local/include"/> + <listOptionValue builtIn="false" value="/usr/include"/> + <listOptionValue builtIn="false" value="/opt/ros/indigo/include/opencv-3.1.0-dev"/> </option> - <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1695301683" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/> + <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.166078074" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/> </tool> - <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"> + <tool id="cdt.managedbuild.tool.gnu.c.linker.base.2056051326" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.base"/> + <tool id="cdt.managedbuild.tool.gnu.cpp.linker.base.1724439765" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.base"> + <option id="gnu.cpp.link.option.paths.619011598" name="Library search path (-L)" superClass="gnu.cpp.link.option.paths" valueType="libPaths"> + <listOptionValue builtIn="false" value="/usr/lib"/> + <listOptionValue builtIn="false" value="/usr/local/lib"/> + </option> + <inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.1477240259" 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.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"/> + <tool id="cdt.managedbuild.tool.gnu.assembler.base.507993336" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.base"> + <option id="gnu.both.asm.option.include.paths.408889783" name="Include paths (-I)" superClass="gnu.both.asm.option.include.paths" valueType="includePath"> + <listOptionValue builtIn="false" value="/usr/local/include"/> + <listOptionValue builtIn="false" value="/usr/include"/> + <listOptionValue builtIn="false" value="/opt/ros/indigo/include/opencv-3.1.0-dev"/> </option> - <inputType id="cdt.managedbuild.tool.gnu.assembler.input.1370134559" superClass="cdt.managedbuild.tool.gnu.assembler.input"/> + <inputType id="cdt.managedbuild.tool.gnu.assembler.input.794492820" superClass="cdt.managedbuild.tool.gnu.assembler.input"/> </tool> </toolChain> </folderInfo> @@ -53,7 +65,7 @@ </cconfiguration> </storageModule> <storageModule moduleId="cdtBuildSystem" version="4.0.0"> - <project id="vision_utils.null.1875601072" name="vision_utils"/> + <project id="vision_utils.null.1102208136" name="vision_utils"/> </storageModule> <storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/> <storageModule moduleId="refreshScope" versionNumber="2"> @@ -61,7 +73,6 @@ <resource resourceType="PROJECT" workspacePath="/vision_utils"/> </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.1736073220;cdt.managedbuild.toolchain.gnu.base.1736073220.1390770886;cdt.managedbuild.tool.gnu.c.compiler.base.1459107576;cdt.managedbuild.tool.gnu.c.compiler.input.1695301683"> @@ -70,6 +81,18 @@ <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.207681558;cdt.managedbuild.toolchain.gnu.base.207681558.1208625085;cdt.managedbuild.tool.gnu.c.compiler.base.1439246049;cdt.managedbuild.tool.gnu.c.compiler.input.637694474"> + <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/> + </scannerConfigBuildInfo> + <scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.base.727026548;cdt.managedbuild.toolchain.gnu.base.727026548.1071101131;cdt.managedbuild.tool.gnu.c.compiler.base.61708613;cdt.managedbuild.tool.gnu.c.compiler.input.166078074"> + <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/> + </scannerConfigBuildInfo> + <scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.base.207681558;cdt.managedbuild.toolchain.gnu.base.207681558.1208625085;cdt.managedbuild.tool.gnu.cpp.compiler.base.1755527935;cdt.managedbuild.tool.gnu.cpp.compiler.input.1794914341"> + <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/> + </scannerConfigBuildInfo> + <scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.base.727026548;cdt.managedbuild.toolchain.gnu.base.727026548.1071101131;cdt.managedbuild.tool.gnu.cpp.compiler.base.433122623;cdt.managedbuild.tool.gnu.cpp.compiler.input.341288586"> + <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> @@ -78,4 +101,5 @@ </scannerConfigBuildInfo> </storageModule> <storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/> + <storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/> </cproject> diff --git a/.gitignore b/.gitignore index e63ddd8b5e0c43622cec18e9a0a0aa61e00f9103..08b00ab38e6120776e1310c91d4b941a9ad3fc02 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,4 @@ +!.gitignore /Default/ +**/*.*~ +.settings/ diff --git a/.settings/language.settings.xml b/.settings/language.settings.xml deleted file mode 100644 index 5c600911b1171a0f9b6c2e8b05326e3a3daa9ed9..0000000000000000000000000000000000000000 --- a/.settings/language.settings.xml +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<project> - <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="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> - <provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/> - </extension> - </configuration> -</project> diff --git a/CMakeLists.txt b/CMakeLists.txt index ec4ad5c483d1a7139415559eb58d113fbdd5bae7..a31fce829708c2811a2a51be6e3660f14079fae9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,8 +18,25 @@ IF (NOT CMAKE_BUILD_TYPE) SET(CMAKE_BUILD_TYPE "DEBUG") ENDIF (NOT CMAKE_BUILD_TYPE) -SET(CMAKE_CXX_FLAGS_DEBUG "-g -Wall -D_REENTRANT") -SET(CMAKE_CXX_FLAGS_RELEASE "-O3 -D_REENTRANT") +if(UNIX) + # GCC is not strict enough by default, so enable most of the warnings. + set(CMAKE_CXX_FLAGS + "${CMAKE_CXX_FLAGS} -Werror=all -Werror=extra -Wno-unknown-pragmas -Wno-sign-compare -Wno-unused-parameter -Wno-missing-field-initializers") +endif(UNIX) + +#Set compiler according C++11 support +include(CheckCXXCompilerFlag) +CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11) +CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X) +if(COMPILER_SUPPORTS_CXX11) + message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has C++11 support.") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") +elseif(COMPILER_SUPPORTS_CXX0X) + message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has C++0x support.") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") +else() + message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.") +endif() ADD_SUBDIRECTORY(src) diff --git a/cmake_modules/FindYamlCpp.cmake b/cmake_modules/FindYamlCpp.cmake new file mode 100644 index 0000000000000000000000000000000000000000..196c4754e2787a9fa4f47eb8716fd2525bc84fd4 --- /dev/null +++ b/cmake_modules/FindYamlCpp.cmake @@ -0,0 +1,99 @@ +# Locate yaml-cpp +# +# This module defines +# YAMLCPP_FOUND, if false, do not try to link to yaml-cpp +# YAMLCPP_LIBNAME, name of yaml library +# YAMLCPP_LIBRARY, where to find yaml-cpp +# YAMLCPP_LIBRARY_RELEASE, where to find Release or RelWithDebInfo yaml-cpp +# YAMLCPP_LIBRARY_DEBUG, where to find Debug yaml-cpp +# YAMLCPP_INCLUDE_DIR, where to find yaml.h +# YAMLCPP_LIBRARY_DIR, the directories to find YAMLCPP_LIBRARY +# +# By default, the dynamic libraries of yaml-cpp will be found. To find the static ones instead, +# you must set the YAMLCPP_USE_STATIC_LIBS variable to TRUE before calling find_package(YamlCpp ...) + +# attempt to find static library first if this is set +if(YAMLCPP_USE_STATIC_LIBS) + set(YAMLCPP_STATIC libyaml-cpp.a) + set(YAMLCPP_STATIC_DEBUG libyaml-cpp-dbg.a) +endif() + +if(${CMAKE_SYSTEM_NAME} MATCHES "Windows") ### Set Yaml libary name for Windows + set(YAMLCPP_LIBNAME "libyaml-cppmd" CACHE STRING "Name of YAML library") + set(YAMLCPP_LIBNAME optimized ${YAMLCPP_LIBNAME} debug ${YAMLCPP_LIBNAME}d) +else() ### Set Yaml libary name for Unix, Linux, OS X, etc + set(YAMLCPP_LIBNAME "yaml-cpp" CACHE STRING "Name of YAML library") +endif() + +# find the yaml-cpp include directory +find_path(YAMLCPP_INCLUDE_DIR + NAMES yaml-cpp/yaml.h + PATH_SUFFIXES include + PATHS + ${PROJECT_SOURCE_DIR}/dependencies/yaml-cpp-0.5.1/include + ~/Library/Frameworks/yaml-cpp/include/ + /Library/Frameworks/yaml-cpp/include/ + /usr/local/include/ + /usr/include/ + /sw/yaml-cpp/ # Fink + /opt/local/yaml-cpp/ # DarwinPorts + /opt/csw/yaml-cpp/ # Blastwave + /opt/yaml-cpp/) + +# find the release yaml-cpp library +find_library(YAMLCPP_LIBRARY_RELEASE + NAMES ${YAMLCPP_STATIC} yaml-cpp libyaml-cppmd.lib + PATH_SUFFIXES lib64 lib Release RelWithDebInfo + PATHS + ${PROJECT_SOURCE_DIR}/dependencies/yaml-cpp-0.5.1/ + ${PROJECT_SOURCE_DIR}/dependencies/yaml-cpp-0.5.1/build + ~/Library/Frameworks + /Library/Frameworks + /usr/local + /usr + /sw + /opt/local + /opt/csw + /opt) + +# find the debug yaml-cpp library +find_library(YAMLCPP_LIBRARY_DEBUG + NAMES ${YAMLCPP_STATIC_DEBUG} yaml-cpp-dbg libyaml-cppmdd.lib + PATH_SUFFIXES lib64 lib Debug + PATHS + ${PROJECT_SOURCE_DIR}/dependencies/yaml-cpp-0.5.1/ + ${PROJECT_SOURCE_DIR}/dependencies/yaml-cpp-0.5.1/build + ~/Library/Frameworks + /Library/Frameworks + /usr/local + /usr + /sw + /opt/local + /opt/csw + /opt) + +# set library vars +set(YAMLCPP_LIBRARY ${YAMLCPP_LIBRARY_RELEASE}) +if(CMAKE_BUILD_TYPE MATCHES Debug AND EXISTS ${YAMLCPP_LIBRARY_DEBUG}) + set(YAMLCPP_LIBRARY ${YAMLCPP_LIBRARY_DEBUG}) +endif() + +get_filename_component(YAMLCPP_LIBRARY_RELEASE_DIR ${YAMLCPP_LIBRARY_RELEASE} PATH) +get_filename_component(YAMLCPP_LIBRARY_DEBUG_DIR ${YAMLCPP_LIBRARY_DEBUG} PATH) +set(YAMLCPP_LIBRARY_DIR ${YAMLCPP_LIBRARY_RELEASE_DIR} ${YAMLCPP_LIBRARY_DEBUG_DIR}) + +# handle the QUIETLY and REQUIRED arguments and set YAMLCPP_FOUND to TRUE if all listed variables are TRUE +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(YamlCpp DEFAULT_MSG + YAMLCPP_INCLUDE_DIR + YAMLCPP_LIBRARY + YAMLCPP_LIBRARY_DIR) +mark_as_advanced( + YAMLCPP_INCLUDE_DIR + YAMLCPP_LIBRARY_DIR + YAMLCPP_LIBRARY + YAMLCPP_LIBRARY_RELEASE + YAMLCPP_LIBRARY_RELEASE_DIR + YAMLCPP_LIBRARY_DEBUG + YAMLCPP_LIBRARY_DEBUG_DIR) + diff --git a/Findvision_utils.cmake b/cmake_modules/Findvision_utils.cmake similarity index 100% rename from Findvision_utils.cmake rename to cmake_modules/Findvision_utils.cmake diff --git a/internal/config.h b/internal/config.h new file mode 100644 index 0000000000000000000000000000000000000000..6449c336a10ce2de3629678959b70208e2055486 --- /dev/null +++ b/internal/config.h @@ -0,0 +1,6 @@ +#ifndef VU_INTERNAL_CONFIG_H_ +#define VU_INTERNAL_CONFIG_H_ + +#define _VU_ROOT_DIR "/home/asantamaria/git/asantamaria_cpp/vision_utils" + +#endif /* VU_INTERNAL_CONFIG_H_ */ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7eef9dc97b86120262fd4986ba28410776c926f4..175def8dfdc0fb24658197bec161593742c14e94 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,8 +1,116 @@ # library source files -SET(sources vision_utils.cpp cam_utils/cam_utils.cpp feature_detector/feature_detector.cpp feature_descriptor/feature_descriptor.cpp feature_matcher/feature_matcher.cpp) - +SET(sources + vision_utils.cpp + sensors/sensor_base.cpp + sensors/usb_cam/usb_cam.cpp + sensors/usb_cam/usb_cam_load_yaml.cpp + detectors/detector_base.cpp + detectors/orb/detector_orb.cpp + detectors/orb/detector_orb_load_yaml.cpp + detectors/fast/detector_fast.cpp + detectors/fast/detector_fast_load_yaml.cpp + detectors/sift/detector_sift.cpp + detectors/sift/detector_sift_load_yaml.cpp + detectors/surf/detector_surf.cpp + detectors/surf/detector_surf_load_yaml.cpp + detectors/brisk/detector_brisk.cpp + detectors/brisk/detector_brisk_load_yaml.cpp + detectors/mser/detector_mser.cpp + detectors/mser/detector_mser_load_yaml.cpp + detectors/gftt/detector_gftt.cpp + detectors/gftt/detector_gftt_load_yaml.cpp + detectors/harris/detector_harris.cpp + detectors/harris/detector_harris_load_yaml.cpp + detectors/sbd/detector_sbd.cpp + detectors/sbd/detector_sbd_load_yaml.cpp + detectors/kaze/detector_kaze.cpp + detectors/kaze/detector_kaze_load_yaml.cpp + detectors/akaze/detector_akaze.cpp + detectors/akaze/detector_akaze_load_yaml.cpp + detectors/agast/detector_agast.cpp + detectors/agast/detector_agast_load_yaml.cpp + descriptors/descriptor_base.cpp + descriptors/orb/descriptor_orb.cpp + descriptors/orb/descriptor_orb_load_yaml.cpp + descriptors/sift/descriptor_sift.cpp + descriptors/sift/descriptor_sift_load_yaml.cpp + descriptors/surf/descriptor_surf.cpp + descriptors/surf/descriptor_surf_load_yaml.cpp + descriptors/brisk/descriptor_brisk.cpp + descriptors/brisk/descriptor_brisk_load_yaml.cpp + descriptors/kaze/descriptor_kaze.cpp + descriptors/kaze/descriptor_kaze_load_yaml.cpp + descriptors/akaze/descriptor_akaze.cpp + descriptors/akaze/descriptor_akaze_load_yaml.cpp + descriptors/latch/descriptor_latch.cpp + descriptors/latch/descriptor_latch_load_yaml.cpp + descriptors/freak/descriptor_freak.cpp + descriptors/freak/descriptor_freak_load_yaml.cpp + descriptors/brief/descriptor_brief.cpp + descriptors/brief/descriptor_brief_load_yaml.cpp + descriptors/daisy/descriptor_daisy.cpp + descriptors/daisy/descriptor_daisy_load_yaml.cpp + descriptors/lucid/descriptor_lucid.cpp + descriptors/lucid/descriptor_lucid_load_yaml.cpp + matchers/matcher_base.cpp + matchers/bruteforce/matcher_bruteforce.cpp + matchers/bruteforce/matcher_bruteforce_load_yaml.cpp + matchers/bruteforce_l1/matcher_bruteforce_l1.cpp + matchers/bruteforce_l1/matcher_bruteforce_l1_load_yaml.cpp + matchers/bruteforce_hamming/matcher_bruteforce_hamming.cpp + matchers/bruteforce_hamming/matcher_bruteforce_hamming_load_yaml.cpp + matchers/bruteforce_hamming_2/matcher_bruteforce_hamming_2.cpp + matchers/bruteforce_hamming_2/matcher_bruteforce_hamming_2_load_yaml.cpp + matchers/flannbased/matcher_flannbased.cpp + matchers/flannbased/matcher_flannbased_load_yaml.cpp + algorithms/algorithm_base.cpp + algorithms/opticalflowpyrlk/alg_opticalflowpyrlk.cpp + algorithms/opticalflowpyrlk/alg_opticalflowpyrlk_load_yaml.cpp) + # application header files -SET(headers vision_utils.h common/vu_base.h cam_utils/cam_utils.h feature_detector/feature_detector.h feature_descriptor/feature_descriptor.h feature_matcher/feature_matcher.h) +SET(headers + vision_utils.h + factory.h + sensors/sensor_factory.h + sensors/sensor_base.h + sensors/usb_cam/usb_cam.h + detectors/detector_factory.h + detectors/detector_base.h + detectors/orb/detector_orb.h + detectors/fast/detector_fast.h + detectors/sift/detector_sift.h + detectors/surf/detector_surf.h + detectors/brisk/detector_brisk.h + detectors/mser/detector_mser.h + detectors/gftt/detector_gftt.h + detectors/harris/detector_harris.h + detectors/sbd/detector_sbd.h + detectors/kaze/detector_kaze.h + detectors/akaze/detector_akaze.h + detectors/agast/detector_agast.h + descriptors/descriptor_factory.h + descriptors/descriptor_base.h + descriptors/orb/descriptor_orb.h + descriptors/sift/descriptor_sift.h + descriptors/surf/descriptor_surf.h + descriptors/brisk/descriptor_brisk.h + descriptors/kaze/descriptor_kaze.h + descriptors/akaze/descriptor_akaze.h + descriptors/latch/descriptor_latch.h + descriptors/freak/descriptor_freak.h + descriptors/brief/descriptor_brief.h + descriptors/daisy/descriptor_daisy.h + descriptors/lucid/descriptor_lucid.h + matchers/matcher_factory.h + matchers/matcher_base.h + matchers/bruteforce/matcher_bruteforce.h + matchers/bruteforce_l1/matcher_bruteforce_l1.h + matchers/bruteforce_hamming/matcher_bruteforce_hamming.h + matchers/bruteforce_hamming_2/matcher_bruteforce_hamming_2.h + matchers/flannbased/matcher_flannbased.h + algorithms/algorithm_factory.h + algorithms/algorithm_base.h + algorithms/opticalflowpyrlk/alg_opticalflowpyrlk.h) # locate the necessary dependencies FIND_PACKAGE(Eigen3 REQUIRED) @@ -22,23 +130,61 @@ else(OpenCV_FOUND) message("[WARN] OpenCV support not installed. Minimum 3.0 version required.") endif(OpenCV_FOUND) +# YAML with yaml-cpp +INCLUDE (${PROJECT_SOURCE_DIR}/cmake_modules/FindYamlCpp.cmake) +IF(YAMLCPP_FOUND) + MESSAGE(STATUS "Yaml-cpp related sources will be built.") + ADD_DEFINITIONS( -DUSING_YAML ) +ELSEIF(YAMLCPP_FOUND) + MESSAGE("[WARN] yaml-cpp Library NOT FOUND!") +ENDIF(YAMLCPP_FOUND) # add the necessary include directories INCLUDE_DIRECTORIES(. ${EIGEN3_INCLUDE_DIR} ${OpenCV_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}) +IF(YAMLCPP_FOUND) +INCLUDE_DIRECTORIES(${YAMLCPP_INCLUDE_DIR}) +ENDIF(YAMLCPP_FOUND) + +SET(_VU_ROOT_DIR ${CMAKE_SOURCE_DIR}) + +# Define the directory where will be the configured config.h +SET(VU_CONFIG_DIR ${PROJECT_BINARY_DIR}/conf/_internal) + +# Create the specified output directory if it does not exist. +IF(NOT EXISTS "${VU_CONFIG_DIR}") + MESSAGE(STATUS "Creating config output directory: ${VU_CONFIG_DIR}") + FILE(MAKE_DIRECTORY "${VU_CONFIG_DIR}") +ENDIF() +IF(EXISTS "${VU_CONFIG_DIR}" AND NOT IS_DIRECTORY "${VU_CONFIG_DIR}") + MESSAGE(FATAL_ERROR "Bug: Specified CONFIG_DIR: ${VU_CONFIG_DIR} exists, but is not a directory.") +ENDIF() +CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/_internal/config.h.in "${VU_CONFIG_DIR}/config.h") +MESSAGE(STATUS "Configuring ${PROJECT_NAME} (creating config.h from _internal dir)") + +# Include config.h directory at first. +include_directories("${PROJECT_BINARY_DIR}/conf") + # create the shared library -ADD_LIBRARY(vision_utils SHARED ${sources}) +ADD_LIBRARY(${PROJECT_NAME} SHARED ${sources}) # link necessary libraries -TARGET_LINK_LIBRARIES(vision_utils ${OpenCV_LIBS} ${Boost_LIBRARIES}) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${OpenCV_LIBS} ${Boost_LIBRARIES}) + +IF (YAMLCPP_FOUND) + TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${YAMLCPP_LIBRARY}) +ENDIF (YAMLCPP_FOUND) # install -INSTALL(TARGETS vision_utils +INSTALL(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin - LIBRARY DESTINATION lib/vision_utils - ARCHIVE DESTINATION lib/vision_utils) -INSTALL(FILES ${headers} DESTINATION include/vision_utils) -INSTALL(FILES ../Findvision_utils.cmake DESTINATION ${CMAKE_ROOT}/Modules/) + LIBRARY DESTINATION lib/${PROJECT_NAME} + ARCHIVE DESTINATION lib/${PROJECT_NAME}) +INSTALL(FILES ${headers} DESTINATION include/${PROJECT_NAME}) +INSTALL(FILES ../cmake_modules/Find${PROJECT_NAME}.cmake DESTINATION ${CMAKE_ROOT}/Modules/) +INSTALL(FILES "${VU_CONFIG_DIR}/config.h" DESTINATION include/${PROJECT_NAME}/_internal) # examples of usage ADD_SUBDIRECTORY(examples) + + diff --git a/src/_internal/config.h.in b/src/_internal/config.h.in new file mode 100644 index 0000000000000000000000000000000000000000..1d5c2a8bbaeb5ee6e6dfe9f26b03013b8bbbeb41 --- /dev/null +++ b/src/_internal/config.h.in @@ -0,0 +1,6 @@ +#ifndef VU_INTERNAL_CONFIG_H_ +#define VU_INTERNAL_CONFIG_H_ + +#define _VU_ROOT_DIR "${_VU_ROOT_DIR}" + +#endif /* VU_INTERNAL_CONFIG_H_ */ diff --git a/src/algorithms/algorithm_base.cpp b/src/algorithms/algorithm_base.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6bbb87fc2ccfbd781047c56309f67e7814a48939 --- /dev/null +++ b/src/algorithms/algorithm_base.cpp @@ -0,0 +1,34 @@ +#include "algorithm_base.h" + +namespace vision_utils { + +AlgorithmBase::AlgorithmBase(void) +{ +} + +AlgorithmBase::~AlgorithmBase(void) +{ +} + +} /* namespace vision_utils */ + +#include "algorithm_factory.h" + +namespace vision_utils +{ + +AlgorithmBasePtr setupAlgorithm(const std::string& _type, const std::string& _unique_name, const ParamsBasePtr& _params) +{ + AlgorithmBasePtr mat_ptr = AlgorithmFactory::get().create(_type, _unique_name, _params); + return mat_ptr; +}; + +#ifdef USING_YAML +AlgorithmBasePtr setupAlgorithm(const std::string& _type, const std::string& _unique_name, const std::string& _filename_dot_yaml) +{ + ParamsBasePtr params_ptr = ParamsFactory::get().create(_type+" ALG", _filename_dot_yaml); + return setupAlgorithm(_type, _unique_name, params_ptr); +} +#endif + +} /* namespace vision_utils */ diff --git a/src/algorithms/algorithm_base.h b/src/algorithms/algorithm_base.h new file mode 100644 index 0000000000000000000000000000000000000000..13a4af29939298ecbd5198e89f8c054893b13fc1 --- /dev/null +++ b/src/algorithms/algorithm_base.h @@ -0,0 +1,82 @@ +#ifndef _ALGORITHM_BASE_H_ +#define _ALGORITHM_BASE_H_ + +// vision_utils +#include "../vision_utils.h" + +namespace vision_utils +{ + +///////////////////////////////////////////////////////////////////////// +// CLASS DEFINITIONS +///////////////////////////////////////////////////////////////////////// + +// Create all pointers +VU_PTR_TYPEDEFS(AlgorithmBase); +VU_PTR_TYPEDEFS(AlgorithmParamsBase); + +/** \brief Class parameters + * + */ +struct AlgorithmParamsBase: public ParamsBase +{}; + +/** \brief base class for Algorithm base + * + * Derive from this class to create Algorithm base class parameters. + */ +class AlgorithmBase : public VUBase, public std::enable_shared_from_this<AlgorithmBase> +{ + public: + + /** + * \brief Constructor without parameters + */ + AlgorithmBase(void); + + /** + * \brief Virtual destructor + */ + virtual ~AlgorithmBase(void); + + std::string getName(void); + + virtual AlgorithmParamsBasePtr getParams(void) = 0; + + virtual void compute(cv::Mat& frame, PointVector& pts_prev, PointVector& pts_matched_in_prev, PointVector& pts_matched_in_frame) = 0; + + // Factory method + static AlgorithmBasePtr create(const std::string& _unique_name, const ParamsBasePtr _params); + + protected: + + std::string name_; + + AlgorithmParamsBasePtr params_base_ptr_; + + void setName(const std::string& _name); + + virtual void defineAlgorithm(const ParamsBasePtr _params) = 0; +}; + +/* + * brief Retrieve object name + */ +inline std::string AlgorithmBase::getName(void) { return name_; } + +/* + * brief Set object name + */ +inline void AlgorithmBase::setName(const std::string& _name){ name_ = _name; } + +/* + * brief Setup and get the corresponding pointer + */ +AlgorithmBasePtr setupAlgorithm(const std::string& _type, const std::string& _unique_name, const ParamsBasePtr& _params); +#ifdef USING_YAML +AlgorithmBasePtr setupAlgorithm(const std::string& _type, const std::string& _unique_name, const std::string& _filename_dot_yaml); +#endif + +} /* namespace vision_utils */ + +#endif /* _ALGORITHM_BASE_H_ */ diff --git a/src/algorithms/algorithm_factory.h b/src/algorithms/algorithm_factory.h new file mode 100644 index 0000000000000000000000000000000000000000..b05a50ab1a1ca084f193970115bbc45500698b04 --- /dev/null +++ b/src/algorithms/algorithm_factory.h @@ -0,0 +1,32 @@ +#ifndef _ALGORITHM_FACTORY_H_ +#define _ALGORITHM_FACTORY_H_ + +namespace vision_utils +{ +class AlgorithmBase; +struct AlgorithmParamsBase; +} + +#include "../factory.h" + +namespace vision_utils +{ + +/* Algorithm Factory */ +typedef Factory<AlgorithmBase, + const std::string&, + const ParamsBasePtr> AlgorithmFactory; + +template<> +inline std::string AlgorithmFactory::getClass() +{ + return "AlgorithmFactory"; +} + +#define VU_REGISTER_ALGORITHM(AlgorithmType, AlgorithmName) \ + namespace{ const bool AlgorithmName##Registered = \ + AlgorithmFactory::get().registerCreator(AlgorithmType, AlgorithmName::create, true); }\ + +} /* namespace vision_utils */ + +#endif /* _ALGORITHM_FACTORY_H_ */ diff --git a/src/algorithms/opticalflowpyrlk/alg_opticalflowpyrlk.cpp b/src/algorithms/opticalflowpyrlk/alg_opticalflowpyrlk.cpp new file mode 100644 index 0000000000000000000000000000000000000000..08fbce06e562c054c59e834f61b24824874172eb --- /dev/null +++ b/src/algorithms/opticalflowpyrlk/alg_opticalflowpyrlk.cpp @@ -0,0 +1,56 @@ +#include "alg_opticalflowpyrlk.h" + +// OpenCV +#include "opencv2/video/tracking.hpp" + +namespace vision_utils { + +AlgorithmOPTFLOWPYRLK::AlgorithmOPTFLOWPYRLK(void): initialized_(false) +{} + +AlgorithmOPTFLOWPYRLK::~AlgorithmOPTFLOWPYRLK(void) +{} + +void AlgorithmOPTFLOWPYRLK::compute(cv::Mat& frame, PointVector& pts_prev, PointVector& pts_matched_in_prev, PointVector& pts_matched_in_frame) +{ + // Convert to gray scale if necessary + cv::Mat frame_gray; + if (frame.channels() == 3) + cv::cvtColor(frame, frame_gray, CV_RGB2GRAY); + else + frame_gray = frame; + + if (!initialized_) + initialized_ = true; + else + { + std::vector<uchar> kpt_is_found; // output status vector (of unsigned chars); each element of the vector is set to 1 if the flow for the corresponding features has been found, otherwise, it is set to 0. + std::vector<float> err; // output vector of errors + + pts_matched_in_prev.clear(); + + // Compute optical flow + if (pts_prev.size() > 0) + cv::calcOpticalFlowPyrLK(frame_gray_prev_, frame_gray, pts_prev, pts_matched_in_frame, kpt_is_found, err, params_ptr_->win_size, params_ptr_->max_level, params_ptr_->criteria, params_ptr_->flags, params_ptr_->min_eig_threshold); + + //Draw lines connecting previous position and current position + PointVector good_kpts; + for(size_t ii=0; ii<pts_matched_in_frame.size(); ii++) + if(kpt_is_found[ii] && err[ii] < params_ptr_->min_err_kpt_match) + { + good_kpts.push_back(pts_matched_in_frame[ii]); + pts_matched_in_prev.push_back(pts_prev[ii]); + } + pts_matched_in_frame = good_kpts; + } + + frame_gray_prev_ = frame_gray; +} + +} /* namespace vision_utils */ + +// Register in the AlgorithmsFactory +namespace vision_utils +{ +VU_REGISTER_ALGORITHM("OPTFLOWPYRLK", AlgorithmOPTFLOWPYRLK); +} /* namespace vision_utils */ diff --git a/src/algorithms/opticalflowpyrlk/alg_opticalflowpyrlk.h b/src/algorithms/opticalflowpyrlk/alg_opticalflowpyrlk.h new file mode 100644 index 0000000000000000000000000000000000000000..535e620689c8c95914f8dba9fe87111f57e4798b --- /dev/null +++ b/src/algorithms/opticalflowpyrlk/alg_opticalflowpyrlk.h @@ -0,0 +1,85 @@ +#ifndef _ALGORITHM_OPTFLOWPYRLK_H_ +#define _ALGORITHM_OPTFLOWPYRLK_H_ + +#include "../algorithm_base.h" +#include "../algorithm_factory.h" + +// yaml-cpp library +#ifdef USING_YAML + #include <yaml-cpp/yaml.h> +#endif + +namespace vision_utils { + +// Create all pointers +VU_PTR_TYPEDEFS(AlgorithmOPTFLOWPYRLK); +VU_PTR_TYPEDEFS(AlgorithmParamsOPTFLOWPYRLK); + +/** \brief Class parameters + * + */ +struct AlgorithmParamsOPTFLOWPYRLK: public AlgorithmParamsBase +{ + cv::Size win_size = cv::Size(21, 21); // Size of the search window at each pyramid level. + int max_level = 3; // 0-based maximal pyramid level number; if set to 0, pyramids are not used (single level), if set to 1, two levels are used, and so on; if pyramids are passed to input then algorithm will use as many levels as pyramids have but no more than maxLevel. + cv::TermCriteria criteria = cv::TermCriteria(cv::TermCriteria::COUNT+cv::TermCriteria::EPS, 30, 0.01); // Parameter, specifying the termination criteria of the iterative search algorithm (after the specified maximum number of iterations criteria.maxCount or when the search window moves by less than criteria.epsilon. + int flags = 0; // Operation flags: OPTFLOW_USE_INITIAL_FLOW uses initial estimations, stored in nextPts; if the flag is not set, then prevPts is copied to nextPts and is considered the initial estimate. OPTFLOW_LK_GET_MIN_EIGENVALS use minimum eigen values as an error measure (see minEigThreshold description); if the flag is not set, then L1 distance between patches around the original and a moved point, divided by number of pixels in a window, is used as a error measure. + double min_eig_threshold = 1e-4; // The algorithm calculates the minimum eigen value of a 2x2 normal matrix of optical flow equations (this matrix is called a spatial gradient matrix in [16]), divided by number of pixels in a window; if this value is less than minEigThreshold, then a corresponding feature is filtered out and its flow is not processed, so it allows to remove bad points and get a performance boost. + double min_err_kpt_match = 4.0; // Minimum reprojection error to be considered a good feature. +}; + +/** \brief DETECTOR class + * + */ +class AlgorithmOPTFLOWPYRLK : public AlgorithmBase { + + public: + AlgorithmOPTFLOWPYRLK(); + virtual ~AlgorithmOPTFLOWPYRLK(void); + + // Factory method + static AlgorithmBasePtr create(const std::string& _unique_name, const ParamsBasePtr _params); + + void compute(cv::Mat& frame, PointVector& pts_prev, PointVector& pts_matched_in_prev, PointVector& pts_matched_in_frame); + + AlgorithmParamsBasePtr getParams(void); + + private: + + bool initialized_; + + AlgorithmParamsOPTFLOWPYRLKPtr params_ptr_; + + cv::Mat frame_gray_prev_; + + void defineAlgorithm(const ParamsBasePtr _params); +}; + +/* + * brief Retrieve object parameters + */ +inline AlgorithmParamsBasePtr AlgorithmOPTFLOWPYRLK::getParams(void) { return params_ptr_; } + +/* + * brief Define detector + */ +inline void AlgorithmOPTFLOWPYRLK::defineAlgorithm(const ParamsBasePtr _params) +{ + params_base_ptr_ = std::static_pointer_cast<AlgorithmParamsBase>(_params); + params_ptr_ = std::static_pointer_cast<AlgorithmParamsOPTFLOWPYRLK>(_params); +} + +/* + * brief Create object in factory + */ +inline AlgorithmBasePtr AlgorithmOPTFLOWPYRLK::create(const std::string& _unique_name, const ParamsBasePtr _params) +{ + AlgorithmOPTFLOWPYRLKPtr mat_ptr = std::make_shared<AlgorithmOPTFLOWPYRLK>(); + mat_ptr->setName(_unique_name); + mat_ptr->defineAlgorithm(_params); + return mat_ptr; +} + +} /* namespace vision_utils */ + +#endif /* _ALGORITHM_OPTFLOWPYRLK_H_ */ diff --git a/src/algorithms/opticalflowpyrlk/alg_opticalflowpyrlk_load_yaml.cpp b/src/algorithms/opticalflowpyrlk/alg_opticalflowpyrlk_load_yaml.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f1ad13cadf08880025330978533f5521fad89078 --- /dev/null +++ b/src/algorithms/opticalflowpyrlk/alg_opticalflowpyrlk_load_yaml.cpp @@ -0,0 +1,53 @@ +#include "alg_opticalflowpyrlk.h" + +#ifdef USING_YAML + +// yaml-cpp library +#include <yaml-cpp/yaml.h> + +namespace vision_utils +{ + +namespace +{ + +static ParamsBasePtr createParamsOPTFLOWPYRLKAlgorithm(const std::string & _filename_dot_yaml) +{ + AlgorithmParamsOPTFLOWPYRLKPtr params_ptr = std::make_shared<AlgorithmParamsOPTFLOWPYRLK>(); + + using std::string; + using YAML::Node; + Node yaml_params = YAML::LoadFile(_filename_dot_yaml); + if (!yaml_params.IsNull()) + { + Node d_yaml = yaml_params["algorithm"]; + if(d_yaml["type"].as<string>() == "OPTFLOWPYRLK") + { + int win_edge = d_yaml["window edge"].as<int>(); + params_ptr->win_size = cv::Size(win_edge, win_edge); + params_ptr->max_level = d_yaml["max level"].as<int>(); + int criteria_max_count = d_yaml["criteria max count"].as<int>(); + double criteria_epsilon = d_yaml["criteria epsilon"].as<double>(); + params_ptr->criteria = cv::TermCriteria(cv::TermCriteria::COUNT+cv::TermCriteria::EPS, criteria_max_count, criteria_epsilon); + params_ptr->flags = d_yaml["flags"].as<int>(); + params_ptr->min_eig_threshold = d_yaml["min eigen threshold"].as<double>(); + params_ptr->min_err_kpt_match = d_yaml["min error kpt match"].as<double>(); + }else + { + std::cerr << "Bad configuration file. Wrong type " << d_yaml["type"].as<string>() << std::endl; + return nullptr; + } + } + + return params_ptr; +} + +// Register in the SensorFactory +const bool registered_matOPTFLOWPYRLK_params = ParamsFactory::get().registerCreator("OPTFLOWPYRLK ALG", createParamsOPTFLOWPYRLKAlgorithm); + +} /* namespace [unnamed] */ + +} /* namespace vision_utils */ + +#endif /* IF USING_YAML */ + diff --git a/src/cam_utils/cam_utils.cpp b/src/cam_utils/cam_utils.cpp deleted file mode 100644 index d57f926b54c23a59767d5f6de404f76e1dd140d2..0000000000000000000000000000000000000000 --- a/src/cam_utils/cam_utils.cpp +++ /dev/null @@ -1,49 +0,0 @@ -#include "cam_utils.h" - -CCamUtils::CCamUtils() -{ -} - -CCamUtils::~CCamUtils() -{ -} - -bool CCamUtils::openCamera(const int& _cam_num, cv::VideoCapture& _cam) -{ - cv::VideoCapture camera(_cam_num); - if (!camera.isOpened()) // check if we succeeded - { - std::cerr << "ERROR: Could not open camera: " << _cam_num << std::endl; - return false; - } - _cam = camera; - return true; -} - -bool CCamUtils::getFrame(cv::VideoCapture& _cam, cv::Mat& _frame) -{ - try - { - _cam >> _frame; - } - catch (cv::Exception& e) - { - std::cout << "An exception occurred. Ignoring frame. " << e.err << std::endl; - return false; - } - return true; -} - -bool CCamUtils::showFrame(const std::string& _window_name, const cv::Mat& _frame) -{ - try - { - cv::imshow(_window_name, _frame); - } - catch (cv::Exception& e) - { - std::cout << "An exception occurred. Ignoring frame. " << e.err << std::endl; - return false; - } - return true; -} diff --git a/src/cam_utils/cam_utils.h b/src/cam_utils/cam_utils.h deleted file mode 100644 index 5c06fd44e520e57f654c981f2842519f7be71eb1..0000000000000000000000000000000000000000 --- a/src/cam_utils/cam_utils.h +++ /dev/null @@ -1,69 +0,0 @@ -#ifndef _CAMUTILS_H -#define _CAMUTILS_H - -// std stuff -#include <stdio.h> -#include <iostream> - -// OpenCV stuff -#include "opencv2/opencv.hpp" - -class CCamUtils -{ - public: - - /** - * \brief Constructor - * - * Main class constructor. - */ - CCamUtils(); - - /** - * \brief Destructor - * - * Main class destructor. - */ - ~CCamUtils(); - - /** - * \brief Open Webcam - * - * This method opens the specified webcam using OpenCV - * Inputs: - * _cam_num: system camera number (int) - * Ouptuts: - * cam: camera handle (cv::VideoCapture) - * - * Returns true if the camera is correctly opened - * - */ - bool openCamera(const int& _cam_num, cv::VideoCapture& _cam); - - /** - * \brief Get frame - * - * This method gets a frame from the specified webcam - * - * Inputs: - * cam: camera handle (cv::VideoCapture) - * Outputs: - * frame: filled frame (cv::Mat) - * Returns true if the frame is correctly obtained - */ - bool getFrame(cv::VideoCapture& _cam, cv::Mat& _frame); - - /** - *\brief Show Frame - * - * This method shows the specified frame using OpenCV - * - * Inputs: - * window_name: Window name inwhich the frame will be displayed (string) - * frame: Frame to be displayed (cv::Mat) - * Returns true if the frame is correctly displayed - */ - bool showFrame(const std::string& _window_name, const cv::Mat& _frame); -}; - -#endif diff --git a/src/common/factory.h b/src/common/factory.h deleted file mode 100644 index fe451fdbcb272a04c899a52b7bfd342e3224f463..0000000000000000000000000000000000000000 --- a/src/common/factory.h +++ /dev/null @@ -1,330 +0,0 @@ -#ifndef FACTORY_H_ -#define FACTORY_H_ - -// wolf -//#include "wolf.h" - -// std -#include <string> -#include <map> -#include <iostream> -#include <iomanip> - -namespace cv_utils -{ - -/** \brief Singleton template factory - * - * This class implements a generic factory as a singleton. - * - * > IMPORTANT: This template factory can be used to construct many different objects except: - * > - Objects deriving from DetectorBase --> see DetectorFactory - * > - Objects deriving from DescriptorBase --> see DescriptorFactory - * > - Objects deriving from MatcherBase --> see MatcherFactory - * > - * > The reason for this is that the two cases above need a more elaborated API than the one in this template class. - * - * \param TypeBase base type of all the objects created by the factory - * \param TypeInput type of the input argument. Typical cases are std::string for file names, and YAML::Node for YAML nodes. - * - * - The class is templatized on the class of the produced objects, __TypeBase__. - * The produced objects are always of a class deriving from TypeBase. - * The returned data is always a pointer to TypeBase. - * - * For example, you may use as __TypeBase__ the following types: - * - DetectorBase: the Factory creates detectors deriving from DetectorBase and returns base pointers ````DetectorBasePtr```` to them - * - XxxBase: the Factory creates objects deriving from XxxBase and returns pointers ````XxxBasePtr```` to them. - * - * - The class in also templatized on the type of the input parameter of the creator, __TypeInput__: - * - ````std::string```` is used when the input parameter is a file name from which to read data (typically a YAML file). - * - ````YAML::Node```` is used when the input parameter is a YAML node with structured data. - * - * ### Operation of the factory - * - * #### Rationale - * - * This factory can create objects of classes deriving from TypeBase. - * - * > For example, if you want to make a Detector factory, set TypeBase = DetectorBase.\n - * > Then, the factory will create specific detectors deriving from DetectorBase.\n - * > The specific type of detector (e.g. FAST, SIFT, ORB, etc) is indicated by a string that we call TYPE in this documentation. - * - * Specific object creation is invoked by the method ````create(TYPE, params ... )````, where - * - the TYPE of object to create is identified with a string - * - the params may be provided in different forms -- see TypeInput. - * - * The methods to create specific objects are called __creators__. - * Creators must be registered to the factory before they can be invoked for object creation. - * - * This documentation shows you how to: - * - Define correct TYPE names - * - Access the factory - * - Write object creators - * - Register and unregister object creators to the factory - * - Create objects using the factory - * - Examples: Write and register a detector creator for FAST. - * - * #### Define correct TYPE names - * The rule to make new TYPE strings unique is that you skip the generic 'Type' prefix from your class name, - * and you build a string in CAPITALS with space separators, e.g.: - * - ParamsDetectorORB -> ````"ORB PARAMS"```` - * - ParamsMatcherKnn -> ````"KNN PARAMS"```` - * - etc. - * - * #### Access the factory - * The first thing to know is that we have defined typedefs for the templates that we are using. For example: - * - * \code - * typedef Factory<ParamsBase, std::string> ParamsFactory; - * typedef Factory<DetectorBase, std::string> DetectorFactory; - * typedef Factory<DescriptorBase, YAML::Node> DescriptorFactory; - * \endcode - * - * - * Second to know, the Factory class is a <a href="http://stackoverflow.com/questions/1008019/c-singleton-design-pattern#1008289">singleton</a>: it can only exist once in your application. - * To access it, use the static method get(), - * - * \code - * Factory<MyTypeBase, MyTypeInput>::get() - * \endcode - * - * where, of course, you better make use of the appropriate typedef in place of ````Factory<MyTypeBase, MyTypeInput>````. - * - * You can then call the methods you like, e.g. to create a detector, you use: - * - * \code - * DetectorFactory::get().create(...); // see below for creating objects ... - * \endcode - * - * #### Write creator methods (in your derived object classes) - * The method DetectorORB::create(...) exists in the DetectorORB class as a static method. - * All these ````XxxXxx::create()```` methods need to have exactly the same API, regardless of the object type. - * The API puts into play the two template parameters: - * - * \code - * static TypeBase* create( const TypeInput& ); - * \endcode - * - * This API includes an element of type TypeInput, which might be either a std::string, or a YAML::node: - * - ````std::string```` is used to indicate the name of a configuration file. These files are usually YAML files containing configuration data to create your object. - * - ````YAML::Node```` is used to access parts of a YAML file already encoded as nodes, such as when loading landmarks from a SLAM map stored as a YAML file. - * - * - * Two examples: - * - * \code - * static ParamsBasePtr create(const std::string& _params_dot_yaml) - * static DetectorBasePtr create(const YAML::Node& _lmk_yaml_node) - * \endcode - * - * See further down for an implementation example. - * - * #### Register object creators - * Prior to invoking the creation of an object of a particular TYPE, - * you must register the creator for this type into the factory. - * - * Registering object creators into the factory is done through registerCreator(). - * You provide an object TYPE string (above), and a pointer to a static method - * that knows how to create your specific object, e.g.: - * - * \code - * DetectorFactory::get().registerCreator("DETECTOR ORB", DetectorORB::create); - * \endcode - * - * #### Automatic registration - * Currently, registering is performed in specific source files, object_xxxx.cpp. - * For example, in detector_orb_yaml.cpp we find the line: - * - * \code - * const bool registered_detector_params = ParamsFactory::get().registerCreator("ORB PARAMS", createORBParams); - * \endcode - * - * which is a static invocation (i.e., it is placed at global scope outside of the ORBParams class). - * - * Therefore, at application level, all objects that have a .cpp file compiled are automatically registered. - * - * #### Unregister object creators - * The method unregisterCreator() unregisters the ObjectXxx::create() method. It only needs to be passed the string of the object type. - * - * \code - * Factory<MyTypeBase, MyTypeInput>::get().unregisterCreator("CAMERA"); - * \endcode - * - * #### Create objects using the factory - * Note: Prior to invoking the creation of a object of a particular type, - * you must register the creator for this type into the factory. - * - * To create e.g. a DetectorORB from a YAML node you type: - * - * \code - * DetectorBasePtr det_orb_ptr = Factory<DetectorBasePtr, YAML::Node>::get().create("DETECTOR ORB", det_orb_yaml_node); - * \endcode - * - * or even better, make use of the convenient typedefs: - * - * \code - * DetectorBasePtr det_orb_ptr = DetectorFactory::get().create("DETECTOR ORB", det_orb_yaml_node); - * \endcode - * - * ### Examples - * TODO: Update this - * #### Example 1: Writing the creator of DetectorORB from a YAML node - * - * You can find this code in the detector_orb.cpp file. - * - * \code - * // Creator (this method is static): - * DetectorBasePtr DetectorORB::create(const YAML::Node& _det_orb_node) - * { - * // Parse YAML node with lmk info and data - * unsigned int id = _det_orb_node["id"].as<unsigned int>(); - * int first_id = _det_orb_node["first_id"].as<int>(); - * bool first_defined = _det_orb_node["first_defined"].as<bool>(); - * bool last_defined = _det_orb_node["last_defined"].as<bool>(); - * unsigned int npoints = _det_orb_node["points"].size(); - * Eigen::MatrixXs points(2,npoints); - * for (unsigned int i = 0; i < npoints; i++) - * { - * points.col(i) = _lmk_node["points"][i].as<Eigen::Vector2s>(); - * } - * - * // Create a new landmark - * LandmarkBasePtr lmk_ptr = new LandmarkPolyline2D(points, first_defined, last_defined, first_id); - * lmk_ptr->setId(id); - * - * return lmk_ptr; - * } - * \endcode - * - * #### Example 2: Registering the creator of LandmarkPolyline2D from a YAML node - * - * You can find this code in the landmark_polyline_2D.cpp file. - * - * \code - * // Register landmark creator (put the register code inside an unnamed namespace): - * namespace - * { - * const bool registered_lmk_polyline_2D = LandmarkFactory::get().registerCreator("POLYLINE 2D", LandmarkPolyline2D::create); - * } - * - * \endcode - * - * ### More information - * - IntrinsicsFactory: typedef of this template to create intrinsic structs deriving from IntrinsicsBase directly from YAML files. - * - ProcessorParamsFactory: typedef of this template to create processor params structs deriving from ProcessorParamsBase directly from YAML files. - * - LandmarkFactory: typedef of this template to create landmarks deriving from LandmarkBase directly from YAML nodes. - * - Problem::loadMap() : to load a maps directly from YAML files. - * - You can also check the code in the example file ````src/examples/test_map_yaml.cpp````. - * - * #### See also - * - SensorFactory: to create sensors - * - ProcessorFactory: to create processors. - * - Problem::installSensor() : to install sensors in WOLF Problem. - * - Problem::installProcessor() : to install processors in WOLF Problem. - * - */ -template<class TypeBase, typename... TypeInput> -class Factory -{ - typedef std::shared_ptr<TypeBase> TypeBasePtr; - public: - // example of creator callback (see typedefs below) - typedef TypeBasePtr (*CreatorCallback)(TypeInput... _input); - - // Main factory API - bool registerCreator(const std::string& _type, CreatorCallback createFn); - bool unregisterCreator(const std::string& _type); - TypeBasePtr create(const std::string& _type, TypeInput... _input); - std::string getClass(); - - private: - - typedef std::map<std::string, CreatorCallback> CallbackMap; - - CallbackMap callbacks_; - - // Singleton --------------------------------------------------- - // This class is a singleton. The code below guarantees this. - // See: http://stackoverflow.com/questions/1008019/c-singleton-design-pattern - public: - static Factory& get(); - Factory(const Factory&) = delete; - void operator=(Factory const&) = delete; - private: - Factory() { } - ~Factory() { } -}; - -template<class TypeBase, typename... TypeInput> -inline bool Factory<TypeBase, TypeInput...>::registerCreator(const std::string& _type, CreatorCallback createFn) -{ - bool reg = callbacks_.insert(typename CallbackMap::value_type(_type, createFn)).second; - if (reg) - std::cout << std::setw(22) << std::left << getClass() << " <-- registered " << _type << std::endl; - else - std::cout << std::setw(22) << std::left << getClass() << " X-- skipping " << _type << ": already registered." << std::endl; - - return reg; -} - -template<class TypeBase, typename... TypeInput> -inline bool Factory<TypeBase, TypeInput...>::unregisterCreator(const std::string& _type) -{ - return callbacks_.erase(_type) == 1; -} - -template<class TypeBase, typename... TypeInput> -inline typename Factory<TypeBase, TypeInput...>::TypeBasePtr Factory<TypeBase, TypeInput...>::create(const std::string& _type, TypeInput... _input) -{ - typename CallbackMap::const_iterator creator_callback_it = callbacks_.find(_type); - - if (creator_callback_it == callbacks_.end()) - // not found - throw std::runtime_error(getClass() + " : Unknown type \"" + _type + "\". Possibly you tried to use an unregistered creator."); - - // Invoke the creation function - return (creator_callback_it->second)(std::forward<TypeInput>(_input)...); -} - -template<class TypeBase, typename... TypeInput> -inline Factory<TypeBase, TypeInput...>& Factory<TypeBase, TypeInput...>::get() -{ - static Factory instance_; - return instance_; -} - -template<class TypeBase, typename... TypeInput> -inline std::string Factory<TypeBase, TypeInput...>::getClass() -{ - return "Factory<class TypeBase>"; -} - -// Some specializations -//====================== - -// Parameters -struct ParamsBase; -typedef Factory<ParamsBase, - const std::string&> ParamsFactory; -template<> -inline std::string ParamsFactory::getClass() -{ - return "ParamsFactory"; -} - -// Frames -class FrameBase; -class TimeStamp; -typedef Factory<FrameBase, const FrameType&, const TimeStamp&, const Eigen::VectorXs&> FrameFactory; -template<> -inline std::string FrameFactory::getClass() -{ - return "FrameFactory"; -} -#define WOLF_REGISTER_FRAME(FrameType, FrameName) \ - namespace{ const bool FrameName##Registered = \ - FrameFactory::get().registerCreator(FrameType, FrameName::create); }\ - -} /* namespace cv_utils */ - -#endif /* FACTORY_H_ */ diff --git a/src/common/vu_base.h b/src/common/vu_base.h deleted file mode 100644 index b35c0595b7420ffac51af40bda4b98ce30ace379..0000000000000000000000000000000000000000 --- a/src/common/vu_base.h +++ /dev/null @@ -1,217 +0,0 @@ -#ifndef _VU_BASE_H -#define _VU_BASE_H - -// std -#include <functional> -#include <set> -#include <iostream> -#include <map> -#include <vector> -#include <string> -#include <iostream> -#include <time.h> - -// Boost -#include <boost/assign/std/vector.hpp> // for 'operator+=()' -using namespace boost::assign; // bring 'operator+=()' into scope - -// OpenCV -#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 std::vector<cv::KeyPoint> KeyPointVector; -typedef std::vector<cv::KeyPoint> KeyPointVector; -typedef std::vector<cv::line_descriptor::KeyLine> KeyLineVector; - -/** - * \brief Class to set object types - */ -class CTypes { - -public: - - CTypes(void): init_(false) {}; - - ~CTypes(void) {}; - - void set(std::vector<std::string> &_types) - { - for (unsigned int ii = 0; ii < _types.size(); ii++) - types_[_types[ii]] = ii; - init_= true; - }; - - std::vector<std::string> list(void) - { - std::vector<std::string> list; - list.reserve(types_.size()); - for(std::map<std::string,int>::iterator it = types_.begin(); it != types_.end(); ++it) - { - list.push_back(it->first); - } - return list; - } - - int operator()(const std::string &name) { - if (init_) - { - // Search done to take advantage of MAP alphabetical order - int idx = 0; - for (std::map<std::string, int>::const_iterator it = types_.begin();it != types_.end(); ++it) - { - if (it->first.compare(name) == 0) - return idx; - ++idx; - } - - - } - else - { - std::cerr << "[Vision Utils]: Wrong object initialization" << std::cout; - } - return 0; - }; - - std::string operator()(const int &num) { - if (init_) - { - // Search done to take advantage of MAP alphabetical order - int idx = 0; - for (std::map<std::string, int>::const_iterator it = types_.begin();it != types_.end(); ++it) - { - if (num == idx) - return it->first; - ++idx; - } - } - else - std::cerr << "[Vision Utils]: Wrong object initialization" << std::cout; - return 0; - }; - - unsigned int size(void) - { return types_.size(); } - -protected: - - std::map<std::string, int> types_; - bool init_; -}; - -/** - * \brief Class to set object parameters - */ -class CParams { -public: - CParams(void) { - } - ; - ~CParams(void) { - } - ; -}; - - -/** - * \brief Superbase Class - * - * This Super class is created in order to work with pointers to the derived - * classes. Otherwise CSensor_base is templated and does not allow it. - */ -class CVu_Superbase -{ -public: - CVu_Superbase(){}; - virtual ~CVu_Superbase(){}; - -}; - -/** - * \brief base Class - */ -template <class T_PARAMS> -class CVu_Base: public CVu_Superbase { - -public: - - CVu_Base(void): is_init_(false) {}; - - virtual ~CVu_Base(void){}; - - /** - * \brief Get detection duration - */ - double getTime(void){return comp_time_;}; - - /** - * \brief list types - */ - std::vector<std::string> list(void) - { return types_.list();}; - - /** - * \brief Set object without constructor - */ - bool set(const std::string& _type, const T_PARAMS &_params) - { - bool success = init(_type, _params); - return success; - }; - - void get(std::string& _type) - { _type = type_; }; - - void get(int& _type) - { - _type = types_(type_); - }; - - cv::Mat drawKeyFeatures(const cv::Mat& _image, const KeyPointVector& _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 drawKeyFeatures(const cv::Mat& _image, const KeyLineVector& _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; - } - - -protected: - - // Flags - bool is_init_; - - double comp_time_; // Detection time - - CTypes types_; - - std::string type_; - - virtual bool init(const std::string &_type, const T_PARAMS &_params) = 0; - - /** - * \brief Set all types - */ - virtual void setAllTypes(void) = 0; - -}; - -#endif diff --git a/src/descriptors/akaze/descriptor_akaze.cpp b/src/descriptors/akaze/descriptor_akaze.cpp new file mode 100644 index 0000000000000000000000000000000000000000..db9bdc6d5f44afd301f83d732976706e0af66546 --- /dev/null +++ b/src/descriptors/akaze/descriptor_akaze.cpp @@ -0,0 +1,17 @@ +#include "descriptor_akaze.h" + +namespace vision_utils { + +DescriptorAKAZE::DescriptorAKAZE(void) +{} + +DescriptorAKAZE::~DescriptorAKAZE(void) +{} + +} /* namespace vision_utils */ + +// Register in the DescriptorsFactory +namespace vision_utils +{ +VU_REGISTER_DESCRIPTOR("AKAZE", DescriptorAKAZE); +} /* namespace vision_utils */ diff --git a/src/descriptors/akaze/descriptor_akaze.h b/src/descriptors/akaze/descriptor_akaze.h new file mode 100644 index 0000000000000000000000000000000000000000..11979d7ec0f9ba4199da372f09edbec8b3e4df60 --- /dev/null +++ b/src/descriptors/akaze/descriptor_akaze.h @@ -0,0 +1,79 @@ +#ifndef _DESCRIPTOR_AKAZE_H_ +#define _DESCRIPTOR_AKAZE_H_ + +#include "../descriptor_base.h" +#include "../descriptor_factory.h" + +// yaml-cpp library +#ifdef USING_YAML + #include <yaml-cpp/yaml.h> +#endif + +namespace vision_utils { + +// Create all pointers +VU_PTR_TYPEDEFS(DescriptorAKAZE); +VU_PTR_TYPEDEFS(DescriptorParamsAKAZE); + +/** \brief Class parameters + * + */ +struct DescriptorParamsAKAZE: public ParamsBase +{ + int descriptor_type = cv::AKAZE::DESCRIPTOR_MLDB; // Type of the extracted descriptor. DESCRIPTOR_KAZE_UPRIGHT=2, DESCRIPTOR_KAZE=3, DESCRIPTOR_MLDB_UPRIGHT=4, DESCRIPTOR_MLDB=5 + int descriptor_size = 0; // Size of the descriptor in bits. 0 -> Full size + int descriptor_channels = 3; // Number of channels in the descriptor (1, 2, 3) + float threshold = 0.001f; // Descriptor response threshold to accept point + int nOctaves = 4; // Maximum octave evolution of the image + int nOctaveLayers = 4; // Default number of sublevels per scale level + int diffusivity = cv::KAZE::DIFF_PM_G2; // Diffusivity type. DIFF_PM_G1=0, DIFF_PM_G2=1, DIFF_WEICKERT=2, DIFF_CHARBONNIER=3 +}; + +/** \brief DETECTOR class + * + */ +class DescriptorAKAZE : public DescriptorBase { + + public: + DescriptorAKAZE(); + virtual ~DescriptorAKAZE(void); + + // Factory method + static DescriptorBasePtr create(const std::string& _unique_name, const ParamsBasePtr _params); + + private: + + void defineDescriptor(const ParamsBasePtr _params); +}; + +/* + * brief Define detector + */ +inline void DescriptorAKAZE::defineDescriptor(const ParamsBasePtr _params) +{ + DescriptorParamsAKAZEPtr params_ptr = std::static_pointer_cast<DescriptorParamsAKAZE>(_params); + + descriptor_ = cv::AKAZE::create(params_ptr->descriptor_type, + params_ptr->descriptor_size, + params_ptr->descriptor_channels, + params_ptr->threshold, + params_ptr->nOctaves, + params_ptr->nOctaveLayers, + params_ptr->diffusivity); +} + + +/* + * brief Create object in factory + */ +inline DescriptorBasePtr DescriptorAKAZE::create(const std::string& _unique_name, const ParamsBasePtr _params) +{ + DescriptorAKAZEPtr det_ptr = std::make_shared<DescriptorAKAZE>(); + det_ptr->setName(_unique_name); + det_ptr->defineDescriptor(_params); + return det_ptr; +} + +} /* namespace vision_utils */ + +#endif /* _DESCRIPTOR_AKAZE_H_ */ diff --git a/src/descriptors/akaze/descriptor_akaze_load_yaml.cpp b/src/descriptors/akaze/descriptor_akaze_load_yaml.cpp new file mode 100644 index 0000000000000000000000000000000000000000..043ceb070a7a93f2cc7e496674afa8495fbe199a --- /dev/null +++ b/src/descriptors/akaze/descriptor_akaze_load_yaml.cpp @@ -0,0 +1,51 @@ +#include "descriptor_akaze.h" + +#ifdef USING_YAML + +// yaml-cpp library +#include <yaml-cpp/yaml.h> + +namespace vision_utils +{ + +namespace +{ + +static ParamsBasePtr createParamsAKAZEDescriptor(const std::string & _filename_dot_yaml) +{ + DescriptorParamsAKAZEPtr params_ptr = std::make_shared<DescriptorParamsAKAZE>(); + + using std::string; + using YAML::Node; + Node yaml_params = YAML::LoadFile(_filename_dot_yaml); + if (!yaml_params.IsNull()) + { + Node d_yaml = yaml_params["descriptor"]; + if(d_yaml["type"].as<string>() == "AKAZE") + { + params_ptr->descriptor_type = d_yaml["descriptor_type"].as<int>(); + params_ptr->descriptor_size = d_yaml["descriptor_size"].as<int>(); + params_ptr->descriptor_channels = d_yaml["descriptor_channels"].as<int>(); + params_ptr->threshold = d_yaml["threshold"].as<float>(); + params_ptr->nOctaves = d_yaml["nOctaves"].as<int>(); + params_ptr->nOctaveLayers = d_yaml["nOctaveLayers"].as<int>(); + params_ptr->diffusivity = d_yaml["diffusivity"].as<int>(); + }else + { + std::cerr << "Bad configuration file. Wrong type " << d_yaml["type"].as<string>() << std::endl; + return nullptr; + } + } + + return params_ptr; +} + +// Register in the SensorFactory +const bool registered_desAKAZE_params = ParamsFactory::get().registerCreator("AKAZE DES", createParamsAKAZEDescriptor); + +} /* namespace [unnamed] */ + +} /* namespace vision_utils */ + +#endif /* IF USING_YAML */ + diff --git a/src/descriptors/brief/descriptor_brief.cpp b/src/descriptors/brief/descriptor_brief.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d19b78f3827dc19fdba1f145cf639746d5b72107 --- /dev/null +++ b/src/descriptors/brief/descriptor_brief.cpp @@ -0,0 +1,17 @@ +#include "descriptor_brief.h" + +namespace vision_utils { + +DescriptorBRIEF::DescriptorBRIEF(void) +{} + +DescriptorBRIEF::~DescriptorBRIEF(void) +{} + +} /* namespace vision_utils */ + +// Register in the DescriptorsFactory +namespace vision_utils +{ +VU_REGISTER_DESCRIPTOR("BRIEF", DescriptorBRIEF); +} /* namespace vision_utils */ diff --git a/src/descriptors/brief/descriptor_brief.h b/src/descriptors/brief/descriptor_brief.h new file mode 100644 index 0000000000000000000000000000000000000000..a128d4a553bf3cb334f4168256491e7f0025fd02 --- /dev/null +++ b/src/descriptors/brief/descriptor_brief.h @@ -0,0 +1,69 @@ +#ifndef _DESCRIPTOR_BRIEF_H_ +#define _DESCRIPTOR_BRIEF_H_ + +#include "../descriptor_base.h" +#include "../descriptor_factory.h" + +// yaml-cpp library +#ifdef USING_YAML + #include <yaml-cpp/yaml.h> +#endif + +namespace vision_utils { + +// Create all pointers +VU_PTR_TYPEDEFS(DescriptorBRIEF); +VU_PTR_TYPEDEFS(DescriptorParamsBRIEF); + +/** \brief Class parameters + * + */ +struct DescriptorParamsBRIEF: public ParamsBase +{ + int bytes = 32; // Legth of the descriptor in bytes, valid values are: 16, 32 (default) or 64 . + bool use_orientation = false; // Sample patterns using keypoints orientation, disabled by default. +}; + +/** \brief DETECTOR class + * + */ +class DescriptorBRIEF : public DescriptorBase { + + public: + DescriptorBRIEF(); + virtual ~DescriptorBRIEF(void); + + // Factory method + static DescriptorBasePtr create(const std::string& _unique_name, const ParamsBasePtr _params); + + private: + + void defineDescriptor(const ParamsBasePtr _params); +}; + +/* + * brief Define detector + */ +inline void DescriptorBRIEF::defineDescriptor(const ParamsBasePtr _params) +{ + DescriptorParamsBRIEFPtr params_ptr = std::static_pointer_cast<DescriptorParamsBRIEF>(_params); + + descriptor_ = cv::xfeatures2d::BriefDescriptorExtractor::create(params_ptr->bytes, + params_ptr->use_orientation); +} + + +/* + * brief Create object in factory + */ +inline DescriptorBasePtr DescriptorBRIEF::create(const std::string& _unique_name, const ParamsBasePtr _params) +{ + DescriptorBRIEFPtr det_ptr = std::make_shared<DescriptorBRIEF>(); + det_ptr->setName(_unique_name); + det_ptr->defineDescriptor(_params); + return det_ptr; +} + +} /* namespace vision_utils */ + +#endif /* _DESCRIPTOR_BRIEF_H_ */ diff --git a/src/descriptors/brief/descriptor_brief_load_yaml.cpp b/src/descriptors/brief/descriptor_brief_load_yaml.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6e79ed44e7edaada9d5ff28b2dc2618e12243ce5 --- /dev/null +++ b/src/descriptors/brief/descriptor_brief_load_yaml.cpp @@ -0,0 +1,46 @@ +#include "descriptor_brief.h" + +#ifdef USING_YAML + +// yaml-cpp library +#include <yaml-cpp/yaml.h> + +namespace vision_utils +{ + +namespace +{ + +static ParamsBasePtr createParamsBRIEFDescriptor(const std::string & _filename_dot_yaml) +{ + DescriptorParamsBRIEFPtr params_ptr = std::make_shared<DescriptorParamsBRIEF>(); + + using std::string; + using YAML::Node; + Node yaml_params = YAML::LoadFile(_filename_dot_yaml); + if (!yaml_params.IsNull()) + { + Node d_yaml = yaml_params["descriptor"]; + if(d_yaml["type"].as<string>() == "BRIEF") + { + params_ptr->bytes = d_yaml["bytes"].as<int>(); + params_ptr->use_orientation = d_yaml["use_orientation"].as<bool>(); + }else + { + std::cerr << "Bad configuration file. Wrong type " << d_yaml["type"].as<string>() << std::endl; + return nullptr; + } + } + + return params_ptr; +} + +// Register in the SensorFactory +const bool registered_desBRIEF_params = ParamsFactory::get().registerCreator("BRIEF DES", createParamsBRIEFDescriptor); + +} /* namespace [unnamed] */ + +} /* namespace vision_utils */ + +#endif /* IF USING_YAML */ + diff --git a/src/descriptors/brisk/descriptor_brisk.cpp b/src/descriptors/brisk/descriptor_brisk.cpp new file mode 100644 index 0000000000000000000000000000000000000000..55c9f5e6e2a3f1b2ace9d08d70b1f4b4bbd1be1d --- /dev/null +++ b/src/descriptors/brisk/descriptor_brisk.cpp @@ -0,0 +1,17 @@ +#include "descriptor_brisk.h" + +namespace vision_utils { + +DescriptorBRISK::DescriptorBRISK(void) +{} + +DescriptorBRISK::~DescriptorBRISK(void) +{} + +} /* namespace vision_utils */ + +// Register in the DescriptorsFactory +namespace vision_utils +{ +VU_REGISTER_DESCRIPTOR("BRISK", DescriptorBRISK); +} /* namespace vision_utils */ diff --git a/src/descriptors/brisk/descriptor_brisk.h b/src/descriptors/brisk/descriptor_brisk.h new file mode 100644 index 0000000000000000000000000000000000000000..59421a660f3b9b218f31e416693842e626a753f2 --- /dev/null +++ b/src/descriptors/brisk/descriptor_brisk.h @@ -0,0 +1,71 @@ +#ifndef _DESCRIPTOR_BRISK_H_ +#define _DESCRIPTOR_BRISK_H_ + +#include "../descriptor_base.h" +#include "../descriptor_factory.h" + +// yaml-cpp library +#ifdef USING_YAML + #include <yaml-cpp/yaml.h> +#endif + +namespace vision_utils { + +// Create all pointers +VU_PTR_TYPEDEFS(DescriptorBRISK); +VU_PTR_TYPEDEFS(DescriptorParamsBRISK); + +/** \brief Class parameters + * + */ +struct DescriptorParamsBRISK: public ParamsBase +{ + int thresh = 30; // FAST/AGAST detection threshold score. + int octaves = 3; // Detection octaves. Use 0 to do single scale. + float patternScale = 1.0f; // Apply this scale to the pattern used for sampling the neighbourhood of a keypoint. +}; + +/** \brief DETECTOR class + * + */ +class DescriptorBRISK : public DescriptorBase { + + public: + DescriptorBRISK(); + virtual ~DescriptorBRISK(void); + + // Factory method + static DescriptorBasePtr create(const std::string& _unique_name, const ParamsBasePtr _params); + + private: + + void defineDescriptor(const ParamsBasePtr _params); +}; + +/* + * brief Define detector + */ +inline void DescriptorBRISK::defineDescriptor(const ParamsBasePtr _params) +{ + DescriptorParamsBRISKPtr params_ptr = std::static_pointer_cast<DescriptorParamsBRISK>(_params); + + descriptor_ = cv::BRISK::create(params_ptr->thresh, + params_ptr->octaves, + params_ptr->patternScale); +} + + +/* + * brief Create object in factory + */ +inline DescriptorBasePtr DescriptorBRISK::create(const std::string& _unique_name, const ParamsBasePtr _params) +{ + DescriptorBRISKPtr det_ptr = std::make_shared<DescriptorBRISK>(); + det_ptr->setName(_unique_name); + det_ptr->defineDescriptor(_params); + return det_ptr; +} + +} /* namespace vision_utils */ + +#endif /* _DESCRIPTOR_BRISK_H_ */ diff --git a/src/descriptors/brisk/descriptor_brisk_load_yaml.cpp b/src/descriptors/brisk/descriptor_brisk_load_yaml.cpp new file mode 100644 index 0000000000000000000000000000000000000000..394084b47ae57956906f96715b10e3f5b258137f --- /dev/null +++ b/src/descriptors/brisk/descriptor_brisk_load_yaml.cpp @@ -0,0 +1,47 @@ +#include "descriptor_brisk.h" + +#ifdef USING_YAML + +// yaml-cpp library +#include <yaml-cpp/yaml.h> + +namespace vision_utils +{ + +namespace +{ + +static ParamsBasePtr createParamsBRISKDescriptor(const std::string & _filename_dot_yaml) +{ + DescriptorParamsBRISKPtr params_ptr = std::make_shared<DescriptorParamsBRISK>(); + + using std::string; + using YAML::Node; + Node yaml_params = YAML::LoadFile(_filename_dot_yaml); + if (!yaml_params.IsNull()) + { + Node d_yaml = yaml_params["descriptor"]; + if(d_yaml["type"].as<string>() == "BRISK") + { + params_ptr->thresh = d_yaml["thresh"].as<int>(); + params_ptr->octaves = d_yaml["octaves"].as<int>(); + params_ptr->patternScale = d_yaml["patternScale"].as<float>(); + }else + { + std::cerr << "Bad configuration file. Wrong type " << d_yaml["type"].as<string>() << std::endl; + return nullptr; + } + } + + return params_ptr; +} + +// Register in the SensorFactory +const bool registered_desBRISK_params = ParamsFactory::get().registerCreator("BRISK DES", createParamsBRISKDescriptor); + +} /* namespace [unnamed] */ + +} /* namespace vision_utils */ + +#endif /* IF USING_YAML */ + diff --git a/src/descriptors/daisy/descriptor_daisy.cpp b/src/descriptors/daisy/descriptor_daisy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..788b0fe2106e855ef6534224cc50da2f427ab830 --- /dev/null +++ b/src/descriptors/daisy/descriptor_daisy.cpp @@ -0,0 +1,17 @@ +#include "descriptor_daisy.h" + +namespace vision_utils { + +DescriptorDAISY::DescriptorDAISY(void) +{} + +DescriptorDAISY::~DescriptorDAISY(void) +{} + +} /* namespace vision_utils */ + +// Register in the DescriptorsFactory +namespace vision_utils +{ +VU_REGISTER_DESCRIPTOR("DAISY", DescriptorDAISY); +} /* namespace vision_utils */ diff --git a/src/descriptors/daisy/descriptor_daisy.h b/src/descriptors/daisy/descriptor_daisy.h new file mode 100644 index 0000000000000000000000000000000000000000..9d949c2591694143d421fb62c69144db53654165 --- /dev/null +++ b/src/descriptors/daisy/descriptor_daisy.h @@ -0,0 +1,81 @@ +#ifndef _DESCRIPTOR_DAISY_H_ +#define _DESCRIPTOR_DAISY_H_ + +#include "../descriptor_base.h" +#include "../descriptor_factory.h" + +// yaml-cpp library +#ifdef USING_YAML + #include <yaml-cpp/yaml.h> +#endif + +namespace vision_utils { + +// Create all pointers +VU_PTR_TYPEDEFS(DescriptorDAISY); +VU_PTR_TYPEDEFS(DescriptorParamsDAISY); + +/** \DAISY Class parameters + * + */ +struct DescriptorParamsDAISY: public ParamsBase +{ + float radius = 15; // Radius of the descriptor at the initial scale + int q_radius = 3; // Amount of radial range division quantity + int q_theta = 8; // Amount of angular range division quantity + int q_hist = 8; // Amount of gradient orientations range division quantity + int norm = cv::xfeatures2d::DAISY::NRM_NONE; // Descriptors normalization type. DAISY::NRM_NONE=100 will not do any normalization (default), DAISY::NRM_PARTIAL=101 mean that histograms are normalized independently for L2 norm equal to 1.0, DAISY::NRM_FULL=102 mean that descriptors are normalized for L2 norm equal to 1.0, DAISY::NRM_SIFT=103 mean that descriptors are normalized for L2 norm equal to 1.0 but no individual one is bigger than 0.154 as in SIFT + cv::InputOutputArray H = cv::noArray(); // Optional 3x3 homography matrix used to warp the grid of daisy but sampling keypoints remains unwarped on image + bool interpolation = true; // Switch to disable interpolation for speed improvement at minor quality loss + bool use_orientation = false; // Sample patterns using keypoints orientation, disabled by default +}; + +/** \DAISY DETECTOR class + * + */ +class DescriptorDAISY : public DescriptorBase { + + public: + DescriptorDAISY(); + virtual ~DescriptorDAISY(void); + + // Factory method + static DescriptorBasePtr create(const std::string& _unique_name, const ParamsBasePtr _params); + + private: + + void defineDescriptor(const ParamsBasePtr _params); +}; + +/* + * DAISY Define detector + */ +inline void DescriptorDAISY::defineDescriptor(const ParamsBasePtr _params) +{ + DescriptorParamsDAISYPtr params_ptr = std::static_pointer_cast<DescriptorParamsDAISY>(_params); + + descriptor_ = cv::xfeatures2d::DAISY::create(params_ptr->radius, + params_ptr->q_radius, + params_ptr->q_theta, + params_ptr->q_hist, + params_ptr->norm, + params_ptr->H, + params_ptr->interpolation, + params_ptr->use_orientation); +} + + +/* + * DAISY Create object in factory + */ +inline DescriptorBasePtr DescriptorDAISY::create(const std::string& _unique_name, const ParamsBasePtr _params) +{ + DescriptorDAISYPtr det_ptr = std::make_shared<DescriptorDAISY>(); + det_ptr->setName(_unique_name); + det_ptr->defineDescriptor(_params); + return det_ptr; +} + +} /* namespace vision_utils */ + +#endif /* _DESCRIPTOR_DAISY_H_ */ diff --git a/src/descriptors/daisy/descriptor_daisy_load_yaml.cpp b/src/descriptors/daisy/descriptor_daisy_load_yaml.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b714a9e60a875ba63a429381a2bd238ab856799b --- /dev/null +++ b/src/descriptors/daisy/descriptor_daisy_load_yaml.cpp @@ -0,0 +1,53 @@ +#include "descriptor_daisy.h" + +#ifdef USING_YAML + +// yaml-cpp library +#include <yaml-cpp/yaml.h> + +namespace vision_utils +{ + +namespace +{ + +static ParamsBasePtr createParamsDAISYDescriptor(const std::string & _filename_dot_yaml) +{ + DescriptorParamsDAISYPtr params_ptr = std::make_shared<DescriptorParamsDAISY>(); + + using std::string; + using YAML::Node; + Node yaml_params = YAML::LoadFile(_filename_dot_yaml); + if (!yaml_params.IsNull()) + { + Node d_yaml = yaml_params["descriptor"]; + if(d_yaml["type"].as<string>() == "DAISY") + { + params_ptr->radius = d_yaml["radius"].as<float>(); + params_ptr->q_radius = d_yaml["q_radius"].as<int>(); + params_ptr->q_theta = d_yaml["q_theta"].as<int>(); + params_ptr->q_hist = d_yaml["q_hist"].as<int>(); + params_ptr->norm = d_yaml["norm"].as<int>(); + // Currently not implemented + // std::vector<std::vector<float> > Hread = d_yaml["H"].as<std::vector<std::vector<float> > >(); + params_ptr->interpolation = d_yaml["interpolation"].as<bool>(); + params_ptr->use_orientation = d_yaml["use_orientation"].as<bool>(); + }else + { + std::cerr << "Bad configuration file. Wrong type " << d_yaml["type"].as<string>() << std::endl; + return nullptr; + } + } + + return params_ptr; +} + +// Register in the SensorFactory +const bool registered_desDAISY_params = ParamsFactory::get().registerCreator("DAISY DES", createParamsDAISYDescriptor); + +} /* namespace [unnamed] */ + +} /* namespace vision_utils */ + +#endif /* IF USING_YAML */ + diff --git a/src/descriptors/descriptor_base.cpp b/src/descriptors/descriptor_base.cpp new file mode 100644 index 0000000000000000000000000000000000000000..af912459197525ab6a6b5ffaa698cce27107083f --- /dev/null +++ b/src/descriptors/descriptor_base.cpp @@ -0,0 +1,46 @@ +#include "descriptor_base.h" + +namespace vision_utils { + +DescriptorBase::DescriptorBase(void) +{ +} + +DescriptorBase::~DescriptorBase(void) +{ +} + +cv::Mat DescriptorBase::getDescriptor(const cv::Mat& _image, KeyPointVector& _kpts) +{ + cv::Mat descriptors; + + clock_t tStart = clock(); + if (!_kpts.empty()) + descriptor_->compute(_image, _kpts, descriptors); + comp_time_ = (double)(clock() - tStart) / CLOCKS_PER_SEC; + + return descriptors; +} + +} /* namespace vision_utils */ + +#include "descriptor_factory.h" + +namespace vision_utils +{ + +DescriptorBasePtr setupDescriptor(const std::string& _type, const std::string& _unique_name, const ParamsBasePtr& _params) +{ + DescriptorBasePtr des_ptr = DescriptorFactory::get().create(_type, _unique_name, _params); + return des_ptr; +}; + +#ifdef USING_YAML +DescriptorBasePtr setupDescriptor(const std::string& _type, const std::string& _unique_name, const std::string& _filename_dot_yaml) +{ + ParamsBasePtr params_ptr = ParamsFactory::get().create(_type+" DES", _filename_dot_yaml); + return setupDescriptor(_type, _unique_name, params_ptr); +} +#endif + +} /* namespace vision_utils */ diff --git a/src/descriptors/descriptor_base.h b/src/descriptors/descriptor_base.h new file mode 100644 index 0000000000000000000000000000000000000000..c3b1202b75eeb51c119cf2024aca7a89d1862eaa --- /dev/null +++ b/src/descriptors/descriptor_base.h @@ -0,0 +1,75 @@ +#ifndef _DESCRIPTOR_BASE_H_ +#define _DESCRIPTOR_BASE_H_ + +// vision_utils +#include "../vision_utils.h" + +typedef cv::Ptr<cv::DescriptorExtractor> FeatureDescriptorPtr; + +namespace vision_utils +{ + +///////////////////////////////////////////////////////////////////////// +// CLASS DEFINITIONS +///////////////////////////////////////////////////////////////////////// + +// Create all pointers +VU_PTR_TYPEDEFS(DescriptorBase); + +/** \brief base class for Descriptor base + * + * Derive from this class to create Descriptor base class parameters. + */ +class DescriptorBase : public VUBase, public std::enable_shared_from_this<DescriptorBase> +{ + public: + + /** + * \brief Constructor without parameters + */ + DescriptorBase(void); + + /** + * \brief Virtual destructor + */ + virtual ~DescriptorBase(void); + + cv::Mat getDescriptor(const cv::Mat& _image, KeyPointVector& _kpts); + + std::string getName(void); + + // Factory method + static DescriptorBasePtr create(const std::string& _unique_name, const ParamsBasePtr _params); + + protected: + + std::string name_; + + FeatureDescriptorPtr descriptor_; + + void setName(const std::string& _name); + + virtual void defineDescriptor(const ParamsBasePtr _params) = 0; +}; + +/* + * brief Retrieve object name + */ +inline std::string DescriptorBase::getName(void) { return name_; } + +/* + * brief Set object name + */ +inline void DescriptorBase::setName(const std::string& _name){ name_ = _name; } + +/* + * brief Setup and get the corresponding pointer + */ +DescriptorBasePtr setupDescriptor(const std::string& _type, const std::string& _unique_name, const ParamsBasePtr& _params); +#ifdef USING_YAML +DescriptorBasePtr setupDescriptor(const std::string& _type, const std::string& _unique_name, const std::string& _filename_dot_yaml); +#endif + +} /* namespace vision_utils */ + +#endif /* _DESCRIPTOR_BASE_H_ */ diff --git a/src/descriptors/descriptor_factory.h b/src/descriptors/descriptor_factory.h new file mode 100644 index 0000000000000000000000000000000000000000..0ce949336853686a143869ff25910e2839146591 --- /dev/null +++ b/src/descriptors/descriptor_factory.h @@ -0,0 +1,32 @@ +#ifndef _DESCRIPTOR_FACTORY_H_ +#define _DESCRIPTOR_FACTORY_H_ + +namespace vision_utils +{ +class DescriptorBase; +struct DescriptorParamsBase; +} + +#include "../factory.h" + +namespace vision_utils +{ + +/* Descriptor Factory */ +typedef Factory<DescriptorBase, + const std::string&, + const ParamsBasePtr> DescriptorFactory; + +template<> +inline std::string DescriptorFactory::getClass() +{ + return "DescriptorFactory"; +} + +#define VU_REGISTER_DESCRIPTOR(DescriptorType, DescriptorName) \ + namespace{ const bool DescriptorName##Registered = \ + DescriptorFactory::get().registerCreator(DescriptorType, DescriptorName::create, true); }\ + +} /* namespace vision_utils */ + +#endif /* _DESCRIPTOR_FACTORY_H_ */ diff --git a/src/descriptors/freak/descriptor_freak.cpp b/src/descriptors/freak/descriptor_freak.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7a93b418c61399a8a80f2a98088ce11b8f55e023 --- /dev/null +++ b/src/descriptors/freak/descriptor_freak.cpp @@ -0,0 +1,17 @@ +#include "descriptor_freak.h" + +namespace vision_utils { + +DescriptorFREAK::DescriptorFREAK(void) +{} + +DescriptorFREAK::~DescriptorFREAK(void) +{} + +} /* namespace vision_utils */ + +// Register in the DescriptorsFactory +namespace vision_utils +{ +VU_REGISTER_DESCRIPTOR("FREAK", DescriptorFREAK); +} /* namespace vision_utils */ diff --git a/src/descriptors/freak/descriptor_freak.h b/src/descriptors/freak/descriptor_freak.h new file mode 100644 index 0000000000000000000000000000000000000000..18cf5ca2f167e783646bbb974831890d29d9a4a6 --- /dev/null +++ b/src/descriptors/freak/descriptor_freak.h @@ -0,0 +1,75 @@ +#ifndef _DESCRIPTOR_FREAK_H_ +#define _DESCRIPTOR_FREAK_H_ + +#include "../descriptor_base.h" +#include "../descriptor_factory.h" + +// yaml-cpp library +#ifdef USING_YAML + #include <yaml-cpp/yaml.h> +#endif + +namespace vision_utils { + +// Create all pointers +VU_PTR_TYPEDEFS(DescriptorFREAK); +VU_PTR_TYPEDEFS(DescriptorParamsFREAK); + +/** \brief Class parameters + * + */ +struct DescriptorParamsFREAK: public ParamsBase +{ + bool orientationNormalized = true; // Enable orientation normalization. + bool scaleNormalized = true; // Enable scale normalization. + float patternScale = 22.0; // Scaling of the description pattern. + int nOctaves = 4; // Number of octaves covered by the detected keypoints. + std::vector< int > selectedPairs = std::vector< int >(); // (Optional) user defined selected pairs indexes, +}; + +/** \brief DETECTOR class + * + */ +class DescriptorFREAK : public DescriptorBase { + + public: + DescriptorFREAK(); + virtual ~DescriptorFREAK(void); + + // Factory method + static DescriptorBasePtr create(const std::string& _unique_name, const ParamsBasePtr _params); + + private: + + void defineDescriptor(const ParamsBasePtr _params); +}; + +/* + * brief Define detector + */ +inline void DescriptorFREAK::defineDescriptor(const ParamsBasePtr _params) +{ + DescriptorParamsFREAKPtr params_ptr = std::static_pointer_cast<DescriptorParamsFREAK>(_params); + + descriptor_ = cv::xfeatures2d::FREAK::create(params_ptr->orientationNormalized, + params_ptr->scaleNormalized, + params_ptr->patternScale, + params_ptr->nOctaves, + params_ptr->selectedPairs); +} + + +/* + * brief Create object in factory + */ +inline DescriptorBasePtr DescriptorFREAK::create(const std::string& _unique_name, const ParamsBasePtr _params) +{ + DescriptorFREAKPtr det_ptr = std::make_shared<DescriptorFREAK>(); + det_ptr->setName(_unique_name); + det_ptr->defineDescriptor(_params); + return det_ptr; +} + +} /* namespace vision_utils */ + +#endif /* _DESCRIPTOR_FREAK_H_ */ diff --git a/src/descriptors/freak/descriptor_freak_load_yaml.cpp b/src/descriptors/freak/descriptor_freak_load_yaml.cpp new file mode 100644 index 0000000000000000000000000000000000000000..08a869eb443004b074597e7f60e7a60621f06d7c --- /dev/null +++ b/src/descriptors/freak/descriptor_freak_load_yaml.cpp @@ -0,0 +1,49 @@ +#include "descriptor_freak.h" + +#ifdef USING_YAML + +// yaml-cpp library +#include <yaml-cpp/yaml.h> + +namespace vision_utils +{ + +namespace +{ + +static ParamsBasePtr createParamsFREAKDescriptor(const std::string & _filename_dot_yaml) +{ + DescriptorParamsFREAKPtr params_ptr = std::make_shared<DescriptorParamsFREAK>(); + + using std::string; + using YAML::Node; + Node yaml_params = YAML::LoadFile(_filename_dot_yaml); + if (!yaml_params.IsNull()) + { + Node d_yaml = yaml_params["descriptor"]; + if(d_yaml["type"].as<string>() == "FREAK") + { + params_ptr->orientationNormalized = d_yaml["orientationNormalized"].as<bool>(); + params_ptr->scaleNormalized = d_yaml["scaleNormalized"].as<bool>(); + params_ptr->patternScale = d_yaml["patternScale"].as<float>(); + params_ptr->nOctaves = d_yaml["nOctaves"].as<int>(); + params_ptr->selectedPairs = d_yaml["selectedPairs"].as<std::vector< int > >(); + }else + { + std::cerr << "Bad configuration file. Wrong type " << d_yaml["type"].as<string>() << std::endl; + return nullptr; + } + } + + return params_ptr; +} + +// Register in the SensorFactory +const bool registered_desFREAK_params = ParamsFactory::get().registerCreator("FREAK DES", createParamsFREAKDescriptor); + +} /* namespace [unnamed] */ + +} /* namespace vision_utils */ + +#endif /* IF USING_YAML */ + diff --git a/src/descriptors/kaze/descriptor_kaze.cpp b/src/descriptors/kaze/descriptor_kaze.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2cd80cba238a9efd120d0efa8ffd81237cbb6f5c --- /dev/null +++ b/src/descriptors/kaze/descriptor_kaze.cpp @@ -0,0 +1,17 @@ +#include "descriptor_kaze.h" + +namespace vision_utils { + +DescriptorKAZE::DescriptorKAZE(void) +{} + +DescriptorKAZE::~DescriptorKAZE(void) +{} + +} /* namespace vision_utils */ + +// Register in the DescriptorsFactory +namespace vision_utils +{ +VU_REGISTER_DESCRIPTOR("KAZE", DescriptorKAZE); +} /* namespace vision_utils */ diff --git a/src/descriptors/kaze/descriptor_kaze.h b/src/descriptors/kaze/descriptor_kaze.h new file mode 100644 index 0000000000000000000000000000000000000000..4b0a8758ca16363f69f342920c28fc828471cd75 --- /dev/null +++ b/src/descriptors/kaze/descriptor_kaze.h @@ -0,0 +1,77 @@ +#ifndef _DESCRIPTOR_KAZE_H_ +#define _DESCRIPTOR_KAZE_H_ + +#include "../descriptor_base.h" +#include "../descriptor_factory.h" + +// yaml-cpp library +#ifdef USING_YAML + #include <yaml-cpp/yaml.h> +#endif + +namespace vision_utils { + +// Create all pointers +VU_PTR_TYPEDEFS(DescriptorKAZE); +VU_PTR_TYPEDEFS(DescriptorParamsKAZE); + +/** \brief Class parameters + * + */ +struct DescriptorParamsKAZE: public ParamsBase +{ + bool extended = false; // Set to enable extraction of extended (128-byte) descriptor. + bool upright = false; // Set to enable use of upright descriptors (non rotation-invariant). + float threshold = 0.001f; // Descriptor response threshold to accept point + int nOctaves = 4; // Maximum octave evolution of the image + int nOctaveLayers = 4; // Default number of sublevels per scale level + int diffusivity = cv::KAZE::DIFF_PM_G2; // Diffusivity type. DIFF_PM_G1, DIFF_PM_G2, DIFF_WEICKERT or DIFF_CHARBONNIER +}; + +/** \brief DETECTOR class + * + */ +class DescriptorKAZE : public DescriptorBase { + + public: + DescriptorKAZE(); + virtual ~DescriptorKAZE(void); + + // Factory method + static DescriptorBasePtr create(const std::string& _unique_name, const ParamsBasePtr _params); + + private: + + void defineDescriptor(const ParamsBasePtr _params); +}; + +/* + * brief Define detector + */ +inline void DescriptorKAZE::defineDescriptor(const ParamsBasePtr _params) +{ + DescriptorParamsKAZEPtr params_ptr = std::static_pointer_cast<DescriptorParamsKAZE>(_params); + + descriptor_ = cv::KAZE::create(params_ptr->extended, + params_ptr->upright, + params_ptr->threshold, + params_ptr->nOctaves, + params_ptr->nOctaveLayers, + params_ptr->diffusivity); +} + + +/* + * brief Create object in factory + */ +inline DescriptorBasePtr DescriptorKAZE::create(const std::string& _unique_name, const ParamsBasePtr _params) +{ + DescriptorKAZEPtr det_ptr = std::make_shared<DescriptorKAZE>(); + det_ptr->setName(_unique_name); + det_ptr->defineDescriptor(_params); + return det_ptr; +} + +} /* namespace vision_utils */ + +#endif /* _DESCRIPTOR_KAZE_H_ */ diff --git a/src/descriptors/kaze/descriptor_kaze_load_yaml.cpp b/src/descriptors/kaze/descriptor_kaze_load_yaml.cpp new file mode 100644 index 0000000000000000000000000000000000000000..63fd5edd7e2605a0e51bf23fdadbafdc7365de53 --- /dev/null +++ b/src/descriptors/kaze/descriptor_kaze_load_yaml.cpp @@ -0,0 +1,50 @@ +#include "descriptor_kaze.h" + +#ifdef USING_YAML + +// yaml-cpp library +#include <yaml-cpp/yaml.h> + +namespace vision_utils +{ + +namespace +{ + +static ParamsBasePtr createParamsKAZEDescriptor(const std::string & _filename_dot_yaml) +{ + DescriptorParamsKAZEPtr params_ptr = std::make_shared<DescriptorParamsKAZE>(); + + using std::string; + using YAML::Node; + Node yaml_params = YAML::LoadFile(_filename_dot_yaml); + if (!yaml_params.IsNull()) + { + Node d_yaml = yaml_params["descriptor"]; + if(d_yaml["type"].as<string>() == "KAZE") + { + params_ptr->extended = d_yaml["extended"].as<bool>(); + params_ptr->upright = d_yaml["upright"].as<bool>(); + params_ptr->threshold = d_yaml["threshold"].as<float>(); + params_ptr->nOctaves = d_yaml["nOctaves"].as<int>(); + params_ptr->nOctaveLayers = d_yaml["nOctaveLayers"].as<int>(); + params_ptr->diffusivity = d_yaml["diffusivity"].as<int>(); + }else + { + std::cerr << "Bad configuration file. Wrong type " << d_yaml["type"].as<string>() << std::endl; + return nullptr; + } + } + + return params_ptr; +} + +// Register in the SensorFactory +const bool registered_desKAZE_params = ParamsFactory::get().registerCreator("KAZE DES", createParamsKAZEDescriptor); + +} /* namespace [unnamed] */ + +} /* namespace vision_utils */ + +#endif /* IF USING_YAML */ + diff --git a/src/descriptors/latch/descriptor_latch.cpp b/src/descriptors/latch/descriptor_latch.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bfa0cce083d14baef6dea719b5fd9267a13136d5 --- /dev/null +++ b/src/descriptors/latch/descriptor_latch.cpp @@ -0,0 +1,17 @@ +#include "descriptor_latch.h" + +namespace vision_utils { + +DescriptorLATCH::DescriptorLATCH(void) +{} + +DescriptorLATCH::~DescriptorLATCH(void) +{} + +} /* namespace vision_utils */ + +// Register in the DescriptorsFactory +namespace vision_utils +{ +VU_REGISTER_DESCRIPTOR("LATCH", DescriptorLATCH); +} /* namespace vision_utils */ diff --git a/src/descriptors/latch/descriptor_latch.h b/src/descriptors/latch/descriptor_latch.h new file mode 100644 index 0000000000000000000000000000000000000000..56b0ae28beda43861934311a274b299a159a4409 --- /dev/null +++ b/src/descriptors/latch/descriptor_latch.h @@ -0,0 +1,71 @@ +#ifndef _DESCRIPTOR_LATCH_H_ +#define _DESCRIPTOR_LATCH_H_ + +#include "../descriptor_base.h" +#include "../descriptor_factory.h" + +// yaml-cpp library +#ifdef USING_YAML + #include <yaml-cpp/yaml.h> +#endif + +namespace vision_utils { + +// Create all pointers +VU_PTR_TYPEDEFS(DescriptorLATCH); +VU_PTR_TYPEDEFS(DescriptorParamsLATCH); + +/** \brief Class parameters + * + */ +struct DescriptorParamsLATCH: public ParamsBase +{ + int bytes = 32; // Size of the descriptor - can be 64, 32, 16, 8, 4, 2 or 1 + bool rotationInvariance = true; // Whether or not the descriptor should compansate for orientation changes + int half_ssd_size = 3; // Size of half of the mini-patches size +}; + +/** \brief DETECTOR class + * + */ +class DescriptorLATCH : public DescriptorBase { + + public: + DescriptorLATCH(); + virtual ~DescriptorLATCH(void); + + // Factory method + static DescriptorBasePtr create(const std::string& _unique_name, const ParamsBasePtr _params); + + private: + + void defineDescriptor(const ParamsBasePtr _params); +}; + +/* + * brief Define detector + */ +inline void DescriptorLATCH::defineDescriptor(const ParamsBasePtr _params) +{ + DescriptorParamsLATCHPtr params_ptr = std::static_pointer_cast<DescriptorParamsLATCH>(_params); + + descriptor_ = cv::xfeatures2d::LATCH::create(params_ptr->bytes, + params_ptr->rotationInvariance, + params_ptr->half_ssd_size); +} + + +/* + * brief Create object in factory + */ +inline DescriptorBasePtr DescriptorLATCH::create(const std::string& _unique_name, const ParamsBasePtr _params) +{ + DescriptorLATCHPtr det_ptr = std::make_shared<DescriptorLATCH>(); + det_ptr->setName(_unique_name); + det_ptr->defineDescriptor(_params); + return det_ptr; +} + +} /* namespace vision_utils */ + +#endif /* _DESCRIPTOR_LATCH_H_ */ diff --git a/src/descriptors/latch/descriptor_latch_load_yaml.cpp b/src/descriptors/latch/descriptor_latch_load_yaml.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b79dd9fd0a9bf5be5cd480635739ed7ed857d801 --- /dev/null +++ b/src/descriptors/latch/descriptor_latch_load_yaml.cpp @@ -0,0 +1,48 @@ +#include "descriptor_latch.h" + +#ifdef USING_YAML + +// yaml-cpp library +#include <yaml-cpp/yaml.h> + +namespace vision_utils +{ + +namespace +{ + +static ParamsBasePtr createParamsLATCHDescriptor(const std::string & _filename_dot_yaml) +{ + DescriptorParamsLATCHPtr params_ptr = std::make_shared<DescriptorParamsLATCH>(); + + using std::string; + using YAML::Node; + Node yaml_params = YAML::LoadFile(_filename_dot_yaml); + if (!yaml_params.IsNull()) + { + Node d_yaml = yaml_params["descriptor"]; + if(d_yaml["type"].as<string>() == "LATCH") + { + params_ptr->bytes = d_yaml["bytes"].as<int>(); + params_ptr->rotationInvariance = d_yaml["rotationInvariance"].as<bool>(); + params_ptr->half_ssd_size = d_yaml["half_ssd_size"].as<int>(); + + }else + { + std::cerr << "Bad configuration file. Wrong type " << d_yaml["type"].as<string>() << std::endl; + return nullptr; + } + } + + return params_ptr; +} + +// Register in the SensorFactory +const bool registered_desLATCH_params = ParamsFactory::get().registerCreator("LATCH DES", createParamsLATCHDescriptor); + +} /* namespace [unnamed] */ + +} /* namespace vision_utils */ + +#endif /* IF USING_YAML */ + diff --git a/src/descriptors/lucid/descriptor_lucid.cpp b/src/descriptors/lucid/descriptor_lucid.cpp new file mode 100644 index 0000000000000000000000000000000000000000..42bbd7a1dc453adaf19b1b9712477ef6c062f7d6 --- /dev/null +++ b/src/descriptors/lucid/descriptor_lucid.cpp @@ -0,0 +1,17 @@ +#include "descriptor_lucid.h" + +namespace vision_utils { + +DescriptorLUCID::DescriptorLUCID(void) +{} + +DescriptorLUCID::~DescriptorLUCID(void) +{} + +} /* namespace vision_utils */ + +// Register in the DescriptorsFactory +namespace vision_utils +{ +VU_REGISTER_DESCRIPTOR("LUCID", DescriptorLUCID); +} /* namespace vision_utils */ diff --git a/src/descriptors/lucid/descriptor_lucid.h b/src/descriptors/lucid/descriptor_lucid.h new file mode 100644 index 0000000000000000000000000000000000000000..148021ac4a493bb3ea2d8cb28230dea898ec1fc6 --- /dev/null +++ b/src/descriptors/lucid/descriptor_lucid.h @@ -0,0 +1,69 @@ +#ifndef _DESCRIPTOR_LUCID_H_ +#define _DESCRIPTOR_LUCID_H_ + +#include "../descriptor_base.h" +#include "../descriptor_factory.h" + +// yaml-cpp library +#ifdef USING_YAML + #include <yaml-cpp/yaml.h> +#endif + +namespace vision_utils { + +// Create all pointers +VU_PTR_TYPEDEFS(DescriptorLUCID); +VU_PTR_TYPEDEFS(DescriptorParamsLUCID); + +/** \brief Class parameters + * + */ +struct DescriptorParamsLUCID: public ParamsBase +{ + int lucid_kernel = 1; // Kernel for descriptor construction, where 1=3x3, 2=5x5, 3=7x7 and so forth + int blur_kernel = 2; // Kernel for blurring image prior to descriptor construction, where 1=3x3, 2=5x5, 3=7x7 and so forth +}; + +/** \brief DETECTOR class + * + */ +class DescriptorLUCID : public DescriptorBase { + + public: + DescriptorLUCID(); + virtual ~DescriptorLUCID(void); + + // Factory method + static DescriptorBasePtr create(const std::string& _unique_name, const ParamsBasePtr _params); + + private: + + void defineDescriptor(const ParamsBasePtr _params); +}; + +/* + * brief Define detector + */ +inline void DescriptorLUCID::defineDescriptor(const ParamsBasePtr _params) +{ + DescriptorParamsLUCIDPtr params_ptr = std::static_pointer_cast<DescriptorParamsLUCID>(_params); + + descriptor_ = cv::xfeatures2d::LUCID::create(params_ptr->lucid_kernel, + params_ptr->blur_kernel); +} + + +/* + * brief Create object in factory + */ +inline DescriptorBasePtr DescriptorLUCID::create(const std::string& _unique_name, const ParamsBasePtr _params) +{ + DescriptorLUCIDPtr det_ptr = std::make_shared<DescriptorLUCID>(); + det_ptr->setName(_unique_name); + det_ptr->defineDescriptor(_params); + return det_ptr; +} + +} /* namespace vision_utils */ + +#endif /* _DESCRIPTOR_LUCID_H_ */ diff --git a/src/descriptors/lucid/descriptor_lucid_load_yaml.cpp b/src/descriptors/lucid/descriptor_lucid_load_yaml.cpp new file mode 100644 index 0000000000000000000000000000000000000000..50de9f18392eef12c4def9934cdf86fa170d8431 --- /dev/null +++ b/src/descriptors/lucid/descriptor_lucid_load_yaml.cpp @@ -0,0 +1,46 @@ +#include "descriptor_lucid.h" + +#ifdef USING_YAML + +// yaml-cpp library +#include <yaml-cpp/yaml.h> + +namespace vision_utils +{ + +namespace +{ + +static ParamsBasePtr createParamsLUCIDDescriptor(const std::string & _filename_dot_yaml) +{ + DescriptorParamsLUCIDPtr params_ptr = std::make_shared<DescriptorParamsLUCID>(); + + using std::string; + using YAML::Node; + Node yaml_params = YAML::LoadFile(_filename_dot_yaml); + if (!yaml_params.IsNull()) + { + Node d_yaml = yaml_params["descriptor"]; + if(d_yaml["type"].as<string>() == "LUCID") + { + params_ptr->lucid_kernel = d_yaml["lucid_kernel"].as<int>(); + params_ptr->blur_kernel = d_yaml["blur_kernel"].as<int>(); + }else + { + std::cerr << "Bad configuration file. Wrong type " << d_yaml["type"].as<string>() << std::endl; + return nullptr; + } + } + + return params_ptr; +} + +// Register in the SensorFactory +const bool registered_desLUCID_params = ParamsFactory::get().registerCreator("LUCID DES", createParamsLUCIDDescriptor); + +} /* namespace [unnamed] */ + +} /* namespace vision_utils */ + +#endif /* IF USING_YAML */ + diff --git a/src/descriptors/orb/descriptor_orb.cpp b/src/descriptors/orb/descriptor_orb.cpp new file mode 100644 index 0000000000000000000000000000000000000000..88d2552e5745281e4fc799dc7401eaa0b1ac8c51 --- /dev/null +++ b/src/descriptors/orb/descriptor_orb.cpp @@ -0,0 +1,17 @@ +#include "descriptor_orb.h" + +namespace vision_utils { + +DescriptorORB::DescriptorORB(void) +{} + +DescriptorORB::~DescriptorORB(void) +{} + +} /* namespace vision_utils */ + +// Register in the DescriptorsFactory +namespace vision_utils +{ +VU_REGISTER_DESCRIPTOR("ORB", DescriptorORB); +} /* namespace vision_utils */ diff --git a/src/descriptors/orb/descriptor_orb.h b/src/descriptors/orb/descriptor_orb.h new file mode 100644 index 0000000000000000000000000000000000000000..5375c41cbddf862f5ab80f1cd39ab259f988f6ac --- /dev/null +++ b/src/descriptors/orb/descriptor_orb.h @@ -0,0 +1,81 @@ +#ifndef _DESCRIPTOR_ORB_H_ +#define _DESCRIPTOR_ORB_H_ + +#include "../descriptor_base.h" +#include "../descriptor_factory.h" + +// yaml-cpp library +#ifdef USING_YAML + #include <yaml-cpp/yaml.h> +#endif + +namespace vision_utils { + +// Create all pointers +VU_PTR_TYPEDEFS(DescriptorORB); +VU_PTR_TYPEDEFS(DescriptorParamsORB); + +/** \brief Class parameters + * + */ +struct DescriptorParamsORB: public ParamsBase +{ + int nfeatures = 500; // The maximum number of features to retain. + float scaleFactor = 2.0f; // Pyramid decimation ratio, greater than 1. scaleFactor==2 means the classical pyramid, where each next level has 4x less pixels than the previous, but such a big scale factor will degrade feature matching scores dramatically. On the other hand, too close to 1 scale factor will mean that to cover certain scale range you will need more pyramid levels and so the speed will suffer. + int nlevels = 8; // The number of pyramid levels. The smallest level will have linear size equal to input_image_linear_size/pow(scaleFactor, nlevels). + int edgeThreshold = 31; // This is size of the border where the features are not detected. It should roughly match the patchSize parameter. + int firstLevel = 0; // It should be 0 in the current implementation. + int WTA_K = 2; // The number of points that produce each element of the oriented BRIEF descriptor. The default value 2 means the BRIEF where we take a random point pair and compare their brightnesses, so we get 0/1 response. Other possible values are 3 and 4. For example, 3 means that we take 3 random points (of course, those point coordinates are random, but they are generated from the pre-defined seed, so each element of BRIEF descriptor is computed deterministically from the pixel rectangle), find point of maximum brightness and output index of the winner (0, 1 or 2). Such output will occupy 2 bits, and therefore it will need a special variant of Hamming distance, denoted as NORM_HAMMING2 (2 bits per bin). When WTA_K=4, we take 4 random points to compute each bin (that will also occupy 2 bits with possible values 0, 1, 2 or 3). + int scoreType = cv::ORB::HARRIS_SCORE; // The default HARRIS_SCORE means that Harris algorithm is used to rank features (the score is written to KeyPoint::score and is used to retain best nfeatures features); FAST_SCORE is alternative value of the parameter that produces slightly less stable keypoints, but it is a little faster to compute. + int patchSize = 31; // size of the patch used by the oriented BRIEF descriptor. Of course, on smaller pyramid layers the perceived image area covered by a feature will be larger. +}; + +/** \brief Descriptor class + * + */ +class DescriptorORB : public DescriptorBase { + + public: + DescriptorORB(); + virtual ~DescriptorORB(void); + + // Factory method + static DescriptorBasePtr create(const std::string& _unique_name, const ParamsBasePtr _params); + + private: + + void defineDescriptor(const ParamsBasePtr _params); +}; + +/* + * brief Define Descriptor + */ +inline void DescriptorORB::defineDescriptor(const ParamsBasePtr _params) +{ + DescriptorParamsORBPtr params_ptr = std::static_pointer_cast<DescriptorParamsORB>(_params); + + descriptor_ = cv::ORB::create(params_ptr->nfeatures, + params_ptr->scaleFactor, + params_ptr->nlevels, + params_ptr->edgeThreshold, + params_ptr->firstLevel, + params_ptr->WTA_K, + params_ptr->scoreType, + params_ptr->patchSize); +} + + +/* + * brief Create object in factory + */ +inline DescriptorBasePtr DescriptorORB::create(const std::string& _unique_name, const ParamsBasePtr _params) +{ + DescriptorORBPtr det_ptr = std::make_shared<DescriptorORB>(); + det_ptr->setName(_unique_name); + det_ptr->defineDescriptor(_params); + return det_ptr; +} + +} /* namespace vision_utils */ + +#endif /* _DESCRIPTOR_ORB_H_ */ diff --git a/src/descriptors/orb/descriptor_orb_load_yaml.cpp b/src/descriptors/orb/descriptor_orb_load_yaml.cpp new file mode 100644 index 0000000000000000000000000000000000000000..03b31f79acbe18758efa19c0e3da88bd06a4d319 --- /dev/null +++ b/src/descriptors/orb/descriptor_orb_load_yaml.cpp @@ -0,0 +1,52 @@ +#include "descriptor_orb.h" + +#ifdef USING_YAML + +// yaml-cpp library +#include <yaml-cpp/yaml.h> + +namespace vision_utils +{ + +namespace +{ + +static ParamsBasePtr createParamsORBDescriptor(const std::string & _filename_dot_yaml) +{ + DescriptorParamsORBPtr params_ptr = std::make_shared<DescriptorParamsORB>(); + + using std::string; + using YAML::Node; + Node yaml_params = YAML::LoadFile(_filename_dot_yaml); + if (!yaml_params.IsNull()) + { + Node d_yaml = yaml_params["descriptor"]; + if(d_yaml["type"].as<string>() == "ORB") + { + params_ptr->nfeatures = d_yaml["nfeatures"].as<unsigned int>(); + params_ptr->scaleFactor = d_yaml["scale factor"].as<float>(); + params_ptr->nlevels = d_yaml["nlevels"].as<unsigned int>(); + params_ptr->edgeThreshold = d_yaml["edge threshold"].as<unsigned int>(); + params_ptr->firstLevel = d_yaml["first level"].as<unsigned int>(); + params_ptr->WTA_K = d_yaml["WTA_K"].as<unsigned int>(); + params_ptr->scoreType = d_yaml["score type"].as<int>(); // enum { kBytes = 32, HARRIS_SCORE=0, FAST_SCORE=1 }; + params_ptr->patchSize = d_yaml["patch size"].as<unsigned int>(); + }else + { + std::cerr << "Bad configuration file. Wrong type " << d_yaml["type"].as<string>() << std::endl; + return nullptr; + } + } + + return params_ptr; +} + +// Register in the SensorFactory +const bool registered_desORB_params = ParamsFactory::get().registerCreator("ORB DES", createParamsORBDescriptor); + +} /* namespace [unnamed] */ + +} /* namespace vision_utils */ + +#endif /* IF USING_YAML */ + diff --git a/src/descriptors/sift/descriptor_sift.cpp b/src/descriptors/sift/descriptor_sift.cpp new file mode 100644 index 0000000000000000000000000000000000000000..905fc58832237f3b46fb9f99d9bf498652b41c80 --- /dev/null +++ b/src/descriptors/sift/descriptor_sift.cpp @@ -0,0 +1,17 @@ +#include "descriptor_sift.h" + +namespace vision_utils { + +DescriptorSIFT::DescriptorSIFT(void) +{} + +DescriptorSIFT::~DescriptorSIFT(void) +{} + +} /* namespace vision_utils */ + +// Register in the DescriptorsFactory +namespace vision_utils +{ +VU_REGISTER_DESCRIPTOR("SIFT", DescriptorSIFT); +} /* namespace vision_utils */ diff --git a/src/descriptors/sift/descriptor_sift.h b/src/descriptors/sift/descriptor_sift.h new file mode 100644 index 0000000000000000000000000000000000000000..25d2e0fc0975ed6e936671ae9934e85c1c773dbc --- /dev/null +++ b/src/descriptors/sift/descriptor_sift.h @@ -0,0 +1,75 @@ +#ifndef _DESCRIPTOR_SIFT_H_ +#define _DESCRIPTOR_SIFT_H_ + +#include "../descriptor_base.h" +#include "../descriptor_factory.h" + +// yaml-cpp library +#ifdef USING_YAML + #include <yaml-cpp/yaml.h> +#endif + +namespace vision_utils { + +// Create all pointers +VU_PTR_TYPEDEFS(DescriptorSIFT); +VU_PTR_TYPEDEFS(DescriptorParamsSIFT); + +/** \brief Class parameters + * + */ +struct DescriptorParamsSIFT: public ParamsBase +{ + int nfeatures=0; // The number of best features to retain. The features are ranked by their scores (measured in SIFT algorithm as the local contrast) + int nOctaveLayers=3; // The number of layers in each octave. 3 is the value used in D. Lowe paper. The number of octaves is computed automatically from the image resolution. + double contrastThreshold=0.04; // The contrast threshold used to filter out weak features in semi-uniform (low-contrast) regions. The larger the threshold, the less features are produced by the detector. + double edgeThreshold=10; // The threshold used to filter out edge-like features. Note that the its meaning is different from the contrastThreshold, i.e. the larger the edgeThreshold, the less features are filtered out (more features are retained). + double sigma=1.6; // The sigma of the Gaussian applied to the input image at the octave #0. If your image is captured with a weak camera with soft lenses, you might want to reduce the number. +}; + +/** \brief DETECTOR class + * + */ +class DescriptorSIFT : public DescriptorBase { + + public: + DescriptorSIFT(); + virtual ~DescriptorSIFT(void); + + // Factory method + static DescriptorBasePtr create(const std::string& _unique_name, const ParamsBasePtr _params); + + private: + + void defineDescriptor(const ParamsBasePtr _params); +}; + +/* + * brief Define detector + */ +inline void DescriptorSIFT::defineDescriptor(const ParamsBasePtr _params) +{ + DescriptorParamsSIFTPtr params_ptr = std::static_pointer_cast<DescriptorParamsSIFT>(_params); + + descriptor_ = cv::xfeatures2d::SIFT::create(params_ptr->nfeatures, + params_ptr->nOctaveLayers, + params_ptr->contrastThreshold, + params_ptr->edgeThreshold, + params_ptr->sigma); +} + + +/* + * brief Create object in factory + */ +inline DescriptorBasePtr DescriptorSIFT::create(const std::string& _unique_name, const ParamsBasePtr _params) +{ + DescriptorSIFTPtr det_ptr = std::make_shared<DescriptorSIFT>(); + det_ptr->setName(_unique_name); + det_ptr->defineDescriptor(_params); + return det_ptr; +} + +} /* namespace vision_utils */ + +#endif /* _DESCRIPTOR_SIFT_H_ */ diff --git a/src/descriptors/sift/descriptor_sift_load_yaml.cpp b/src/descriptors/sift/descriptor_sift_load_yaml.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d18646e1859e87b7bd22c5d2d32b02d907ed80df --- /dev/null +++ b/src/descriptors/sift/descriptor_sift_load_yaml.cpp @@ -0,0 +1,49 @@ +#include "descriptor_sift.h" + +#ifdef USING_YAML + +// yaml-cpp library +#include <yaml-cpp/yaml.h> + +namespace vision_utils +{ + +namespace +{ + +static ParamsBasePtr createParamsSIFTDescriptor(const std::string & _filename_dot_yaml) +{ + DescriptorParamsSIFTPtr params_ptr = std::make_shared<DescriptorParamsSIFT>(); + + using std::string; + using YAML::Node; + Node yaml_params = YAML::LoadFile(_filename_dot_yaml); + if (!yaml_params.IsNull()) + { + Node d_yaml = yaml_params["descriptor"]; + if(d_yaml["type"].as<string>() == "SIFT") + { + params_ptr->nfeatures = d_yaml["nfeatures"].as<int>(); + params_ptr->nOctaveLayers = d_yaml["nOctaveLayers"].as<int>(); + params_ptr->contrastThreshold = d_yaml["contrastThreshold"].as<double>(); + params_ptr->edgeThreshold = d_yaml["edgeThreshold"].as<double>(); + params_ptr->sigma = d_yaml["sigma"].as<double>(); + }else + { + std::cerr << "DESCRIPTOR Bad configuration file. Wrong type " << d_yaml["type"].as<string>() << std::endl; + return nullptr; + } + } + + return params_ptr; +} + +// Register in the SensorFactory +const bool registered_desSIFT_params = ParamsFactory::get().registerCreator("SIFT DES", createParamsSIFTDescriptor); + +} /* namespace [unnamed] */ + +} /* namespace vision_utils */ + +#endif /* IF USING_YAML */ + diff --git a/src/descriptors/surf/descriptor_surf.cpp b/src/descriptors/surf/descriptor_surf.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6e7d7a462c065bd0f17b09d4de6345718db77884 --- /dev/null +++ b/src/descriptors/surf/descriptor_surf.cpp @@ -0,0 +1,17 @@ +#include "descriptor_surf.h" + +namespace vision_utils { + +DescriptorSURF::DescriptorSURF(void) +{} + +DescriptorSURF::~DescriptorSURF(void) +{} + +} /* namespace vision_utils */ + +// Register in the DescriptorsFactory +namespace vision_utils +{ +VU_REGISTER_DESCRIPTOR("SURF", DescriptorSURF); +} /* namespace vision_utils */ diff --git a/src/descriptors/surf/descriptor_surf.h b/src/descriptors/surf/descriptor_surf.h new file mode 100644 index 0000000000000000000000000000000000000000..191787282a47182f11eca4dcbc4550e81d2a6fce --- /dev/null +++ b/src/descriptors/surf/descriptor_surf.h @@ -0,0 +1,75 @@ +#ifndef _DESCRIPTOR_SURF_H_ +#define _DESCRIPTOR_SURF_H_ + +#include "../descriptor_base.h" +#include "../descriptor_factory.h" + +// yaml-cpp library +#ifdef USING_YAML + #include <yaml-cpp/yaml.h> +#endif + +namespace vision_utils { + +// Create all pointers +VU_PTR_TYPEDEFS(DescriptorSURF); +VU_PTR_TYPEDEFS(DescriptorParamsSURF); + +/** \brief Class parameters + * + */ +struct DescriptorParamsSURF: public ParamsBase +{ + double hessianThreshold=400; // Threshold for hessian keypoint detector used in SURF. + int nOctaves=4; // Number of pyramid octaves the keypoint detector will use. + int nOctaveLayers=2; // Number of octave layers within each octave. + bool extended=true; // Extended descriptor flag (true - use extended 128-element descriptors; false - use 64-element descriptors). + bool upright=false; // Up-right or rotated features flag (true - do not compute orientation of features; false - compute orientation +}; + +/** \brief DETECTOR class + * + */ +class DescriptorSURF : public DescriptorBase { + + public: + DescriptorSURF(); + virtual ~DescriptorSURF(void); + + // Factory method + static DescriptorBasePtr create(const std::string& _unique_name, const ParamsBasePtr _params); + + private: + + void defineDescriptor(const ParamsBasePtr _params); +}; + +/* + * brief Define detector + */ +inline void DescriptorSURF::defineDescriptor(const ParamsBasePtr _params) +{ + DescriptorParamsSURFPtr params_ptr = std::static_pointer_cast<DescriptorParamsSURF>(_params); + + descriptor_ = cv::xfeatures2d::SURF::create(params_ptr->hessianThreshold, + params_ptr->nOctaves, + params_ptr->nOctaveLayers, + params_ptr->extended, + params_ptr->upright); +} + + +/* + * brief Create object in factory + */ +inline DescriptorBasePtr DescriptorSURF::create(const std::string& _unique_name, const ParamsBasePtr _params) +{ + DescriptorSURFPtr det_ptr = std::make_shared<DescriptorSURF>(); + det_ptr->setName(_unique_name); + det_ptr->defineDescriptor(_params); + return det_ptr; +} + +} /* namespace vision_utils */ + +#endif /* _DESCRIPTOR_SURF_H_ */ diff --git a/src/descriptors/surf/descriptor_surf_load_yaml.cpp b/src/descriptors/surf/descriptor_surf_load_yaml.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8cfb642ed31e728f97e5f26bc8fcb4d9e34249e0 --- /dev/null +++ b/src/descriptors/surf/descriptor_surf_load_yaml.cpp @@ -0,0 +1,49 @@ +#include "descriptor_surf.h" + +#ifdef USING_YAML + +// yaml-cpp library +#include <yaml-cpp/yaml.h> + +namespace vision_utils +{ + +namespace +{ + +static ParamsBasePtr createParamsSURFDescriptor(const std::string & _filename_dot_yaml) +{ + DescriptorParamsSURFPtr params_ptr = std::make_shared<DescriptorParamsSURF>(); + + using std::string; + using YAML::Node; + Node yaml_params = YAML::LoadFile(_filename_dot_yaml); + if (!yaml_params.IsNull()) + { + Node d_yaml = yaml_params["descriptor"]; + if(d_yaml["type"].as<string>() == "SURF") + { + params_ptr->hessianThreshold = d_yaml["hessianThreshold"].as<double>(); + params_ptr->nOctaves = d_yaml["nOctaves"].as<int>(); + params_ptr->nOctaveLayers = d_yaml["nOctaveLayers"].as<int>(); + params_ptr->extended = d_yaml["extended"].as<bool>(); + params_ptr->upright = d_yaml["upright"].as<bool>(); + }else + { + std::cerr << "Bad configuration file. Wrong type " << d_yaml["type"].as<string>() << std::endl; + return nullptr; + } + } + + return params_ptr; +} + +// Register in the SensorFactory +const bool registered_desSURF_params = ParamsFactory::get().registerCreator("SURF DES", createParamsSURFDescriptor); + +} /* namespace [unnamed] */ + +} /* namespace vision_utils */ + +#endif /* IF USING_YAML */ + diff --git a/src/detectors/agast/detector_agast.cpp b/src/detectors/agast/detector_agast.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9bcfbe1cf487cf4ae681e4ecf74bdbc18ed440bc --- /dev/null +++ b/src/detectors/agast/detector_agast.cpp @@ -0,0 +1,17 @@ +#include "detector_agast.h" + +namespace vision_utils { + +DetectorAGAST::DetectorAGAST(void) +{} + +DetectorAGAST::~DetectorAGAST(void) +{} + +} /* namespace vision_utils */ + +// Register in the DetectorsFactory +namespace vision_utils +{ +VU_REGISTER_DETECTOR("AGAST", DetectorAGAST); +} /* namespace vision_utils */ diff --git a/src/detectors/agast/detector_agast.h b/src/detectors/agast/detector_agast.h new file mode 100644 index 0000000000000000000000000000000000000000..dee975fdb4a049ccc176cd567e92a237c3e3077a --- /dev/null +++ b/src/detectors/agast/detector_agast.h @@ -0,0 +1,70 @@ +#ifndef _DETECTOR_AGAST_H_ +#define _DETECTOR_AGAST_H_ + +#include "../detector_base.h" +#include "../detector_factory.h" + +// yaml-cpp library +#ifdef USING_YAML + #include <yaml-cpp/yaml.h> +#endif + +namespace vision_utils { + +// Create all pointers +VU_PTR_TYPEDEFS(DetectorAGAST); +VU_PTR_TYPEDEFS(DetectorParamsAGAST); + +/** \brief Class parameters + * + */ +struct DetectorParamsAGAST: public ParamsBase +{ + int threshold = 10; + bool nonmaxSuppression = true; + int type = cv::AgastFeatureDetector::OAST_9_16; // AGAST_5_8=0, AGAST_7_12d=1, AGAST_7_12s=2, OAST_9_16=3, THRESHOLD=10000, NONMAX_SUPPRESSION=10001 +}; + +/** \brief DETECTOR class + * + */ +class DetectorAGAST : public DetectorBase { + + public: + DetectorAGAST(); + virtual ~DetectorAGAST(void); + + // Factory method + static DetectorBasePtr create(const std::string& _unique_name, const ParamsBasePtr _params); + + private: + + void defineDetector(const ParamsBasePtr _params); +}; + +/* + * brief Define detector + */ +inline void DetectorAGAST::defineDetector(const ParamsBasePtr _params) +{ + DetectorParamsAGASTPtr params_ptr = std::static_pointer_cast<DetectorParamsAGAST>(_params); + + detector_ = cv::AgastFeatureDetector::create(params_ptr->threshold, + params_ptr->nonmaxSuppression, + params_ptr->type); +} + +/* + * brief Create object in factory + */ +inline DetectorBasePtr DetectorAGAST::create(const std::string& _unique_name, const ParamsBasePtr _params) +{ + DetectorAGASTPtr det_ptr = std::make_shared<DetectorAGAST>(); + det_ptr->setName(_unique_name); + det_ptr->defineDetector(_params); + return det_ptr; +} + +} /* namespace vision_utils */ + +#endif /* _DETECTOR_AGAST_H_ */ diff --git a/src/detectors/agast/detector_agast_load_yaml.cpp b/src/detectors/agast/detector_agast_load_yaml.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e07e11706c0ede2b3aa452ed2973985c66fe7ea2 --- /dev/null +++ b/src/detectors/agast/detector_agast_load_yaml.cpp @@ -0,0 +1,47 @@ +#include "detector_agast.h" + +#ifdef USING_YAML + +// yaml-cpp library +#include <yaml-cpp/yaml.h> + +namespace vision_utils +{ + +namespace +{ + +static ParamsBasePtr createParamsAGASTDetector(const std::string & _filename_dot_yaml) +{ + DetectorParamsAGASTPtr params_ptr = std::make_shared<DetectorParamsAGAST>(); + + using std::string; + using YAML::Node; + Node yaml_params = YAML::LoadFile(_filename_dot_yaml); + if (!yaml_params.IsNull()) + { + Node d_yaml = yaml_params["detector"]; + if(d_yaml["type"].as<string>() == "AGAST") + { + params_ptr->threshold = d_yaml["threshold"].as<int>(); + params_ptr->nonmaxSuppression = d_yaml["nonmaxSuppression"].as<bool>(); + params_ptr->type = d_yaml["detection type"].as<int>(); + }else + { + std::cerr << "Bad configuration file. Wrong type " << d_yaml["type"].as<string>() << std::endl; + return nullptr; + } + } + + return params_ptr; +} + +// Register in the SensorFactory +const bool registered_detAGAST_params = ParamsFactory::get().registerCreator("AGAST DET", createParamsAGASTDetector); + +} /* namespace [unnamed] */ + +} /* namespace vision_utils */ + +#endif /* IF USING_YAML */ + diff --git a/src/detectors/akaze/detector_akaze.cpp b/src/detectors/akaze/detector_akaze.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9b7e0aaa9953816f0661ac9fd048d5807d2f2fdd --- /dev/null +++ b/src/detectors/akaze/detector_akaze.cpp @@ -0,0 +1,17 @@ +#include "detector_akaze.h" + +namespace vision_utils { + +DetectorAKAZE::DetectorAKAZE(void) +{} + +DetectorAKAZE::~DetectorAKAZE(void) +{} + +} /* namespace vision_utils */ + +// Register in the DetectorsFactory +namespace vision_utils +{ +VU_REGISTER_DETECTOR("AKAZE", DetectorAKAZE); +} /* namespace vision_utils */ diff --git a/src/detectors/akaze/detector_akaze.h b/src/detectors/akaze/detector_akaze.h new file mode 100644 index 0000000000000000000000000000000000000000..ed4b54561c324a7ffb563375bc950480bc3eac59 --- /dev/null +++ b/src/detectors/akaze/detector_akaze.h @@ -0,0 +1,79 @@ +#ifndef _DETECTOR_AKAZE_H_ +#define _DETECTOR_AKAZE_H_ + +#include "../detector_base.h" +#include "../detector_factory.h" + +// yaml-cpp library +#ifdef USING_YAML + #include <yaml-cpp/yaml.h> +#endif + +namespace vision_utils { + +// Create all pointers +VU_PTR_TYPEDEFS(DetectorAKAZE); +VU_PTR_TYPEDEFS(DetectorParamsAKAZE); + +/** \brief Class parameters + * + */ +struct DetectorParamsAKAZE: public ParamsBase +{ + int descriptor_type = cv::AKAZE::DESCRIPTOR_MLDB; // Type of the extracted descriptor. DESCRIPTOR_KAZE_UPRIGHT=2, DESCRIPTOR_KAZE=3, DESCRIPTOR_MLDB_UPRIGHT=4, DESCRIPTOR_MLDB=5 + int descriptor_size = 0; // Size of the descriptor in bits. 0 -> Full size + int descriptor_channels = 3; // Number of channels in the descriptor (1, 2, 3) + float threshold = 0.001f; // Detector response threshold to accept point + int nOctaves = 4; // Maximum octave evolution of the image + int nOctaveLayers = 4; // Default number of sublevels per scale level + int diffusivity = cv::KAZE::DIFF_PM_G2; // Diffusivity type. DIFF_PM_G1=0, DIFF_PM_G2=1, DIFF_WEICKERT=2, DIFF_CHARBONNIER=3 +}; + +/** \brief DETECTOR class + * + */ +class DetectorAKAZE : public DetectorBase { + + public: + DetectorAKAZE(); + virtual ~DetectorAKAZE(void); + + // Factory method + static DetectorBasePtr create(const std::string& _unique_name, const ParamsBasePtr _params); + + private: + + void defineDetector(const ParamsBasePtr _params); +}; + +/* + * brief Define detector + */ +inline void DetectorAKAZE::defineDetector(const ParamsBasePtr _params) +{ + DetectorParamsAKAZEPtr params_ptr = std::static_pointer_cast<DetectorParamsAKAZE>(_params); + + detector_ = cv::AKAZE::create(params_ptr->descriptor_type, + params_ptr->descriptor_size, + params_ptr->descriptor_channels, + params_ptr->threshold, + params_ptr->nOctaves, + params_ptr->nOctaveLayers, + params_ptr->diffusivity); +} + + +/* + * brief Create object in factory + */ +inline DetectorBasePtr DetectorAKAZE::create(const std::string& _unique_name, const ParamsBasePtr _params) +{ + DetectorAKAZEPtr det_ptr = std::make_shared<DetectorAKAZE>(); + det_ptr->setName(_unique_name); + det_ptr->defineDetector(_params); + return det_ptr; +} + +} /* namespace vision_utils */ + +#endif /* _DETECTOR_AKAZE_H_ */ diff --git a/src/detectors/akaze/detector_akaze_load_yaml.cpp b/src/detectors/akaze/detector_akaze_load_yaml.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1f41c7cd508ee3b39d50e89be7a1e6718e7fd4e8 --- /dev/null +++ b/src/detectors/akaze/detector_akaze_load_yaml.cpp @@ -0,0 +1,51 @@ +#include "detector_akaze.h" + +#ifdef USING_YAML + +// yaml-cpp library +#include <yaml-cpp/yaml.h> + +namespace vision_utils +{ + +namespace +{ + +static ParamsBasePtr createParamsAKAZEDetector(const std::string & _filename_dot_yaml) +{ + DetectorParamsAKAZEPtr params_ptr = std::make_shared<DetectorParamsAKAZE>(); + + using std::string; + using YAML::Node; + Node yaml_params = YAML::LoadFile(_filename_dot_yaml); + if (!yaml_params.IsNull()) + { + Node d_yaml = yaml_params["detector"]; + if(d_yaml["type"].as<string>() == "AKAZE") + { + params_ptr->descriptor_type = d_yaml["descriptor_type"].as<int>(); + params_ptr->descriptor_size = d_yaml["descriptor_size"].as<int>(); + params_ptr->descriptor_channels = d_yaml["descriptor_channels"].as<int>(); + params_ptr->threshold = d_yaml["threshold"].as<float>(); + params_ptr->nOctaves = d_yaml["nOctaves"].as<int>(); + params_ptr->nOctaveLayers = d_yaml["nOctaveLayers"].as<int>(); + params_ptr->diffusivity = d_yaml["diffusivity"].as<int>(); + }else + { + std::cerr << "Bad configuration file. Wrong type " << d_yaml["type"].as<string>() << std::endl; + return nullptr; + } + } + + return params_ptr; +} + +// Register in the SensorFactory +const bool registered_detAKAZE_params = ParamsFactory::get().registerCreator("AKAZE DET", createParamsAKAZEDetector); + +} /* namespace [unnamed] */ + +} /* namespace vision_utils */ + +#endif /* IF USING_YAML */ + diff --git a/src/detectors/brisk/detector_brisk.cpp b/src/detectors/brisk/detector_brisk.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d7bfc3ee2fb26e2904945fe0a53d873770beafc4 --- /dev/null +++ b/src/detectors/brisk/detector_brisk.cpp @@ -0,0 +1,17 @@ +#include "detector_brisk.h" + +namespace vision_utils { + +DetectorBRISK::DetectorBRISK(void) +{} + +DetectorBRISK::~DetectorBRISK(void) +{} + +} /* namespace vision_utils */ + +// Register in the DetectorsFactory +namespace vision_utils +{ +VU_REGISTER_DETECTOR("BRISK", DetectorBRISK); +} /* namespace vision_utils */ diff --git a/src/detectors/brisk/detector_brisk.h b/src/detectors/brisk/detector_brisk.h new file mode 100644 index 0000000000000000000000000000000000000000..05b54df4ad63cc98eba685bcede6a3108d8b7c1a --- /dev/null +++ b/src/detectors/brisk/detector_brisk.h @@ -0,0 +1,71 @@ +#ifndef _DETECTOR_BRISK_H_ +#define _DETECTOR_BRISK_H_ + +#include "../detector_base.h" +#include "../detector_factory.h" + +// yaml-cpp library +#ifdef USING_YAML + #include <yaml-cpp/yaml.h> +#endif + +namespace vision_utils { + +// Create all pointers +VU_PTR_TYPEDEFS(DetectorBRISK); +VU_PTR_TYPEDEFS(DetectorParamsBRISK); + +/** \brief Class parameters + * + */ +struct DetectorParamsBRISK: public ParamsBase +{ + int thresh = 30; // FAST/AGAST detection threshold score. + int octaves = 3; // Detection octaves. Use 0 to do single scale. + float patternScale = 1.0f; // Apply this scale to the pattern used for sampling the neighbourhood of a keypoint. +}; + +/** \brief DETECTOR class + * + */ +class DetectorBRISK : public DetectorBase { + + public: + DetectorBRISK(); + virtual ~DetectorBRISK(void); + + // Factory method + static DetectorBasePtr create(const std::string& _unique_name, const ParamsBasePtr _params); + + private: + + void defineDetector(const ParamsBasePtr _params); +}; + +/* + * brief Define detector + */ +inline void DetectorBRISK::defineDetector(const ParamsBasePtr _params) +{ + DetectorParamsBRISKPtr params_ptr = std::static_pointer_cast<DetectorParamsBRISK>(_params); + + detector_ = cv::BRISK::create(params_ptr->thresh, + params_ptr->octaves, + params_ptr->patternScale); +} + + +/* + * brief Create object in factory + */ +inline DetectorBasePtr DetectorBRISK::create(const std::string& _unique_name, const ParamsBasePtr _params) +{ + DetectorBRISKPtr det_ptr = std::make_shared<DetectorBRISK>(); + det_ptr->setName(_unique_name); + det_ptr->defineDetector(_params); + return det_ptr; +} + +} /* namespace vision_utils */ + +#endif /* _DETECTOR_BRISK_H_ */ diff --git a/src/detectors/brisk/detector_brisk_load_yaml.cpp b/src/detectors/brisk/detector_brisk_load_yaml.cpp new file mode 100644 index 0000000000000000000000000000000000000000..dd4317c7a2bae16171614f102f995fb1d23d7462 --- /dev/null +++ b/src/detectors/brisk/detector_brisk_load_yaml.cpp @@ -0,0 +1,47 @@ +#include "detector_brisk.h" + +#ifdef USING_YAML + +// yaml-cpp library +#include <yaml-cpp/yaml.h> + +namespace vision_utils +{ + +namespace +{ + +static ParamsBasePtr createParamsBRISKDetector(const std::string & _filename_dot_yaml) +{ + DetectorParamsBRISKPtr params_ptr = std::make_shared<DetectorParamsBRISK>(); + + using std::string; + using YAML::Node; + Node yaml_params = YAML::LoadFile(_filename_dot_yaml); + if (!yaml_params.IsNull()) + { + Node d_yaml = yaml_params["detector"]; + if(d_yaml["type"].as<string>() == "BRISK") + { + params_ptr->thresh = d_yaml["thresh"].as<int>(); + params_ptr->octaves = d_yaml["octaves"].as<int>(); + params_ptr->patternScale = d_yaml["patternScale"].as<float>(); + }else + { + std::cerr << "Bad configuration file. Wrong type " << d_yaml["type"].as<string>() << std::endl; + return nullptr; + } + } + + return params_ptr; +} + +// Register in the SensorFactory +const bool registered_detBRISK_params = ParamsFactory::get().registerCreator("BRISK DET", createParamsBRISKDetector); + +} /* namespace [unnamed] */ + +} /* namespace vision_utils */ + +#endif /* IF USING_YAML */ + diff --git a/src/detectors/detector_base.cpp b/src/detectors/detector_base.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2b6e87eac33c50bb66b0384d94d622866eb0a916 --- /dev/null +++ b/src/detectors/detector_base.cpp @@ -0,0 +1,49 @@ +#include "detector_base.h" + +namespace vision_utils { + +DetectorBase::DetectorBase(void) +{ +} + +DetectorBase::~DetectorBase(void) +{ +} + +KeyPointVector DetectorBase::detect(const cv::Mat& _image) +{ + cv::Mat mask = cv::Mat::ones(_image.size(), CV_8U); + return detect(_image, mask); +} +KeyPointVector DetectorBase::detect(const cv::Mat& _image, const cv::Mat& _mask) +{ + KeyPointVector kpts; + clock_t tStart = clock(); + detector_->detect(_image, kpts, _mask); + comp_time_ = (double)(clock() - tStart) / CLOCKS_PER_SEC; + + return kpts; +} + +} /* namespace vision_utils */ + +#include "detector_factory.h" + +namespace vision_utils +{ + +DetectorBasePtr setupDetector(const std::string& _type, const std::string& _unique_name, const ParamsBasePtr& _params) +{ + DetectorBasePtr det_ptr = DetectorFactory::get().create(_type, _unique_name, _params); + return det_ptr; +}; + +#ifdef USING_YAML +DetectorBasePtr setupDetector(const std::string& _type, const std::string& _unique_name, const std::string& _filename_dot_yaml) +{ + ParamsBasePtr params_ptr = ParamsFactory::get().create(_type+" DET", _filename_dot_yaml); + return setupDetector(_type, _unique_name, params_ptr); +} +#endif + +} /* namespace vision_utils */ diff --git a/src/detectors/detector_base.h b/src/detectors/detector_base.h new file mode 100644 index 0000000000000000000000000000000000000000..8671f846167d4339e700b3003ddc02e2aa3660fa --- /dev/null +++ b/src/detectors/detector_base.h @@ -0,0 +1,76 @@ +#ifndef _DETECTOR_BASE_H_ +#define _DETECTOR_BASE_H_ + +// vision_utils +#include "../vision_utils.h" + +typedef cv::Ptr<cv::FeatureDetector> FeatureDetectorPtr; + +namespace vision_utils +{ + +///////////////////////////////////////////////////////////////////////// +// CLASS DEFINITIONS +///////////////////////////////////////////////////////////////////////// + +// Create all pointers +VU_PTR_TYPEDEFS(DetectorBase); + +/** \brief base class for DETECTOR base + * + * Derive from this class to create DETECTOR base class parameters. + */ +class DetectorBase : public VUBase, public std::enable_shared_from_this<DetectorBase> +{ + public: + + /** + * \brief Constructor without parameters + */ + DetectorBase(void); + + /** + * \brief Virtual destructor + */ + virtual ~DetectorBase(void); + + KeyPointVector detect(const cv::Mat& _image); + KeyPointVector detect(const cv::Mat& _image, const cv::Mat& _mask); + + std::string getName(void); + + // Factory method + static DetectorBasePtr create(const std::string& _unique_name, const ParamsBasePtr _params); + + protected: + + std::string name_; + + FeatureDetectorPtr detector_; + + void setName(const std::string& _name); + + virtual void defineDetector(const ParamsBasePtr _params) = 0; +}; + +/* + * brief Retrieve object name + */ +inline std::string DetectorBase::getName(void) { return name_; } + +/* + * brief Set object name + */ +inline void DetectorBase::setName(const std::string& _name){ name_ = _name; } + +/* + * brief Setup and get the corresponding pointer + */ +DetectorBasePtr setupDetector(const std::string& _type, const std::string& _unique_name, const ParamsBasePtr& _params); +#ifdef USING_YAML +DetectorBasePtr setupDetector(const std::string& _type, const std::string& _unique_name, const std::string& _filename_dot_yaml); +#endif + +} /* namespace vision_utils */ + +#endif /* DETECTOR_BASE_H_ */ diff --git a/src/detectors/detector_factory.h b/src/detectors/detector_factory.h new file mode 100644 index 0000000000000000000000000000000000000000..6bba993895df2e85ef761f130317a6cd5b1807f0 --- /dev/null +++ b/src/detectors/detector_factory.h @@ -0,0 +1,32 @@ +#ifndef _DETECTOR_FACTORY_H_ +#define _DETECTOR_FACTORY_H_ + +namespace vision_utils +{ +class DetectorBase; +struct DetectorParamsBase; +} + +#include "../factory.h" + +namespace vision_utils +{ + +/* Detector Factory */ +typedef Factory<DetectorBase, + const std::string&, + const ParamsBasePtr> DetectorFactory; + +template<> +inline std::string DetectorFactory::getClass() +{ + return "DetectorFactory"; +} + +#define VU_REGISTER_DETECTOR(DetectorType, DetectorName) \ + namespace{ const bool DetectorName##Registered = \ + DetectorFactory::get().registerCreator(DetectorType, DetectorName::create, true); }\ + +} /* namespace vision_utils */ + +#endif /* DETECTOR_FACTORY_H_ */ diff --git a/src/detectors/fast/detector_fast.cpp b/src/detectors/fast/detector_fast.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5410bb62c1f07889489d0f20337086916be119f4 --- /dev/null +++ b/src/detectors/fast/detector_fast.cpp @@ -0,0 +1,17 @@ +#include "detector_fast.h" + +namespace vision_utils { + +DetectorFAST::DetectorFAST(void) +{} + +DetectorFAST::~DetectorFAST(void) +{} + +} /* namespace vision_utils */ + +// Register in the DetectorsFactory +namespace vision_utils +{ +VU_REGISTER_DETECTOR("FAST", DetectorFAST); +} /* namespace vision_utils */ diff --git a/src/detectors/fast/detector_fast.h b/src/detectors/fast/detector_fast.h new file mode 100644 index 0000000000000000000000000000000000000000..627a2ef38223d890ac7e453d8d6906a77b155a94 --- /dev/null +++ b/src/detectors/fast/detector_fast.h @@ -0,0 +1,71 @@ +#ifndef _DETECTOR_FAST_H_ +#define _DETECTOR_FAST_H_ + +#include "../detector_base.h" +#include "../detector_factory.h" + +// yaml-cpp library +#ifdef USING_YAML + #include <yaml-cpp/yaml.h> +#endif + +namespace vision_utils { + +// Create all pointers +VU_PTR_TYPEDEFS(DetectorFAST); +VU_PTR_TYPEDEFS(DetectorParamsFAST); + +/** \brief Class parameters + * + */ +struct DetectorParamsFAST: public ParamsBase +{ + int threshold = 10; // threshold on difference between intensity of the central pixel and pixels of a circle around this pixel. + bool nonmaxSuppression = true; // if true, non-maximum suppression is applied to detected corners (keypoints). + int neighbortype = cv::FastFeatureDetector::TYPE_9_16; // one of the three neighborhoods as defined in the paper: FastFeatureDetector::TYPE_9_16, FastFeatureDetector::TYPE_7_12, FastFeatureDetector::TYPE_5_8 +}; + +/** \brief DETECTOR class + * + */ +class DetectorFAST : public DetectorBase { + + public: + DetectorFAST(); + virtual ~DetectorFAST(void); + + // Factory method + static DetectorBasePtr create(const std::string& _unique_name, const ParamsBasePtr _params); + + private: + + void defineDetector(const ParamsBasePtr _params); +}; + +/* + * brief Define detector + */ +inline void DetectorFAST::defineDetector(const ParamsBasePtr _params) +{ + DetectorParamsFASTPtr params_ptr = std::static_pointer_cast<DetectorParamsFAST>(_params); + + detector_ = cv::FastFeatureDetector::create(params_ptr->threshold, + params_ptr->nonmaxSuppression, + params_ptr->neighbortype); +} + + +/* + * brief Create object in factory + */ +inline DetectorBasePtr DetectorFAST::create(const std::string& _unique_name, const ParamsBasePtr _params) +{ + DetectorFASTPtr det_ptr = std::make_shared<DetectorFAST>(); + det_ptr->setName(_unique_name); + det_ptr->defineDetector(_params); + return det_ptr; +} + +} /* namespace vision_utils */ + +#endif /* _DETECTOR_FAST_H_ */ diff --git a/src/detectors/fast/detector_fast_load_yaml.cpp b/src/detectors/fast/detector_fast_load_yaml.cpp new file mode 100644 index 0000000000000000000000000000000000000000..130e717be820c35304e2ae2e41adbc45c8cca2ba --- /dev/null +++ b/src/detectors/fast/detector_fast_load_yaml.cpp @@ -0,0 +1,47 @@ +#include "detector_fast.h" + +#ifdef USING_YAML + +// yaml-cpp library +#include <yaml-cpp/yaml.h> + +namespace vision_utils +{ + +namespace +{ + +static ParamsBasePtr createParamsFASTDetector(const std::string & _filename_dot_yaml) +{ + DetectorParamsFASTPtr params_ptr = std::make_shared<DetectorParamsFAST>(); + + using std::string; + using YAML::Node; + Node yaml_params = YAML::LoadFile(_filename_dot_yaml); + if (!yaml_params.IsNull()) + { + Node d_yaml = yaml_params["detector"]; + if(d_yaml["type"].as<string>() == "FAST") + { + params_ptr->threshold = d_yaml["threshold"].as<int>(); + params_ptr->nonmaxSuppression = d_yaml["nonmaxSuppression"].as<bool>(); + params_ptr->neighbortype = d_yaml["neighbor type"].as<int>(); + }else + { + std::cerr << "Bad configuration file. Wrong type " << d_yaml["type"].as<string>() << std::endl; + return nullptr; + } + } + + return params_ptr; +} + +// Register in the SensorFactory +const bool registered_detfast_params = ParamsFactory::get().registerCreator("FAST DET", createParamsFASTDetector); + +} /* namespace [unnamed] */ + +} /* namespace vision_utils */ + +#endif /* IF USING_YAML */ + diff --git a/src/detectors/gftt/detector_gftt.cpp b/src/detectors/gftt/detector_gftt.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a00ba7debdfd38e696ae8a1764cf168e5aa790be --- /dev/null +++ b/src/detectors/gftt/detector_gftt.cpp @@ -0,0 +1,17 @@ +#include "detector_gftt.h" + +namespace vision_utils { + +DetectorGFTT::DetectorGFTT(void) +{} + +DetectorGFTT::~DetectorGFTT(void) +{} + +} /* namespace vision_utils */ + +// Register in the DetectorsFactory +namespace vision_utils +{ +VU_REGISTER_DETECTOR("GFTT", DetectorGFTT); +} /* namespace vision_utils */ diff --git a/src/detectors/gftt/detector_gftt.h b/src/detectors/gftt/detector_gftt.h new file mode 100644 index 0000000000000000000000000000000000000000..6bdfecfb4b3e22df12aa370083151c0fd832773e --- /dev/null +++ b/src/detectors/gftt/detector_gftt.h @@ -0,0 +1,77 @@ +#ifndef _DETECTOR_GFTT_H_ +#define _DETECTOR_GFTT_H_ + +#include "../detector_base.h" +#include "../detector_factory.h" + +// yaml-cpp library +#ifdef USING_YAML + #include <yaml-cpp/yaml.h> +#endif + +namespace vision_utils { + +// Create all pointers +VU_PTR_TYPEDEFS(DetectorGFTT); +VU_PTR_TYPEDEFS(DetectorParamsGFTT); + +/** \brief Class parameters + * + */ +struct DetectorParamsGFTT: public ParamsBase +{ + int maxCorners = 1000; + double qualityLevel = 0.01; + double minDistance = 1.0; + int blockSize = 3; + bool useHarrisDetector = false; // Set false by default and non accessible for the user as HARRIS detector is separately defined. + double k = 0.04; +}; + +/** \brief DETECTOR class + * + */ +class DetectorGFTT : public DetectorBase { + + public: + DetectorGFTT(); + virtual ~DetectorGFTT(void); + + // Factory method + static DetectorBasePtr create(const std::string& _unique_name, const ParamsBasePtr _params); + + private: + + void defineDetector(const ParamsBasePtr _params); +}; + +/* + * brief Define detector + */ +inline void DetectorGFTT::defineDetector(const ParamsBasePtr _params) +{ + DetectorParamsGFTTPtr params_ptr = std::static_pointer_cast<DetectorParamsGFTT>(_params); + + detector_ = cv::GFTTDetector::create(params_ptr->maxCorners, + params_ptr->qualityLevel, + params_ptr->minDistance, + params_ptr->blockSize, + params_ptr->useHarrisDetector, + params_ptr->k); +} + + +/* + * brief Create object in factory + */ +inline DetectorBasePtr DetectorGFTT::create(const std::string& _unique_name, const ParamsBasePtr _params) +{ + DetectorGFTTPtr det_ptr = std::make_shared<DetectorGFTT>(); + det_ptr->setName(_unique_name); + det_ptr->defineDetector(_params); + return det_ptr; +} + +} /* namespace vision_utils */ + +#endif /* _DETECTOR_GFTT_H_ */ diff --git a/src/detectors/gftt/detector_gftt_load_yaml.cpp b/src/detectors/gftt/detector_gftt_load_yaml.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1b0931131fc2b5f762a5b93aeedae5b83c480cc2 --- /dev/null +++ b/src/detectors/gftt/detector_gftt_load_yaml.cpp @@ -0,0 +1,49 @@ +#include "detector_gftt.h" + +#ifdef USING_YAML + +// yaml-cpp library +#include <yaml-cpp/yaml.h> + +namespace vision_utils +{ + +namespace +{ + +static ParamsBasePtr createParamsGFTTDetector(const std::string & _filename_dot_yaml) +{ + DetectorParamsGFTTPtr params_ptr = std::make_shared<DetectorParamsGFTT>(); + + using std::string; + using YAML::Node; + Node yaml_params = YAML::LoadFile(_filename_dot_yaml); + if (!yaml_params.IsNull()) + { + Node d_yaml = yaml_params["detector"]; + if(d_yaml["type"].as<string>() == "GFTT") + { + params_ptr->maxCorners = d_yaml["maxCorners"].as<int>(); + params_ptr->qualityLevel = d_yaml["qualityLevel"].as<double>(); + params_ptr->minDistance = d_yaml["minDistance"].as<double>(); + params_ptr->blockSize = d_yaml["blockSize"].as<int>(); + params_ptr->k = d_yaml["k"].as<double>(); + }else + { + std::cerr << "Bad configuration file. Wrong type " << d_yaml["type"].as<string>() << std::endl; + return nullptr; + } + } + + return params_ptr; +} + +// Register in the SensorFactory +const bool registered_detGFTT_params = ParamsFactory::get().registerCreator("GFTT DET", createParamsGFTTDetector); + +} /* namespace [unnamed] */ + +} /* namespace vision_utils */ + +#endif /* IF USING_YAML */ + diff --git a/src/detectors/harris/detector_harris.cpp b/src/detectors/harris/detector_harris.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7af88f690e755f1bc2d4987ac57a8cb3c4c66271 --- /dev/null +++ b/src/detectors/harris/detector_harris.cpp @@ -0,0 +1,17 @@ +#include "detector_harris.h" + +namespace vision_utils { + +DetectorHARRIS::DetectorHARRIS(void) +{} + +DetectorHARRIS::~DetectorHARRIS(void) +{} + +} /* namespace vision_utils */ + +// Register in the DetectorsFactory +namespace vision_utils +{ +VU_REGISTER_DETECTOR("HARRIS", DetectorHARRIS); +} /* namespace vision_utils */ diff --git a/src/detectors/harris/detector_harris.h b/src/detectors/harris/detector_harris.h new file mode 100644 index 0000000000000000000000000000000000000000..c6c3120af18d0800334a6a4b6aa9959b60ac0901 --- /dev/null +++ b/src/detectors/harris/detector_harris.h @@ -0,0 +1,77 @@ +#ifndef _DETECTOR_HARRIS_H_ +#define _DETECTOR_HARRIS_H_ + +#include "../detector_base.h" +#include "../detector_factory.h" + +// yaml-cpp library +#ifdef USING_YAML + #include <yaml-cpp/yaml.h> +#endif + +namespace vision_utils { + +// Create all pointers +VU_PTR_TYPEDEFS(DetectorHARRIS); +VU_PTR_TYPEDEFS(DetectorParamsHARRIS); + +/** \brief Class parameters + * + */ +struct DetectorParamsHARRIS: public ParamsBase +{ + int maxCorners = 1000; + double qualityLevel = 0.01; + double minDistance = 1.0; + int blockSize = 3; + bool useHarrisDetector = true; // Set true by default and non accessible for the user because GFTT detector exists separately. + double k = 0.04; +}; + +/** \brief DETECTOR class + * + */ +class DetectorHARRIS : public DetectorBase { + + public: + DetectorHARRIS(); + virtual ~DetectorHARRIS(void); + + // Factory method + static DetectorBasePtr create(const std::string& _unique_name, const ParamsBasePtr _params); + + private: + + void defineDetector(const ParamsBasePtr _params); +}; + +/* + * brief Define detector + */ +inline void DetectorHARRIS::defineDetector(const ParamsBasePtr _params) +{ + DetectorParamsHARRISPtr params_ptr = std::static_pointer_cast<DetectorParamsHARRIS>(_params); + + detector_ = cv::GFTTDetector::create(params_ptr->maxCorners, + params_ptr->qualityLevel, + params_ptr->minDistance, + params_ptr->blockSize, + params_ptr->useHarrisDetector, + params_ptr->k); +} + + +/* + * brief Create object in factory + */ +inline DetectorBasePtr DetectorHARRIS::create(const std::string& _unique_name, const ParamsBasePtr _params) +{ + DetectorHARRISPtr det_ptr = std::make_shared<DetectorHARRIS>(); + det_ptr->setName(_unique_name); + det_ptr->defineDetector(_params); + return det_ptr; +} + +} /* namespace vision_utils */ + +#endif /* _DETECTOR_HARRIS_H_ */ diff --git a/src/detectors/harris/detector_harris_load_yaml.cpp b/src/detectors/harris/detector_harris_load_yaml.cpp new file mode 100644 index 0000000000000000000000000000000000000000..41127275b18e0d057445a8a7ddc73c447ad9bcdc --- /dev/null +++ b/src/detectors/harris/detector_harris_load_yaml.cpp @@ -0,0 +1,49 @@ +#include "detector_harris.h" + +#ifdef USING_YAML + +// yaml-cpp library +#include <yaml-cpp/yaml.h> + +namespace vision_utils +{ + +namespace +{ + +static ParamsBasePtr createParamsHARRISDetector(const std::string & _filename_dot_yaml) +{ + DetectorParamsHARRISPtr params_ptr = std::make_shared<DetectorParamsHARRIS>(); + + using std::string; + using YAML::Node; + Node yaml_params = YAML::LoadFile(_filename_dot_yaml); + if (!yaml_params.IsNull()) + { + Node d_yaml = yaml_params["detector"]; + if(d_yaml["type"].as<string>() == "HARRIS") + { + params_ptr->maxCorners = d_yaml["maxCorners"].as<int>(); + params_ptr->qualityLevel = d_yaml["qualityLevel"].as<double>(); + params_ptr->minDistance = d_yaml["minDistance"].as<double>(); + params_ptr->blockSize = d_yaml["blockSize"].as<int>(); + params_ptr->k = d_yaml["k"].as<double>(); + }else + { + std::cerr << "Bad configuration file. Wrong type " << d_yaml["type"].as<string>() << std::endl; + return nullptr; + } + } + + return params_ptr; +} + +// Register in the SensorFactory +const bool registered_detHARRIS_params = ParamsFactory::get().registerCreator("HARRIS DET", createParamsHARRISDetector); + +} /* namespace [unnamed] */ + +} /* namespace vision_utils */ + +#endif /* IF USING_YAML */ + diff --git a/src/detectors/kaze/detector_kaze.cpp b/src/detectors/kaze/detector_kaze.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7154cbb1b877e79be6ff296faf2fea4901548811 --- /dev/null +++ b/src/detectors/kaze/detector_kaze.cpp @@ -0,0 +1,17 @@ +#include "detector_kaze.h" + +namespace vision_utils { + +DetectorKAZE::DetectorKAZE(void) +{} + +DetectorKAZE::~DetectorKAZE(void) +{} + +} /* namespace vision_utils */ + +// Register in the DetectorsFactory +namespace vision_utils +{ +VU_REGISTER_DETECTOR("KAZE", DetectorKAZE); +} /* namespace vision_utils */ diff --git a/src/detectors/kaze/detector_kaze.h b/src/detectors/kaze/detector_kaze.h new file mode 100644 index 0000000000000000000000000000000000000000..acd86bdf72f35302c963366b615b5e995a7ddbfd --- /dev/null +++ b/src/detectors/kaze/detector_kaze.h @@ -0,0 +1,77 @@ +#ifndef _DETECTOR_KAZE_H_ +#define _DETECTOR_KAZE_H_ + +#include "../detector_base.h" +#include "../detector_factory.h" + +// yaml-cpp library +#ifdef USING_YAML + #include <yaml-cpp/yaml.h> +#endif + +namespace vision_utils { + +// Create all pointers +VU_PTR_TYPEDEFS(DetectorKAZE); +VU_PTR_TYPEDEFS(DetectorParamsKAZE); + +/** \brief Class parameters + * + */ +struct DetectorParamsKAZE: public ParamsBase +{ + bool extended = false; // Set to enable extraction of extended (128-byte) descriptor. + bool upright = false; // Set to enable use of upright descriptors (non rotation-invariant). + float threshold = 0.001f; // Detector response threshold to accept point + int nOctaves = 4; // Maximum octave evolution of the image + int nOctaveLayers = 4; // Default number of sublevels per scale level + int diffusivity = cv::KAZE::DIFF_PM_G2; // Diffusivity type. DIFF_PM_G1, DIFF_PM_G2, DIFF_WEICKERT or DIFF_CHARBONNIER +}; + +/** \brief DETECTOR class + * + */ +class DetectorKAZE : public DetectorBase { + + public: + DetectorKAZE(); + virtual ~DetectorKAZE(void); + + // Factory method + static DetectorBasePtr create(const std::string& _unique_name, const ParamsBasePtr _params); + + private: + + void defineDetector(const ParamsBasePtr _params); +}; + +/* + * brief Define detector + */ +inline void DetectorKAZE::defineDetector(const ParamsBasePtr _params) +{ + DetectorParamsKAZEPtr params_ptr = std::static_pointer_cast<DetectorParamsKAZE>(_params); + + detector_ = cv::KAZE::create(params_ptr->extended, + params_ptr->upright, + params_ptr->threshold, + params_ptr->nOctaves, + params_ptr->nOctaveLayers, + params_ptr->diffusivity); +} + + +/* + * brief Create object in factory + */ +inline DetectorBasePtr DetectorKAZE::create(const std::string& _unique_name, const ParamsBasePtr _params) +{ + DetectorKAZEPtr det_ptr = std::make_shared<DetectorKAZE>(); + det_ptr->setName(_unique_name); + det_ptr->defineDetector(_params); + return det_ptr; +} + +} /* namespace vision_utils */ + +#endif /* _DETECTOR_KAZE_H_ */ diff --git a/src/detectors/kaze/detector_kaze_load_yaml.cpp b/src/detectors/kaze/detector_kaze_load_yaml.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b53d642f4755fa0d2ffe5e86a4889378b487c9d8 --- /dev/null +++ b/src/detectors/kaze/detector_kaze_load_yaml.cpp @@ -0,0 +1,50 @@ +#include "detector_kaze.h" + +#ifdef USING_YAML + +// yaml-cpp library +#include <yaml-cpp/yaml.h> + +namespace vision_utils +{ + +namespace +{ + +static ParamsBasePtr createParamsKAZEDetector(const std::string & _filename_dot_yaml) +{ + DetectorParamsKAZEPtr params_ptr = std::make_shared<DetectorParamsKAZE>(); + + using std::string; + using YAML::Node; + Node yaml_params = YAML::LoadFile(_filename_dot_yaml); + if (!yaml_params.IsNull()) + { + Node d_yaml = yaml_params["detector"]; + if(d_yaml["type"].as<string>() == "KAZE") + { + params_ptr->extended = d_yaml["extended"].as<bool>(); + params_ptr->upright = d_yaml["upright"].as<bool>(); + params_ptr->threshold = d_yaml["threshold"].as<float>(); + params_ptr->nOctaves = d_yaml["nOctaves"].as<int>(); + params_ptr->nOctaveLayers = d_yaml["nOctaveLayers"].as<int>(); + params_ptr->diffusivity = d_yaml["diffusivity"].as<int>(); + }else + { + std::cerr << "Bad configuration file. Wrong type " << d_yaml["type"].as<string>() << std::endl; + return nullptr; + } + } + + return params_ptr; +} + +// Register in the SensorFactory +const bool registered_detKAZE_params = ParamsFactory::get().registerCreator("KAZE DET", createParamsKAZEDetector); + +} /* namespace [unnamed] */ + +} /* namespace vision_utils */ + +#endif /* IF USING_YAML */ + diff --git a/src/detectors/mser/detector_mser.cpp b/src/detectors/mser/detector_mser.cpp new file mode 100644 index 0000000000000000000000000000000000000000..98c0af8f33f723b3e6f21053e24a566d08377054 --- /dev/null +++ b/src/detectors/mser/detector_mser.cpp @@ -0,0 +1,17 @@ +#include "detector_mser.h" + +namespace vision_utils { + +DetectorMSER::DetectorMSER(void) +{} + +DetectorMSER::~DetectorMSER(void) +{} + +} /* namespace vision_utils */ + +// Register in the DetectorsFactory +namespace vision_utils +{ +VU_REGISTER_DETECTOR("MSER", DetectorMSER); +} /* namespace vision_utils */ diff --git a/src/detectors/mser/detector_mser.h b/src/detectors/mser/detector_mser.h new file mode 100644 index 0000000000000000000000000000000000000000..c620593f994fe0391624333edee7ca05630c2377 --- /dev/null +++ b/src/detectors/mser/detector_mser.h @@ -0,0 +1,83 @@ +#ifndef _DETECTOR_MSER_H_ +#define _DETECTOR_MSER_H_ + +#include "../detector_base.h" +#include "../detector_factory.h" + +// yaml-cpp library +#ifdef USING_YAML + #include <yaml-cpp/yaml.h> +#endif + +namespace vision_utils { + +// Create all pointers +VU_PTR_TYPEDEFS(DetectorMSER); +VU_PTR_TYPEDEFS(DetectorParamsMSER); + +/** \brief Class parameters + * + */ +struct DetectorParamsMSER: public ParamsBase +{ + int delta = 5; // Compares (sizei - sizei-delta)/sizei-delta + int min_area = 60; // Prune the area which smaller than minArea + int max_area = 14400; // Prune the area which bigger than maxArea + double max_variation = 0.25; // Prune the area have simliar size to its children + double min_diversity = 0.2; // For color image, trace back to cut off mser with diversity less than min_diversity + int max_evolution = 200; // For color image, the evolution steps + double area_threshold = 1.01; // For color image, the area threshold to cause re-initialize + double min_margin = 0.003; // For color image, ignore too small margin + int edge_blur_size = 5; // For color image, the aperture size for edge blur +}; + +/** \brief DETECTOR class + * + */ +class DetectorMSER : public DetectorBase { + + public: + DetectorMSER(); + virtual ~DetectorMSER(void); + + // Factory method + static DetectorBasePtr create(const std::string& _unique_name, const ParamsBasePtr _params); + + private: + + void defineDetector(const ParamsBasePtr _params); +}; + +/* + * brief Define detector + */ +inline void DetectorMSER::defineDetector(const ParamsBasePtr _params) +{ + DetectorParamsMSERPtr params_ptr = std::static_pointer_cast<DetectorParamsMSER>(_params); + + detector_ = cv::MSER::create(params_ptr->delta, + params_ptr->min_area, + params_ptr->max_area, + params_ptr->max_variation, + params_ptr->min_diversity, + params_ptr->max_evolution, + params_ptr->area_threshold, + params_ptr->min_margin, + params_ptr->edge_blur_size); +} + + +/* + * brief Create object in factory + */ +inline DetectorBasePtr DetectorMSER::create(const std::string& _unique_name, const ParamsBasePtr _params) +{ + DetectorMSERPtr det_ptr = std::make_shared<DetectorMSER>(); + det_ptr->setName(_unique_name); + det_ptr->defineDetector(_params); + return det_ptr; +} + +} /* namespace vision_utils */ + +#endif /* _DETECTOR_MSER_H_ */ diff --git a/src/detectors/mser/detector_mser_load_yaml.cpp b/src/detectors/mser/detector_mser_load_yaml.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bbe4960943d2dfe827b196254e93eb4fd437d30b --- /dev/null +++ b/src/detectors/mser/detector_mser_load_yaml.cpp @@ -0,0 +1,53 @@ +#include "detector_mser.h" + +#ifdef USING_YAML + +// yaml-cpp library +#include <yaml-cpp/yaml.h> + +namespace vision_utils +{ + +namespace +{ + +static ParamsBasePtr createParamsMSERDetector(const std::string & _filename_dot_yaml) +{ + DetectorParamsMSERPtr params_ptr = std::make_shared<DetectorParamsMSER>(); + + using std::string; + using YAML::Node; + Node yaml_params = YAML::LoadFile(_filename_dot_yaml); + if (!yaml_params.IsNull()) + { + Node d_yaml = yaml_params["detector"]; + if(d_yaml["type"].as<string>() == "MSER") + { + params_ptr->delta = d_yaml["delta"].as<int>(); + params_ptr->min_area = d_yaml["min_area"].as<int>(); + params_ptr->max_area = d_yaml["max_area"].as<int>(); + params_ptr->max_variation = d_yaml["max_variation"].as<double>(); + params_ptr->min_diversity = d_yaml["min_diversity"].as<double>(); + params_ptr->max_evolution = d_yaml["max_evolution"].as<int>(); + params_ptr->area_threshold = d_yaml["area_threshold"].as<double>(); + params_ptr->min_margin = d_yaml["min_margin"].as<double>(); + params_ptr->edge_blur_size = d_yaml["edge_blur_size"].as<int>(); + }else + { + std::cerr << "Bad configuration file. Wrong type " << d_yaml["type"].as<string>() << std::endl; + return nullptr; + } + } + + return params_ptr; +} + +// Register in the SensorFactory +const bool registered_detMSER_params = ParamsFactory::get().registerCreator("MSER DET", createParamsMSERDetector); + +} /* namespace [unnamed] */ + +} /* namespace vision_utils */ + +#endif /* IF USING_YAML */ + diff --git a/src/detectors/orb/detector_orb.cpp b/src/detectors/orb/detector_orb.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d30d1331204e8621e173bde8a8a9c868cdc9c36d --- /dev/null +++ b/src/detectors/orb/detector_orb.cpp @@ -0,0 +1,17 @@ +#include "detector_orb.h" + +namespace vision_utils { + +DetectorORB::DetectorORB(void) +{} + +DetectorORB::~DetectorORB(void) +{} + +} /* namespace vision_utils */ + +// Register in the DetectorsFactory +namespace vision_utils +{ +VU_REGISTER_DETECTOR("ORB", DetectorORB); +} /* namespace vision_utils */ diff --git a/src/detectors/orb/detector_orb.h b/src/detectors/orb/detector_orb.h new file mode 100644 index 0000000000000000000000000000000000000000..63aa0a5dcadd855a2767f807b63f454760b6f938 --- /dev/null +++ b/src/detectors/orb/detector_orb.h @@ -0,0 +1,81 @@ +#ifndef _DETECTOR_ORB_H_ +#define _DETECTOR_ORB_H_ + +#include "../detector_base.h" +#include "../detector_factory.h" + +// yaml-cpp library +#ifdef USING_YAML + #include <yaml-cpp/yaml.h> +#endif + +namespace vision_utils { + +// Create all pointers +VU_PTR_TYPEDEFS(DetectorORB); +VU_PTR_TYPEDEFS(DetectorParamsORB); + +/** \brief Class parameters + * + */ +struct DetectorParamsORB: public ParamsBase +{ + int nfeatures = 500; // The maximum number of features to retain. + float scaleFactor = 2.0f; // Pyramid decimation ratio, greater than 1. scaleFactor==2 means the classical pyramid, where each next level has 4x less pixels than the previous, but such a big scale factor will degrade feature matching scores dramatically. On the other hand, too close to 1 scale factor will mean that to cover certain scale range you will need more pyramid levels and so the speed will suffer. + int nlevels = 8; // The number of pyramid levels. The smallest level will have linear size equal to input_image_linear_size/pow(scaleFactor, nlevels). + int edgeThreshold = 31; // This is size of the border where the features are not detected. It should roughly match the patchSize parameter. + int firstLevel = 0; // It should be 0 in the current implementation. + int WTA_K = 2; // The number of points that produce each element of the oriented BRIEF descriptor. The default value 2 means the BRIEF where we take a random point pair and compare their brightnesses, so we get 0/1 response. Other possible values are 3 and 4. For example, 3 means that we take 3 random points (of course, those point coordinates are random, but they are generated from the pre-defined seed, so each element of BRIEF descriptor is computed deterministically from the pixel rectangle), find point of maximum brightness and output index of the winner (0, 1 or 2). Such output will occupy 2 bits, and therefore it will need a special variant of Hamming distance, denoted as NORM_HAMMING2 (2 bits per bin). When WTA_K=4, we take 4 random points to compute each bin (that will also occupy 2 bits with possible values 0, 1, 2 or 3). + int scoreType = cv::ORB::HARRIS_SCORE; // The default HARRIS_SCORE means that Harris algorithm is used to rank features (the score is written to KeyPoint::score and is used to retain best nfeatures features); FAST_SCORE is alternative value of the parameter that produces slightly less stable keypoints, but it is a little faster to compute. + int patchSize = 31; // size of the patch used by the oriented BRIEF descriptor. Of course, on smaller pyramid layers the perceived image area covered by a feature will be larger. +}; + +/** \brief DETECTOR class + * + */ +class DetectorORB : public DetectorBase { + + public: + DetectorORB(); + virtual ~DetectorORB(void); + + // Factory method + static DetectorBasePtr create(const std::string& _unique_name, const ParamsBasePtr _params); + + private: + + void defineDetector(const ParamsBasePtr _params); +}; + +/* + * brief Define detector + */ +inline void DetectorORB::defineDetector(const ParamsBasePtr _params) +{ + DetectorParamsORBPtr params_ptr = std::static_pointer_cast<DetectorParamsORB>(_params); + + detector_ = cv::ORB::create(params_ptr->nfeatures, + params_ptr->scaleFactor, + params_ptr->nlevels, + params_ptr->edgeThreshold, + params_ptr->firstLevel, + params_ptr->WTA_K, + params_ptr->scoreType, + params_ptr->patchSize); +} + + +/* + * brief Create object in factory + */ +inline DetectorBasePtr DetectorORB::create(const std::string& _unique_name, const ParamsBasePtr _params) +{ + DetectorORBPtr det_ptr = std::make_shared<DetectorORB>(); + det_ptr->setName(_unique_name); + det_ptr->defineDetector(_params); + return det_ptr; +} + +} /* namespace vision_utils */ + +#endif /* _DETECTOR_ORB_H_ */ diff --git a/src/detectors/orb/detector_orb_load_yaml.cpp b/src/detectors/orb/detector_orb_load_yaml.cpp new file mode 100644 index 0000000000000000000000000000000000000000..84a5ba3fcf5f2fbe434c641f328b49080a17186b --- /dev/null +++ b/src/detectors/orb/detector_orb_load_yaml.cpp @@ -0,0 +1,52 @@ +#include "detector_orb.h" + +#ifdef USING_YAML + +// yaml-cpp library +#include <yaml-cpp/yaml.h> + +namespace vision_utils +{ + +namespace +{ + +static ParamsBasePtr createParamsORBDetector(const std::string & _filename_dot_yaml) +{ + DetectorParamsORBPtr params_ptr = std::make_shared<DetectorParamsORB>(); + + using std::string; + using YAML::Node; + Node yaml_params = YAML::LoadFile(_filename_dot_yaml); + if (!yaml_params.IsNull()) + { + Node d_yaml = yaml_params["detector"]; + if(d_yaml["type"].as<string>() == "ORB") + { + params_ptr->nfeatures = d_yaml["nfeatures"].as<unsigned int>(); + params_ptr->scaleFactor = d_yaml["scale factor"].as<float>(); + params_ptr->nlevels = d_yaml["nlevels"].as<unsigned int>(); + params_ptr->edgeThreshold = d_yaml["edge threshold"].as<unsigned int>(); + params_ptr->firstLevel = d_yaml["first level"].as<unsigned int>(); + params_ptr->WTA_K = d_yaml["WTA_K"].as<unsigned int>(); + params_ptr->scoreType = d_yaml["score type"].as<int>(); // enum { kBytes = 32, HARRIS_SCORE=0, FAST_SCORE=1 }; + params_ptr->patchSize = d_yaml["patch size"].as<unsigned int>(); + }else + { + std::cerr << "Bad configuration file. Wrong type " << d_yaml["type"].as<string>() << std::endl; + return nullptr; + } + } + + return params_ptr; +} + +// Register in the SensorFactory +const bool registered_detORB_params = ParamsFactory::get().registerCreator("ORB DET", createParamsORBDetector); + +} /* namespace [unnamed] */ + +} /* namespace vision_utils */ + +#endif /* IF USING_YAML */ + diff --git a/src/detectors/sbd/detector_sbd.cpp b/src/detectors/sbd/detector_sbd.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8ec56fb210b117d78af3af966fd274841b2cf71d --- /dev/null +++ b/src/detectors/sbd/detector_sbd.cpp @@ -0,0 +1,17 @@ +#include "detector_sbd.h" + +namespace vision_utils { + +DetectorSBD::DetectorSBD(void) +{} + +DetectorSBD::~DetectorSBD(void) +{} + +} /* namespace vision_utils */ + +// Register in the DetectorsFactory +namespace vision_utils +{ +VU_REGISTER_DETECTOR("SBD", DetectorSBD); +} /* namespace vision_utils */ diff --git a/src/detectors/sbd/detector_sbd.h b/src/detectors/sbd/detector_sbd.h new file mode 100644 index 0000000000000000000000000000000000000000..ccabc8a333c695fa344096b8fbe000891f777beb --- /dev/null +++ b/src/detectors/sbd/detector_sbd.h @@ -0,0 +1,67 @@ +#ifndef _DETECTOR_SBD_H_ +#define _DETECTOR_SBD_H_ + +#include "../detector_base.h" +#include "../detector_factory.h" + +// yaml-cpp library +#ifdef USING_YAML + #include <yaml-cpp/yaml.h> +#endif + +namespace vision_utils { + +// Create all pointers +VU_PTR_TYPEDEFS(DetectorSBD); +VU_PTR_TYPEDEFS(DetectorParamsSBD); + +/** \brief Class parameters + * + */ +struct DetectorParamsSBD: public ParamsBase +{ + cv::SimpleBlobDetector::Params cv_params = cv::SimpleBlobDetector::Params(); +}; + +/** \brief DETECTOR class + * + */ +class DetectorSBD : public DetectorBase { + + public: + DetectorSBD(); + virtual ~DetectorSBD(void); + + // Factory method + static DetectorBasePtr create(const std::string& _unique_name, const ParamsBasePtr _params); + + private: + + void defineDetector(const ParamsBasePtr _params); +}; + +/* + * brief Define detector + */ +inline void DetectorSBD::defineDetector(const ParamsBasePtr _params) +{ + DetectorParamsSBDPtr params_ptr = std::static_pointer_cast<DetectorParamsSBD>(_params); + + detector_ = cv::SimpleBlobDetector::create(params_ptr->cv_params); +} + + +/* + * brief Create object in factory + */ +inline DetectorBasePtr DetectorSBD::create(const std::string& _unique_name, const ParamsBasePtr _params) +{ + DetectorSBDPtr det_ptr = std::make_shared<DetectorSBD>(); + det_ptr->setName(_unique_name); + det_ptr->defineDetector(_params); + return det_ptr; +} + +} /* namespace vision_utils */ + +#endif /* _DETECTOR_SBD_H_ */ diff --git a/src/detectors/sbd/detector_sbd_load_yaml.cpp b/src/detectors/sbd/detector_sbd_load_yaml.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c0abc6998abef514d7c02772adb1d2ceb372ef19 --- /dev/null +++ b/src/detectors/sbd/detector_sbd_load_yaml.cpp @@ -0,0 +1,67 @@ +#include "detector_sbd.h" + +#ifdef USING_YAML + +// yaml-cpp library +#include <yaml-cpp/yaml.h> + +namespace vision_utils +{ + +namespace +{ + +static ParamsBasePtr createParamsSBDDetector(const std::string & _filename_dot_yaml) +{ + DetectorParamsSBDPtr params_ptr = std::make_shared<DetectorParamsSBD>(); + + using std::string; + using YAML::Node; + Node yaml_params = YAML::LoadFile(_filename_dot_yaml); + if (!yaml_params.IsNull()) + { + Node d_yaml = yaml_params["detector"]; + if(d_yaml["type"].as<string>() == "SBD") + { + params_ptr->cv_params.thresholdStep = d_yaml["thresholdStep"].as<float>(); + params_ptr->cv_params.minThreshold = d_yaml["minThreshold"].as<float>(); + params_ptr->cv_params.maxThreshold = d_yaml["maxThreshold"].as<float>(); + params_ptr->cv_params.minRepeatability = d_yaml["minRepeatability"].as<size_t>(); + params_ptr->cv_params.minDistBetweenBlobs = d_yaml["minDistBetweenBlobs"].as<float>(); + params_ptr->cv_params.filterByColor = d_yaml["filterByColor"].as<bool>(); + std::string bcolor_str = d_yaml["blobColor"].as<std::string>(); + unsigned char bcolor[256]; + copy( bcolor_str.begin(), bcolor_str.end(), bcolor ); + bcolor[bcolor_str.length()] = 0; + params_ptr->cv_params.blobColor = *bcolor; + params_ptr->cv_params.filterByArea = d_yaml["filterByArea"].as<bool>(); + params_ptr->cv_params.minArea = d_yaml["minArea"].as<float>(); + params_ptr->cv_params.maxArea = d_yaml["maxArea"].as<float>(); + params_ptr->cv_params.filterByCircularity = d_yaml["filterByCircularity"].as<bool>(); + params_ptr->cv_params.minCircularity = d_yaml["minCircularity"].as<float>(); + params_ptr->cv_params.maxCircularity = d_yaml["maxCircularity"].as<float>(); + params_ptr->cv_params.filterByInertia = d_yaml["filterByInertia"].as<bool>(); + params_ptr->cv_params.minInertiaRatio = d_yaml["minInertiaRatio"].as<float>(); + params_ptr->cv_params.maxInertiaRatio = d_yaml["maxInertiaRatio"].as<float>(); + params_ptr->cv_params.filterByConvexity = d_yaml["filterByConvexity"].as<bool>(); + params_ptr->cv_params.minConvexity = d_yaml["minConvexity"].as<float>(); + params_ptr->cv_params.maxConvexity = d_yaml["maxConvexity"].as<float>(); + }else + { + std::cerr << "Bad configuration file. Wrong type " << d_yaml["type"].as<string>() << std::endl; + return nullptr; + } + } + + return params_ptr; +} + +// Register in the SensorFactory +const bool registered_detSBD_params = ParamsFactory::get().registerCreator("SBD DET", createParamsSBDDetector); + +} /* namespace [unnamed] */ + +} /* namespace vision_utils */ + +#endif /* IF USING_YAML */ + diff --git a/src/detectors/sift/detector_sift.cpp b/src/detectors/sift/detector_sift.cpp new file mode 100644 index 0000000000000000000000000000000000000000..547ece8bfd82907c0962aa2855dd243577de66b2 --- /dev/null +++ b/src/detectors/sift/detector_sift.cpp @@ -0,0 +1,17 @@ +#include "detector_sift.h" + +namespace vision_utils { + +DetectorSIFT::DetectorSIFT(void) +{} + +DetectorSIFT::~DetectorSIFT(void) +{} + +} /* namespace vision_utils */ + +// Register in the DetectorsFactory +namespace vision_utils +{ +VU_REGISTER_DETECTOR("SIFT", DetectorSIFT); +} /* namespace vision_utils */ diff --git a/src/detectors/sift/detector_sift.h b/src/detectors/sift/detector_sift.h new file mode 100644 index 0000000000000000000000000000000000000000..245449e383199147b655dc009aa143e82bc87d29 --- /dev/null +++ b/src/detectors/sift/detector_sift.h @@ -0,0 +1,75 @@ +#ifndef _DETECTOR_SIFT_H_ +#define _DETECTOR_SIFT_H_ + +#include "../detector_base.h" +#include "../detector_factory.h" + +// yaml-cpp library +#ifdef USING_YAML + #include <yaml-cpp/yaml.h> +#endif + +namespace vision_utils { + +// Create all pointers +VU_PTR_TYPEDEFS(DetectorSIFT); +VU_PTR_TYPEDEFS(DetectorParamsSIFT); + +/** \brief Class parameters + * + */ +struct DetectorParamsSIFT: public ParamsBase +{ + int nfeatures=0; // The number of best features to retain. The features are ranked by their scores (measured in SIFT algorithm as the local contrast) + int nOctaveLayers=3; // The number of layers in each octave. 3 is the value used in D. Lowe paper. The number of octaves is computed automatically from the image resolution. + double contrastThreshold=0.04; // The contrast threshold used to filter out weak features in semi-uniform (low-contrast) regions. The larger the threshold, the less features are produced by the detector. + double edgeThreshold=10; // The threshold used to filter out edge-like features. Note that the its meaning is different from the contrastThreshold, i.e. the larger the edgeThreshold, the less features are filtered out (more features are retained). + double sigma=1.6; // The sigma of the Gaussian applied to the input image at the octave #0. If your image is captured with a weak camera with soft lenses, you might want to reduce the number. +}; + +/** \brief DETECTOR class + * + */ +class DetectorSIFT : public DetectorBase { + + public: + DetectorSIFT(); + virtual ~DetectorSIFT(void); + + // Factory method + static DetectorBasePtr create(const std::string& _unique_name, const ParamsBasePtr _params); + + private: + + void defineDetector(const ParamsBasePtr _params); +}; + +/* + * brief Define detector + */ +inline void DetectorSIFT::defineDetector(const ParamsBasePtr _params) +{ + DetectorParamsSIFTPtr params_ptr = std::static_pointer_cast<DetectorParamsSIFT>(_params); + + detector_ = cv::xfeatures2d::SIFT::create(params_ptr->nfeatures, + params_ptr->nOctaveLayers, + params_ptr->contrastThreshold, + params_ptr->edgeThreshold, + params_ptr->sigma); +} + + +/* + * brief Create object in factory + */ +inline DetectorBasePtr DetectorSIFT::create(const std::string& _unique_name, const ParamsBasePtr _params) +{ + DetectorSIFTPtr det_ptr = std::make_shared<DetectorSIFT>(); + det_ptr->setName(_unique_name); + det_ptr->defineDetector(_params); + return det_ptr; +} + +} /* namespace vision_utils */ + +#endif /* _DETECTOR_SIFT_H_ */ diff --git a/src/detectors/sift/detector_sift_load_yaml.cpp b/src/detectors/sift/detector_sift_load_yaml.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9e4f7b1aafccd4514d841b134dc0809ff7c6ee8a --- /dev/null +++ b/src/detectors/sift/detector_sift_load_yaml.cpp @@ -0,0 +1,49 @@ +#include "detector_sift.h" + +#ifdef USING_YAML + +// yaml-cpp library +#include <yaml-cpp/yaml.h> + +namespace vision_utils +{ + +namespace +{ + +static ParamsBasePtr createParamsSIFTDetector(const std::string & _filename_dot_yaml) +{ + DetectorParamsSIFTPtr params_ptr = std::make_shared<DetectorParamsSIFT>(); + + using std::string; + using YAML::Node; + Node yaml_params = YAML::LoadFile(_filename_dot_yaml); + if (!yaml_params.IsNull()) + { + Node d_yaml = yaml_params["detector"]; + if(d_yaml["type"].as<string>() == "SIFT") + { + params_ptr->nfeatures = d_yaml["nfeatures"].as<int>(); + params_ptr->nOctaveLayers = d_yaml["nOctaveLayers"].as<int>(); + params_ptr->contrastThreshold = d_yaml["contrastThreshold"].as<double>(); + params_ptr->edgeThreshold = d_yaml["edgeThreshold"].as<double>(); + params_ptr->sigma = d_yaml["sigma"].as<double>(); + }else + { + std::cerr << "Bad configuration file. Wrong type " << d_yaml["type"].as<string>() << std::endl; + return nullptr; + } + } + + return params_ptr; +} + +// Register in the SensorFactory +const bool registered_detSIFT_params = ParamsFactory::get().registerCreator("SIFT DET", createParamsSIFTDetector); + +} /* namespace [unnamed] */ + +} /* namespace vision_utils */ + +#endif /* IF USING_YAML */ + diff --git a/src/detectors/surf/detector_surf.cpp b/src/detectors/surf/detector_surf.cpp new file mode 100644 index 0000000000000000000000000000000000000000..65c50310145d37429407059f8cbb64d87844f7da --- /dev/null +++ b/src/detectors/surf/detector_surf.cpp @@ -0,0 +1,17 @@ +#include "detector_surf.h" + +namespace vision_utils { + +DetectorSURF::DetectorSURF(void) +{} + +DetectorSURF::~DetectorSURF(void) +{} + +} /* namespace vision_utils */ + +// Register in the DetectorsFactory +namespace vision_utils +{ +VU_REGISTER_DETECTOR("SURF", DetectorSURF); +} /* namespace vision_utils */ diff --git a/src/detectors/surf/detector_surf.h b/src/detectors/surf/detector_surf.h new file mode 100644 index 0000000000000000000000000000000000000000..aea9575a2c6f85014184dae1c6c408341350a349 --- /dev/null +++ b/src/detectors/surf/detector_surf.h @@ -0,0 +1,75 @@ +#ifndef _DETECTOR_SURF_H_ +#define _DETECTOR_SURF_H_ + +#include "../detector_base.h" +#include "../detector_factory.h" + +// yaml-cpp library +#ifdef USING_YAML + #include <yaml-cpp/yaml.h> +#endif + +namespace vision_utils { + +// Create all pointers +VU_PTR_TYPEDEFS(DetectorSURF); +VU_PTR_TYPEDEFS(DetectorParamsSURF); + +/** \brief Class parameters + * + */ +struct DetectorParamsSURF: public ParamsBase +{ + double hessianThreshold=400; // Threshold for hessian keypoint detector used in SURF. + int nOctaves=4; // Number of pyramid octaves the keypoint detector will use. + int nOctaveLayers=2; // Number of octave layers within each octave. + bool extended=true; // Extended descriptor flag (true - use extended 128-element descriptors; false - use 64-element descriptors). + bool upright=false; // Up-right or rotated features flag (true - do not compute orientation of features; false - compute orientation +}; + +/** \brief DETECTOR class + * + */ +class DetectorSURF : public DetectorBase { + + public: + DetectorSURF(); + virtual ~DetectorSURF(void); + + // Factory method + static DetectorBasePtr create(const std::string& _unique_name, const ParamsBasePtr _params); + + private: + + void defineDetector(const ParamsBasePtr _params); +}; + +/* + * brief Define detector + */ +inline void DetectorSURF::defineDetector(const ParamsBasePtr _params) +{ + DetectorParamsSURFPtr params_ptr = std::static_pointer_cast<DetectorParamsSURF>(_params); + + detector_ = cv::xfeatures2d::SURF::create(params_ptr->hessianThreshold, + params_ptr->nOctaves, + params_ptr->nOctaveLayers, + params_ptr->extended, + params_ptr->upright); +} + + +/* + * brief Create object in factory + */ +inline DetectorBasePtr DetectorSURF::create(const std::string& _unique_name, const ParamsBasePtr _params) +{ + DetectorSURFPtr det_ptr = std::make_shared<DetectorSURF>(); + det_ptr->setName(_unique_name); + det_ptr->defineDetector(_params); + return det_ptr; +} + +} /* namespace vision_utils */ + +#endif /* _DETECTOR_SURF_H_ */ diff --git a/src/detectors/surf/detector_surf_load_yaml.cpp b/src/detectors/surf/detector_surf_load_yaml.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1cd84e8d30d47f8e13b588bccda5dc0214e1cc46 --- /dev/null +++ b/src/detectors/surf/detector_surf_load_yaml.cpp @@ -0,0 +1,49 @@ +#include "detector_surf.h" + +#ifdef USING_YAML + +// yaml-cpp library +#include <yaml-cpp/yaml.h> + +namespace vision_utils +{ + +namespace +{ + +static ParamsBasePtr createParamsSURFDetector(const std::string & _filename_dot_yaml) +{ + DetectorParamsSURFPtr params_ptr = std::make_shared<DetectorParamsSURF>(); + + using std::string; + using YAML::Node; + Node yaml_params = YAML::LoadFile(_filename_dot_yaml); + if (!yaml_params.IsNull()) + { + Node d_yaml = yaml_params["detector"]; + if(d_yaml["type"].as<string>() == "SURF") + { + params_ptr->hessianThreshold = d_yaml["hessianThreshold"].as<double>(); + params_ptr->nOctaves = d_yaml["nOctaves"].as<int>(); + params_ptr->nOctaveLayers = d_yaml["nOctaveLayers"].as<int>(); + params_ptr->extended = d_yaml["extended"].as<bool>(); + params_ptr->upright = d_yaml["upright"].as<bool>(); + }else + { + std::cerr << "Bad configuration file. Wrong type " << d_yaml["type"].as<string>() << std::endl; + return nullptr; + } + } + + return params_ptr; +} + +// Register in the SensorFactory +const bool registered_detSURF_params = ParamsFactory::get().registerCreator("SURF DET", createParamsSURFDetector); + +} /* namespace [unnamed] */ + +} /* namespace vision_utils */ + +#endif /* IF USING_YAML */ + diff --git a/src/examples/CMakeLists.txt b/src/examples/CMakeLists.txt index 699b1161afd320eae55fc39dbaf66d540abffabb..96db02d97131727f7e27f553f128eda5f8c37ddd 100644 --- a/src/examples/CMakeLists.txt +++ b/src/examples/CMakeLists.txt @@ -1,11 +1,15 @@ # create an example application -ADD_EXECUTABLE(capture capture.cpp) -ADD_EXECUTABLE(feature_detectors feature_detect.cpp) -ADD_EXECUTABLE(feature_detectors_and_descriptors feature_detect_descript.cpp) -ADD_EXECUTABLE(feature_detectors_descriptors_and_matchers feature_detect_descript_match.cpp) +ADD_EXECUTABLE(test_factories test_factories.cpp ) +ADD_EXECUTABLE(test_sensor test_sensor.cpp) +ADD_EXECUTABLE(test_detector test_detector.cpp) +ADD_EXECUTABLE(test_descriptor test_descriptor.cpp) +ADD_EXECUTABLE(test_matcher test_matcher.cpp) +ADD_EXECUTABLE(test_algorithm test_algorithm.cpp) # link necessary libraries -TARGET_LINK_LIBRARIES(capture vision_utils) -TARGET_LINK_LIBRARIES(feature_detectors vision_utils) -TARGET_LINK_LIBRARIES(feature_detectors_and_descriptors vision_utils) -TARGET_LINK_LIBRARIES(feature_detectors_descriptors_and_matchers vision_utils) \ No newline at end of file +TARGET_LINK_LIBRARIES(test_factories ${PROJECT_NAME}) +TARGET_LINK_LIBRARIES(test_sensor vision_utils) +TARGET_LINK_LIBRARIES(test_detector vision_utils) +TARGET_LINK_LIBRARIES(test_descriptor vision_utils) +TARGET_LINK_LIBRARIES(test_matcher vision_utils) +TARGET_LINK_LIBRARIES(test_algorithm vision_utils) \ No newline at end of file diff --git a/src/examples/capture.cpp b/src/examples/capture.cpp deleted file mode 100644 index ce2601496a3683ebba4f8f2ee9ebea07f39a0549..0000000000000000000000000000000000000000 --- a/src/examples/capture.cpp +++ /dev/null @@ -1,29 +0,0 @@ -// OWN stuff -#include <string> - -#include <vision_utils.h> - -int main(int argc, char *argv[]) -{ - // Open camera - cv::VideoCapture cam; - CCamUtils cam_fc; - cam_fc.openCamera(0, cam); - - cv::startWindowThread(); - cv::namedWindow("Cam Test", 1); - - for (;;) - { - // Get frame - cv::Mat frame; - cam_fc.getFrame(cam, frame); - - // Show frame - cv::imshow("Cam Test", frame); - cv::waitKey(1); - //if (cv::waitKey(30) >= 0) break; - } - - cv::destroyAllWindows(); -} diff --git a/src/examples/feature_detect.cpp b/src/examples/feature_detect.cpp deleted file mode 100644 index 7dae60b028c05cb5f55133d039e344dcc50b4e16..0000000000000000000000000000000000000000 --- a/src/examples/feature_detect.cpp +++ /dev/null @@ -1,90 +0,0 @@ -// OWN stuff -#include <string> - -#include "vision_utils.h" - - -int main(int argc, char *argv[]) -{ - std::cout << "----------------------------------------" << std::endl; - std::cout << "| Feature detector example |" << std::endl; - std::cout << "----------------------------------------" << std::endl; - std::cout << std::endl; - - CFeature_Detector detector; - CDetector_Params detector_params; // TODO: Fill parameters - - std::vector<std::string> detectors_list; - detectors_list = detector.list(); - - for (unsigned int ii=0; ii<detectors_list.size(); ii++) - std::cout << "[" << ii << "]: " << detectors_list[ii] << std::endl; - - //*********** - // Detector | - //*********** - - // Get default value - int feat_type; - detector.get(feat_type); - - std::cout << std::endl << "Which DETECTOR do you want to test?[default: " << detectors_list[feat_type] << "]"; - - feat_type = readFromUser(feat_type); - - detector.set(detectors_list[feat_type],detector_params); - - std::cout << std::endl << "Testing: " << detectors_list[feat_type] << 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); - - if (!detector.isLine()) - { - KeyPointVector keypoints; - keypoints = detector.detectKeyPoints(frame); - // Show frame with features - detector.drawKeyFeatures(frame, keypoints); - } - else - { - KeyLineVector keypoints; - keypoints = detector.detectKeyLines(frame); - // Show frame with features - detector.drawKeyFeatures(frame, keypoints); - } - - std::cout << "\e[A" << "Detection time: " << detector.getTime() << std::endl; - - // Show NEW frame - cv::imshow("Detections", frame); - cv::waitKey(1); - // if (cv::waitKey(30) >= 0) break; - } - - cv::destroyAllWindows(); -} - - - diff --git a/src/examples/feature_detect_descript.cpp b/src/examples/feature_detect_descript.cpp deleted file mode 100644 index f4ba26456b2b65603bd0ebe9db770286ad7400b9..0000000000000000000000000000000000000000 --- a/src/examples/feature_detect_descript.cpp +++ /dev/null @@ -1,115 +0,0 @@ -// OWN stuff -#include <string> - -#include "vision_utils.h" - - -int main(int argc, char *argv[]) -{ - std::cout << "---------------------------------------------------------" << std::endl; - std::cout << "| Feature detectors and descriptors example |" << std::endl; - std::cout << "---------------------------------------------------------" << std::endl; - std::cout << std::endl; - - //*********** - // Detector | - //*********** - - CFeature_Detector detector; - CDetector_Params detector_params; // TODO: Fill parameters - - std::vector<std::string> detectors_list; - detectors_list = detector.list(); - - for (unsigned int ii=0; ii<detectors_list.size(); ii++) - { - if ( (detectors_list[ii].compare("LSD")!=0) && (detectors_list[ii].compare("ED")!=0) ) - std::cout << "[" << ii << "]: " << detectors_list[ii] << std::endl; - } - - // Get default value - int feat_type; - detector.get(feat_type); - - std::cout << std::endl << "Which DETECTOR do you want to test?[default: " << detectors_list[feat_type] << "]"; - - feat_type = readFromUser(feat_type); - - detector.set(detectors_list[feat_type],detector_params); - - //************* - // Descriptor | - //************* - - CFeature_Descriptor descriptor; - CDescriptor_Params descriptor_params; // TODO: Fill parameters - - std::vector<std::string> descriptor_list; - descriptor_list = descriptor.list(); - - for (unsigned int ii=0; ii<descriptor_list.size(); ii++) - std::cout << "[" << ii << "]: " << descriptor_list[ii] << std::endl; - - // Get default value - int desc_type; - descriptor.get(desc_type); - - std::cout << std::endl << "Which DESCRIPTOR do you want to test?[default: " << descriptor_list[desc_type] << "]"; - - desc_type = readFromUser(desc_type); - - descriptor.set(descriptor_list[desc_type],descriptor_params); - - std::cout << std::endl << "Testing: " << detectors_list[feat_type] << " + " << descriptor_list[desc_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 - 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.getTime() << " " << - "Description time: " << descriptor.getTime() << " " << - "TOTAL time: " << detector.getTime() + descriptor.getTime() << std::endl; - - // Show NEW frame - cv::imshow("Detections", frame); - cv::waitKey(1); - // if (cv::waitKey(30) >= 0) break; - } - - cv::destroyAllWindows(); -} - - - diff --git a/src/examples/feature_detect_descript_match.cpp b/src/examples/feature_detect_descript_match.cpp deleted file mode 100644 index 407643d57364e291cccbaf862fb7f3c1c7c7daa9..0000000000000000000000000000000000000000 --- a/src/examples/feature_detect_descript_match.cpp +++ /dev/null @@ -1,201 +0,0 @@ -// OWN stuff -#include <string> - -#include "vision_utils.h" -#include <sstream> - -int main(int argc, char *argv[]) -{ - std::cout << "-------------------------------------------------------------------" << std::endl; - std::cout << "| Feature detectors, descriptors and matchers example |" << std::endl; - std::cout << "-------------------------------------------------------------------" << std::endl; - std::cout << std::endl; - - //*********** - // Detector | - //*********** - - CFeature_Detector detector; - CDetector_Params detector_params; // TODO: Fill parameters - - std::vector<std::string> detectors_list; - detectors_list = detector.list(); - - for (unsigned int ii=0; ii<detectors_list.size(); ii++) - { - if ( (detectors_list[ii].compare("LSD")!=0) && (detectors_list[ii].compare("ED")!=0) ) - std::cout << "[" << ii << "]: " << detectors_list[ii] << std::endl; - } - - // Get default value - int feat_type; - detector.get(feat_type); - - std::cout << std::endl << "Which DETECTOR do you want to test?[default: " << detectors_list[feat_type] << "]"; - -// feat_type = readFromUser(feat_type); - - detector.set(detectors_list[feat_type],detector_params); - - //************* - // Descriptor | - //************* - - CFeature_Descriptor descriptor; - CDescriptor_Params descriptor_params; // TODO: Fill parameters - - std::vector<std::string> descriptor_list; - descriptor_list = descriptor.list(); - - for (unsigned int ii=0; ii<descriptor_list.size(); ii++) - std::cout << "[" << ii << "]: " << descriptor_list[ii] << std::endl; - - // Get default value - int desc_type; - descriptor.get(desc_type); - - std::cout << std::endl << "Which DESCRIPTOR do you want to test?[default: " << descriptor_list[desc_type] << "]" << std::endl; - -// desc_type = readFromUser(desc_type); - - descriptor.set(descriptor_list[desc_type],descriptor_params); - - //********** - // Matcher | - //********** - - CFeature_Matcher matcher; - CMatcher_Params matcher_params; // TODO: Fill parameters - CMatcher_Params matcher_search_params; // TODO: Fill parameters - - std::vector<std::string> matchers_list; - matchers_list = matcher.list(); - - for (unsigned int ii=0; ii<matchers_list.size(); ii++) - std::cout << "[" << ii << "]: " << matchers_list[ii] << std::endl; - - // Get default value - int match_type; - matcher.get(match_type); - - std::cout << std::endl << "Which MATCHER do you want to test?[default: " << matchers_list[match_type] << "]" << std::endl; - -// match_type = readFromUser(match_type); - - matcher.set(matchers_list[match_type],matcher_params); - - std::vector<std::string> matchers_search_list; - matchers_search_list = matcher.listSearchTypes(); - - for (unsigned int ii=0; ii<matchers_search_list.size(); ii++) - std::cout << "[" << ii << "]: " << matchers_search_list[ii] << std::endl; - - // Get default value - int match_search_type; - matcher.getSearchType(match_search_type); - - std::cout << std::endl << "Which MATCHER SEARCH do you want to test?[default: " << matchers_search_list[match_search_type] << "]" << std::endl; - -// match_search_type = readFromUser(match_search_type); - - matcher.setSearchType(matchers_search_list[match_search_type],matcher_search_params); - - std::cout << std::endl << "Testing: " << detectors_list[feat_type] << " + " << descriptor_list[desc_type] << " + " << matchers_list[match_type] << " + " << matchers_search_list[match_search_type] << " (DETECTOR + DESCRIPTOR + MATCHER + MATCHER SEARCH)" << 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); - cv::namedWindow("Matches", cv::WINDOW_NORMAL); - - cv::Mat frame_old; - KeyPointVector keypoints_old; - KeyPointVector good_keypoints; - cv::Mat descriptors_old; - std::vector<cv::DMatch> good_matches; - - // 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); - cv::Mat frame_matches = frame.clone(); - - // Show ORIGINAL frame - cv::imshow("Original image", frame); - - // Detector - KeyPointVector keypoints; - keypoints = detector.detectKeyPoints(frame); - - // Descriptor - cv::Mat descriptors; - descriptors = descriptor.getDescriptor(frame,keypoints); - - // Matcher - if (nframe > 1) - { - // TODO: Implement this object creation depending on user preferences - // if (matchers_search_list[match_search_type].compare("Match") == 0) - // std::vector<cv::DMatch> matches; - // else - std::vector< std::vector<cv::DMatch> > matches; - matcher.match(descriptors,descriptors_old,matches); - - // Filter matches - good_matches.clear(); - good_keypoints.clear(); - matcher.filterMatches(keypoints_old, keypoints, matches, frame.rows, frame.cols, good_matches, good_keypoints); - } - - // Update objects - keypoints_old.clear(); - keypoints_old.resize(keypoints.size()); - for (unsigned int ii = 0; ii < keypoints.size(); ++ii) - keypoints_old.push_back(keypoints[ii]); - descriptors_old = cv::Mat(descriptors.size(),descriptors.type()); - descriptors_old = descriptors.clone(); - frame_old = frame; - - // Show frame with features - detector.drawKeyFeatures(frame, keypoints); - - // Draw matches - if (nframe > 1 && !keypoints_old.empty() && !keypoints.empty()) - { - matcher.drawKeyFeatures(frame_matches, good_keypoints); -// cv::drawMatches( frame_old, keypoints_old, frame, keypoints, -// good_matches, frame_matches, cv::Scalar::all(-1), cv::Scalar::all(-1), -// std::vector<char>(), cv::DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS ); - for (unsigned int ii = 0; ii < good_keypoints.size(); ++ii) - cv::line(frame_matches,good_keypoints[ii].pt,good_keypoints[ii].pt,cv::Scalar(0,255,0),3); - cv::imshow("Matches", frame_matches); - } - - // Show NEW frame - cv::imshow("Detections", frame); - cv::waitKey(1); - // if (cv::waitKey(30) >= 0) break; - - std::cout << "\e[A" << - "Detection time: " << detector.getTime() << " " << - "Description time: " << descriptor.getTime() << " " << - "Match time: " << matcher.getTime() << " " << - "TOTAL time: " << detector.getTime() + descriptor.getTime() << std::endl; - } - - cv::destroyAllWindows(); -} - - - diff --git a/src/examples/test_algorithm.cpp b/src/examples/test_algorithm.cpp new file mode 100644 index 0000000000000000000000000000000000000000..37457d2c4bfb04de109cedc5090e99d5697f4f26 --- /dev/null +++ b/src/examples/test_algorithm.cpp @@ -0,0 +1,159 @@ +#include <iostream> +#include <iomanip> +#include <cstdlib> + +#include "../vision_utils.h" + +// Sensors +#include "../sensors/usb_cam/usb_cam.h" + +// Detectors +#include "../detectors/orb/detector_orb.h" +#include "../detectors/fast/detector_fast.h" +#include "../detectors/sift/detector_sift.h" +#include "../detectors/surf/detector_surf.h" +#include "../detectors/brisk/detector_brisk.h" +#include "../detectors/mser/detector_mser.h" +#include "../detectors/gftt/detector_gftt.h" +#include "../detectors/harris/detector_harris.h" +#include "../detectors/sbd/detector_sbd.h" +#include "../detectors/kaze/detector_kaze.h" +#include "../detectors/akaze/detector_akaze.h" +#include "../detectors/agast/detector_agast.h" + +// Algorithms +#include "../algorithms/opticalflowpyrlk/alg_opticalflowpyrlk.h" + +#define MIN_GOOD_POINTS 10 + +int main(void) +{ + using namespace vision_utils; + using std::shared_ptr; + using std::make_shared; + using std::static_pointer_cast; + + // YAML file with parameters + std::string path_yaml_file = "/src/examples/yaml"; + + // Root dir path + std::string vu_root = _VU_ROOT_DIR; + + // Setup camera sensor by default + SensorBasePtr sen_b_ptr = setupSensor("USB_CAM", "CAMERA_test", vu_root + path_yaml_file + "/FAST.yaml"); // Any YAML with sensor type setup correctly + SensorCameraPtr sen_ptr = std::static_pointer_cast<SensorCamera>(sen_b_ptr); + + std::string def_detector = "HARRIS"; + std::cout << std::endl << "Which DETECTOR do you want to test? Type one of the registered names [default: " << def_detector << "]: "; + std::string det_name = readFromUser(def_detector); + + DetectorBasePtr det_ptr = setupDetector(det_name, det_name + " detector", vu_root + path_yaml_file + "/" + det_name + ".yaml"); + + if (det_name.compare("ORB") == 0) + det_ptr = std::static_pointer_cast<DetectorORB>(det_ptr); + else if (det_name.compare("FAST") == 0) + det_ptr = std::static_pointer_cast<DetectorFAST>(det_ptr); + else if (det_name.compare("SIFT") == 0) + det_ptr = std::static_pointer_cast<DetectorSIFT>(det_ptr); + else if (det_name.compare("SURF") == 0) + det_ptr = std::static_pointer_cast<DetectorSURF>(det_ptr); + else if (det_name.compare("BRISK") == 0) + det_ptr = std::static_pointer_cast<DetectorBRISK>(det_ptr); + else if (det_name.compare("MSER") == 0) + det_ptr = std::static_pointer_cast<DetectorMSER>(det_ptr); + else if (det_name.compare("GFTT") == 0) + det_ptr = std::static_pointer_cast<DetectorGFTT>(det_ptr); + else if (det_name.compare("HARRIS") == 0) + det_ptr = std::static_pointer_cast<DetectorHARRIS>(det_ptr); + else if (det_name.compare("SBD") == 0) + det_ptr = std::static_pointer_cast<DetectorSBD>(det_ptr); + else if (det_name.compare("KAZE") == 0) + det_ptr = std::static_pointer_cast<DetectorKAZE>(det_ptr); + else if (det_name.compare("AKAZE") == 0) + det_ptr = std::static_pointer_cast<DetectorAKAZE>(det_ptr); + else if (det_name.compare("AGAST") == 0) + det_ptr = std::static_pointer_cast<DetectorAGAST>(det_ptr); + + std::cout << "\n================ OPTICAL FLOW TEST =================" << std::endl; + + std::string def_alg = "OPTFLOWPYRLK"; + std::cout << std::endl << "Which MATCHER do you want to test? Type one of the registered names [default: " << def_alg << "]: "; + std::string alg_name = readFromUser(def_alg); + + AlgorithmBasePtr alg_ptr = setupAlgorithm(alg_name, alg_name + " matcher", vu_root + path_yaml_file + "/" + alg_name + ".yaml"); + + if (alg_name.compare("OPTFLOWPYRLK") == 0) + alg_ptr = std::static_pointer_cast<AlgorithmOPTFLOWPYRLK>(alg_ptr); + + std::cout << std::endl << "... Testing " << det_ptr->getName() << " with " << alg_ptr->getName() << " ..." << std::endl; + + // Open camera + sen_ptr->open(0); + + cv::startWindowThread(); + cv::namedWindow(alg_ptr->getName(), cv::WINDOW_NORMAL); + + // The following line is used to remove the OpenCV "init done" from the terminal + std::cout << "\e[A" << " " << std::endl; + + PointVector pts_prev; + + bool full_frame_detection = true; + + for (int nframe = 0; nframe < 1000; ++nframe) + { + cv::Mat frame_cur; + + // Get frame + sen_ptr->getFrame(frame_cur); + + if (full_frame_detection) + { + full_frame_detection = false; + + // Detect features in current frame (and draw them in current frame). + KeyPointVector kpts = det_ptr->detect(frame_cur); + + // Check new features + PointVector pts = KPToP(kpts); + PointVector pts_new; + PointVector pts_existing; + whoHasMoved(pts_prev, pts, pts_existing, pts_new); + + // Add new features to the buffer + pts_prev.insert(pts_prev.end(),pts_new.begin(),pts_new.end()); + std::sort(pts_prev.begin(), pts_prev.end(), LessPoints); + + // Colour new feature detections + for (int ii = 0; ii < pts_new.size(); ++ii) + cv::circle(frame_cur, pts_new[ii], 5, cv::Scalar(0,255,0), -1); + // Colour matched features + for (int ii = 0; ii < pts_existing.size(); ++ii) + cv::circle(frame_cur, pts_existing[ii], 5, cv::Scalar(128,128,0), -1); + } + else + { + // Algorithm call + PointVector pts_matched_in_frame; + PointVector pts_matched_in_prev; + alg_ptr->compute(frame_cur, pts_prev, pts_matched_in_prev, pts_matched_in_frame); + + // If number of tracked features decreases, rescan and get new features + if (pts_matched_in_frame.size() < MIN_GOOD_POINTS) + full_frame_detection = true; + + // Draw optical flow + for(size_t ii=0; ii<pts_matched_in_frame.size(); ii++) + cv::line(frame_cur, pts_matched_in_prev[ii], pts_matched_in_frame[ii], cv::Scalar(255,0,0), 10); + + // update features found in current frame + pts_prev = pts_matched_in_frame; + std::sort(pts_prev.begin(), pts_prev.end(), LessPoints); + } + + cv::imshow(alg_ptr->getName(), frame_cur); + cv::waitKey(1); + } + + cv::destroyAllWindows(); +} diff --git a/src/examples/test_descriptor.cpp b/src/examples/test_descriptor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6ea20092eabb2037d9edee4eec43b0e5a9e8aece --- /dev/null +++ b/src/examples/test_descriptor.cpp @@ -0,0 +1,149 @@ +#include <iostream> +#include <iomanip> +#include <cstdlib> + +#include "../vision_utils.h" + +// Sensors +#include "../sensors/usb_cam/usb_cam.h" + +// Detectors +#include "../detectors/orb/detector_orb.h" +#include "../detectors/fast/detector_fast.h" +#include "../detectors/sift/detector_sift.h" +#include "../detectors/surf/detector_surf.h" +#include "../detectors/brisk/detector_brisk.h" +#include "../detectors/mser/detector_mser.h" +#include "../detectors/gftt/detector_gftt.h" +#include "../detectors/harris/detector_harris.h" +#include "../detectors/sbd/detector_sbd.h" +#include "../detectors/kaze/detector_kaze.h" +#include "../detectors/akaze/detector_akaze.h" +#include "../detectors/agast/detector_agast.h" + +// Descriptors +#include "../descriptors/orb/descriptor_orb.h" +#include "../descriptors/sift/descriptor_sift.h" +#include "../descriptors/surf/descriptor_surf.h" +#include "../descriptors/brisk/descriptor_brisk.h" +#include "../descriptors/kaze/descriptor_kaze.h" +#include "../descriptors/akaze/descriptor_akaze.h" +#include "../descriptors/latch/descriptor_latch.h" +#include "../descriptors/freak/descriptor_freak.h" +#include "../descriptors/brief/descriptor_brief.h" +#include "../descriptors/daisy/descriptor_daisy.h" +#include "../descriptors/lucid/descriptor_lucid.h" + + +int main(void) +{ + using namespace vision_utils; + using std::shared_ptr; + using std::make_shared; + using std::static_pointer_cast; + + // YAML file with parameters + std::string path_yaml_file = "/src/examples/yaml"; + + // Root dir path + std::string vu_root = _VU_ROOT_DIR; + + // Setup camera sensor by default + SensorBasePtr sen_b_ptr = setupSensor("USB_CAM", "CAMERA_test", vu_root + path_yaml_file + "/FAST.yaml"); // Any YAML with sensor type setup correctly + SensorCameraPtr sen_ptr = std::static_pointer_cast<SensorCamera>(sen_b_ptr); + + std::string def_detector = "ORB"; + std::cout << std::endl << "Which DETECTOR do you want to test? Type one of the registered names [default: " << def_detector << "]: "; + std::string det_name = readFromUser(def_detector); + + DetectorBasePtr det_ptr = setupDetector(det_name, det_name + " detector", vu_root + path_yaml_file + "/" + det_name + ".yaml"); + + if (det_name.compare("ORB") == 0) + det_ptr = std::static_pointer_cast<DetectorORB>(det_ptr); + else if (det_name.compare("FAST") == 0) + det_ptr = std::static_pointer_cast<DetectorFAST>(det_ptr); + else if (det_name.compare("SIFT") == 0) + det_ptr = std::static_pointer_cast<DetectorSIFT>(det_ptr); + else if (det_name.compare("SURF") == 0) + det_ptr = std::static_pointer_cast<DetectorSURF>(det_ptr); + else if (det_name.compare("BRISK") == 0) + det_ptr = std::static_pointer_cast<DetectorBRISK>(det_ptr); + else if (det_name.compare("MSER") == 0) + det_ptr = std::static_pointer_cast<DetectorMSER>(det_ptr); + else if (det_name.compare("GFTT") == 0) + det_ptr = std::static_pointer_cast<DetectorGFTT>(det_ptr); + else if (det_name.compare("HARRIS") == 0) + det_ptr = std::static_pointer_cast<DetectorHARRIS>(det_ptr); + else if (det_name.compare("SBD") == 0) + det_ptr = std::static_pointer_cast<DetectorSBD>(det_ptr); + else if (det_name.compare("KAZE") == 0) + det_ptr = std::static_pointer_cast<DetectorKAZE>(det_ptr); + else if (det_name.compare("AKAZE") == 0) + det_ptr = std::static_pointer_cast<DetectorAKAZE>(det_ptr); + else if (det_name.compare("AGAST") == 0) + det_ptr = std::static_pointer_cast<DetectorAGAST>(det_ptr); + + std::cout << "\n================ DESCRIPTOR TEST =================" << std::endl; + + std::string def_descriptor = "ORB"; + std::cout << std::endl << "Which DESCRIPTOR do you want to test? Type one of the registered names [default: " << def_descriptor << "]: "; + std::string des_name = readFromUser(def_descriptor); + + DescriptorBasePtr des_ptr = setupDescriptor(des_name, des_name + " descriptor", vu_root + path_yaml_file + "/" + des_name + ".yaml"); + + if (des_name.compare("ORB") == 0) + des_ptr = std::static_pointer_cast<DescriptorORB>(des_ptr); + else if (des_name.compare("SIFT") == 0) + des_ptr = std::static_pointer_cast<DescriptorSIFT>(des_ptr); + else if (des_name.compare("SURF") == 0) + des_ptr = std::static_pointer_cast<DescriptorSURF>(des_ptr); + else if (des_name.compare("BRISK") == 0) + des_ptr = std::static_pointer_cast<DescriptorBRISK>(des_ptr); + else if (des_name.compare("KAZE") == 0) + des_ptr = std::static_pointer_cast<DescriptorKAZE>(des_ptr); + else if (des_name.compare("AKAZE") == 0) + des_ptr = std::static_pointer_cast<DescriptorAKAZE>(des_ptr); + else if (des_name.compare("LATCH") == 0) + des_ptr = std::static_pointer_cast<DescriptorLATCH>(des_ptr); + else if (des_name.compare("FREAK") == 0) + des_ptr = std::static_pointer_cast<DescriptorFREAK>(des_ptr); + else if (des_name.compare("BRIEF") == 0) + des_ptr = std::static_pointer_cast<DescriptorBRIEF>(des_ptr); + else if (des_name.compare("DAISY") == 0) + des_ptr = std::static_pointer_cast<DescriptorDAISY>(des_ptr); + else if (des_name.compare("LUCID") == 0) + des_ptr = std::static_pointer_cast<DescriptorLUCID>(des_ptr); + + std::cout << std::endl << "... Testing " << det_ptr->getName() << " with " << des_ptr->getName() << " ..." << std::endl; + + // Open camera + sen_ptr->open(0); + + cv::startWindowThread(); + cv::namedWindow(det_ptr->getName(), 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; + sen_ptr->getFrame(frame); + + // Detector + KeyPointVector keypoints = det_ptr->detect(frame); + + // Descriptor + cv::Mat descriptors = des_ptr->getDescriptor(frame,keypoints); + + drawKeyPoints(frame, keypoints); + + std::cout << std::fixed << std::setprecision(4) << "\e[A" << "Detection time: " << det_ptr->getTime() << " Description time: " << des_ptr->getTime() << " TOTAL time: " << det_ptr->getTime() + des_ptr->getTime() << std::endl; + + // Show frame + cv::imshow(det_ptr->getName(), frame); + cv::waitKey(1); + } + + cv::destroyAllWindows(); +} diff --git a/src/examples/test_detector.cpp b/src/examples/test_detector.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8eef026bc64b66644fd9309fba5723902fa91cf5 --- /dev/null +++ b/src/examples/test_detector.cpp @@ -0,0 +1,102 @@ +#include <iostream> +#include <iomanip> +#include <cstdlib> + +#include "../vision_utils.h" + +// Sensors +#include "../sensors/usb_cam/usb_cam.h" + +// Detectors +#include "../detectors/orb/detector_orb.h" +#include "../detectors/fast/detector_fast.h" +#include "../detectors/sift/detector_sift.h" +#include "../detectors/surf/detector_surf.h" +#include "../detectors/brisk/detector_brisk.h" +#include "../detectors/mser/detector_mser.h" +#include "../detectors/gftt/detector_gftt.h" +#include "../detectors/harris/detector_harris.h" +#include "../detectors/sbd/detector_sbd.h" +#include "../detectors/kaze/detector_kaze.h" +#include "../detectors/akaze/detector_akaze.h" +#include "../detectors/agast/detector_agast.h" + +int main(void) +{ + using namespace vision_utils; + using std::shared_ptr; + using std::make_shared; + using std::static_pointer_cast; + + // YAML file with parameters + std::string path_yaml_file = "/src/examples/yaml"; + + // Root dir path + std::string vu_root = _VU_ROOT_DIR; + + // Setup camera sensor by default + SensorBasePtr sen_b_ptr = setupSensor("USB_CAM", "CAMERA_test", vu_root + path_yaml_file + "/FAST.yaml"); // Any YAML with sensor type setup correctly + SensorCameraPtr sen_ptr = std::static_pointer_cast<SensorCamera>(sen_b_ptr); + + std::cout << "\n================ DETECTOR TEST =================" << std::endl; + + std::string def_detector = "ORB"; + std::cout << std::endl << "Which DETECTOR do you want to test? Type one of the registered names [default: " << def_detector << "]: "; + std::string det_name = readFromUser(def_detector); + + DetectorBasePtr det_ptr = setupDetector(det_name, det_name + " detector", vu_root + path_yaml_file + "/" + det_name + ".yaml"); + + if (det_name.compare("ORB") == 0) + det_ptr = std::static_pointer_cast<DetectorORB>(det_ptr); + else if (det_name.compare("FAST") == 0) + det_ptr = std::static_pointer_cast<DetectorFAST>(det_ptr); + else if (det_name.compare("SIFT") == 0) + det_ptr = std::static_pointer_cast<DetectorSIFT>(det_ptr); + else if (det_name.compare("SURF") == 0) + det_ptr = std::static_pointer_cast<DetectorSURF>(det_ptr); + else if (det_name.compare("BRISK") == 0) + det_ptr = std::static_pointer_cast<DetectorBRISK>(det_ptr); + else if (det_name.compare("MSER") == 0) + det_ptr = std::static_pointer_cast<DetectorMSER>(det_ptr); + else if (det_name.compare("GFTT") == 0) + det_ptr = std::static_pointer_cast<DetectorGFTT>(det_ptr); + else if (det_name.compare("HARRIS") == 0) + det_ptr = std::static_pointer_cast<DetectorHARRIS>(det_ptr); + else if (det_name.compare("SBD") == 0) + det_ptr = std::static_pointer_cast<DetectorSBD>(det_ptr); + else if (det_name.compare("KAZE") == 0) + det_ptr = std::static_pointer_cast<DetectorKAZE>(det_ptr); + else if (det_name.compare("AKAZE") == 0) + det_ptr = std::static_pointer_cast<DetectorAKAZE>(det_ptr); + else if (det_name.compare("AGAST") == 0) + det_ptr = std::static_pointer_cast<DetectorAGAST>(det_ptr); + + std::cout << std::endl << "... Testing " << det_ptr->getName() << " ..." << std::endl; + + // Open camera + sen_ptr->open(0); + + cv::startWindowThread(); + cv::namedWindow(det_ptr->getName(), 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; + sen_ptr->getFrame(frame); + + KeyPointVector keypoints = det_ptr->detect(frame); + + drawKeyPoints(frame, keypoints); + + std::cout << std::fixed << std::setprecision(4) << "\e[A" << "Detection time: " << det_ptr->getTime() << std::endl; + + // Show frame + cv::imshow(det_ptr->getName(), frame); + cv::waitKey(1); + } + + cv::destroyAllWindows(); +} diff --git a/src/examples/test_factories.cpp b/src/examples/test_factories.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2ad0f781b3e6af79a62f64eb18a01dcd2163785c --- /dev/null +++ b/src/examples/test_factories.cpp @@ -0,0 +1,39 @@ +#include <iostream> +#include <iomanip> +#include <cstdlib> + +// Sensors +#include "../sensors/usb_cam/usb_cam.h" + +// Detectors +#include "../detectors/orb/detector_orb.h" +#include "../detectors/fast/detector_fast.h" + +int main(void) +{ + using namespace vision_utils; + using std::shared_ptr; + using std::make_shared; + using std::static_pointer_cast; + + std::cout << "\n====== Registering creators in the Factories =======" << std::endl; + + std::cout << "If you look above, you see the registered creators.\n" + "There is only one attempt per class, and it is successful!\n" + "We do this by registering in the class\'s .cpp file.\n"; + + // Root dir path + std::string vu_root = _VU_ROOT_DIR; + + std::string def_sensor = "USB_CAM"; + std::string sen_name = readFromUser(def_sensor); + + std::string file_dot_yaml = "/src/examples/yaml/FAST.yaml"; // Any yaml with sensor configured + + SensorBasePtr sen_b_ptr = setupSensor(sen_name, sen_name + "_test", vu_root + file_dot_yaml); + SensorCameraPtr usb_cam_ptr = std::static_pointer_cast<SensorCamera>(sen_b_ptr); + + + return 0; +} + diff --git a/src/examples/test_matcher.cpp b/src/examples/test_matcher.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c3cfe0f3926882d80b6c8835153c3d7340bf1f8c --- /dev/null +++ b/src/examples/test_matcher.cpp @@ -0,0 +1,235 @@ +#include <iostream> +#include <iomanip> +#include <cstdlib> + +#include "../vision_utils.h" + +// Sensors +#include "../sensors/usb_cam/usb_cam.h" + +// Detectors +#include "../detectors/orb/detector_orb.h" +#include "../detectors/fast/detector_fast.h" +#include "../detectors/sift/detector_sift.h" +#include "../detectors/surf/detector_surf.h" +#include "../detectors/brisk/detector_brisk.h" +#include "../detectors/mser/detector_mser.h" +#include "../detectors/gftt/detector_gftt.h" +#include "../detectors/harris/detector_harris.h" +#include "../detectors/sbd/detector_sbd.h" +#include "../detectors/kaze/detector_kaze.h" +#include "../detectors/akaze/detector_akaze.h" +#include "../detectors/agast/detector_agast.h" + +// Descriptors +#include "../descriptors/orb/descriptor_orb.h" +#include "../descriptors/sift/descriptor_sift.h" +#include "../descriptors/surf/descriptor_surf.h" +#include "../descriptors/brisk/descriptor_brisk.h" +#include "../descriptors/kaze/descriptor_kaze.h" +#include "../descriptors/akaze/descriptor_akaze.h" +#include "../descriptors/latch/descriptor_latch.h" +#include "../descriptors/freak/descriptor_freak.h" +#include "../descriptors/brief/descriptor_brief.h" +#include "../descriptors/daisy/descriptor_daisy.h" +#include "../descriptors/lucid/descriptor_lucid.h" + +// Matchers +#include "../matchers/flannbased/matcher_flannbased.h" +#include "../matchers/bruteforce/matcher_bruteforce.h" +#include "../matchers/bruteforce_l1/matcher_bruteforce_l1.h" +#include "../matchers/bruteforce_hamming/matcher_bruteforce_hamming.h" +#include "../matchers/bruteforce_hamming_2/matcher_bruteforce_hamming_2.h" + +int main(void) +{ + using namespace vision_utils; + using std::shared_ptr; + using std::make_shared; + using std::static_pointer_cast; + + // YAML file with parameters + std::string path_yaml_file = "/src/examples/yaml"; + + // Root dir path + std::string vu_root = _VU_ROOT_DIR; + + // Setup camera sensor by default + SensorBasePtr sen_b_ptr = setupSensor("USB_CAM", "CAMERA_test", vu_root + path_yaml_file + "/FAST.yaml"); // Any YAML with sensor type setup correctly + SensorCameraPtr sen_ptr = std::static_pointer_cast<SensorCamera>(sen_b_ptr); + + std::string def_detector = "ORB"; + std::cout << std::endl << "Which DETECTOR do you want to test? Type one of the registered names [default: " << def_detector << "]: "; + std::string det_name = readFromUser(def_detector); + + DetectorBasePtr det_ptr = setupDetector(det_name, det_name + " detector", vu_root + path_yaml_file + "/" + det_name + ".yaml"); + + if (det_name.compare("ORB") == 0) + det_ptr = std::static_pointer_cast<DetectorORB>(det_ptr); + else if (det_name.compare("FAST") == 0) + det_ptr = std::static_pointer_cast<DetectorFAST>(det_ptr); + else if (det_name.compare("SIFT") == 0) + det_ptr = std::static_pointer_cast<DetectorSIFT>(det_ptr); + else if (det_name.compare("SURF") == 0) + det_ptr = std::static_pointer_cast<DetectorSURF>(det_ptr); + else if (det_name.compare("BRISK") == 0) + det_ptr = std::static_pointer_cast<DetectorBRISK>(det_ptr); + else if (det_name.compare("MSER") == 0) + det_ptr = std::static_pointer_cast<DetectorMSER>(det_ptr); + else if (det_name.compare("GFTT") == 0) + det_ptr = std::static_pointer_cast<DetectorGFTT>(det_ptr); + else if (det_name.compare("HARRIS") == 0) + det_ptr = std::static_pointer_cast<DetectorHARRIS>(det_ptr); + else if (det_name.compare("SBD") == 0) + det_ptr = std::static_pointer_cast<DetectorSBD>(det_ptr); + else if (det_name.compare("KAZE") == 0) + det_ptr = std::static_pointer_cast<DetectorKAZE>(det_ptr); + else if (det_name.compare("AKAZE") == 0) + det_ptr = std::static_pointer_cast<DetectorAKAZE>(det_ptr); + else if (det_name.compare("AGAST") == 0) + det_ptr = std::static_pointer_cast<DetectorAGAST>(det_ptr); + + std::string def_descriptor = "ORB"; + std::cout << std::endl << "Which DESCRIPTOR do you want to test? Type one of the registered names [default: " << def_descriptor << "]: "; + std::string des_name = readFromUser(def_descriptor); + + DescriptorBasePtr des_ptr = setupDescriptor(des_name, des_name + " descriptor", vu_root + path_yaml_file + "/" + des_name + ".yaml"); + + if (des_name.compare("ORB") == 0) + des_ptr = std::static_pointer_cast<DescriptorORB>(des_ptr); + else if (des_name.compare("SIFT") == 0) + des_ptr = std::static_pointer_cast<DescriptorSIFT>(des_ptr); + else if (des_name.compare("SURF") == 0) + des_ptr = std::static_pointer_cast<DescriptorSURF>(des_ptr); + else if (des_name.compare("BRISK") == 0) + des_ptr = std::static_pointer_cast<DescriptorBRISK>(des_ptr); + else if (des_name.compare("KAZE") == 0) + des_ptr = std::static_pointer_cast<DescriptorKAZE>(des_ptr); + else if (des_name.compare("AKAZE") == 0) + des_ptr = std::static_pointer_cast<DescriptorAKAZE>(des_ptr); + else if (des_name.compare("LATCH") == 0) + des_ptr = std::static_pointer_cast<DescriptorLATCH>(des_ptr); + else if (des_name.compare("FREAK") == 0) + des_ptr = std::static_pointer_cast<DescriptorFREAK>(des_ptr); + else if (des_name.compare("BRIEF") == 0) + des_ptr = std::static_pointer_cast<DescriptorBRIEF>(des_ptr); + else if (des_name.compare("DAISY") == 0) + des_ptr = std::static_pointer_cast<DescriptorDAISY>(des_ptr); + else if (des_name.compare("LUCID") == 0) + des_ptr = std::static_pointer_cast<DescriptorLUCID>(des_ptr); + + std::cout << "\n================ MATCHER TEST =================" << std::endl; + + std::string def_matcher = "BRUTEFORCE"; + std::cout << std::endl << "Which MATCHER do you want to test? Type one of the registered names [default: " << def_matcher << "]: "; + std::string mat_name = readFromUser(def_matcher); + + MatcherBasePtr mat_ptr = setupMatcher(mat_name, mat_name + " matcher", vu_root + path_yaml_file + "/" + mat_name + ".yaml"); + + if (mat_name.compare("FLANNBASED") == 0) + mat_ptr = std::static_pointer_cast<MatcherFLANNBASED>(mat_ptr); + if (mat_name.compare("BRUTEFORCE") == 0) + mat_ptr = std::static_pointer_cast<MatcherBRUTEFORCE>(mat_ptr); + if (mat_name.compare("BRUTEFORCE_L1") == 0) + mat_ptr = std::static_pointer_cast<MatcherBRUTEFORCE_L1>(mat_ptr); + if (mat_name.compare("BRUTEFORCE_HAMMING") == 0) + mat_ptr = std::static_pointer_cast<MatcherBRUTEFORCE_HAMMING>(mat_ptr); + if (mat_name.compare("BRUTEFORCE_HAMMING_2") == 0) + mat_ptr = std::static_pointer_cast<MatcherBRUTEFORCE_HAMMING_2>(mat_ptr); + + std::cout << std::endl << "... Testing " << det_ptr->getName() << " with " << des_ptr->getName() << " and " << mat_ptr->getName() << " ..." << std::endl; + + // Open camera + sen_ptr->open(0); + + cv::startWindowThread(); + cv::namedWindow("OLD", cv::WINDOW_NORMAL); + cv::namedWindow("CURRENT", cv::WINDOW_NORMAL); + cv::namedWindow("MATCHES", cv::WINDOW_NORMAL); + + // The following line is used to remove the OpenCV "init done" from the terminal + std::cout << "\e[A" << " " << std::endl; + + cv::Mat frame_cur; + cv::Mat frame_old; + cv::Mat frame_matches; + + KeyPointVector kpts_old; + cv::Mat descriptors_old; + + KeyPointVector KPBuff; + + for (int nframe = 0; nframe < 1000; ++nframe) + { + // Get frame + sen_ptr->getFrame(frame_cur); + + // Detector + KeyPointVector kpts = det_ptr->detect(frame_cur); + + // Descriptor + cv::Mat descriptors = des_ptr->getDescriptor(frame_cur,kpts); + + // Matcher + if (nframe > 1) + { + std::vector<cv::DMatch> best_matches; + KeyPointVector kpts_matched_curf; + KeyPointVector kpts_matched_prevf; + + // get params + MatcherParamsBasePtr mat_params_ptr = mat_ptr->getParams(); + + if (mat_params_ptr->match_type == MATCH) + { + // match + std::vector<cv::DMatch> matches; + mat_ptr->match(descriptors_old,descriptors,matches); + + // filter + mat_ptr->filterByDistance(10, 0.25, kpts_old, kpts, matches, frame_cur.rows, frame_cur.cols, best_matches, kpts_matched_curf, kpts_matched_prevf); + } + else + { + // match + std::vector< std::vector<cv::DMatch> > matches; + mat_ptr->match(descriptors_old,descriptors,matches); + + //filter + mat_ptr->filterByDistance(10, 0.25, kpts_old, kpts, matches, frame_cur.rows, frame_cur.cols, best_matches, kpts_matched_curf, kpts_matched_prevf); + } + + // Draw + frame_old = frame_cur.clone(); + frame_matches = frame_cur.clone(); + if (!kpts_matched_prevf.empty() && !kpts_matched_curf.empty()) + { + // draw detections + drawKeyPoints(frame_old, kpts_old); + drawKeyPoints(frame_cur, kpts); + + // Draw matches + drawKeyPoints(frame_cur, kpts_matched_curf, 5, cv::Scalar(0, 255, 0), 2); +// cv::drawMatches(frame_old,kpts_matched_prevf,frame_cur,kpts_matched_curf,best_matches,frame_matches); + for(std::vector<cv::DMatch>::size_type ii=0; ii<best_matches.size(); ii++) + cv::line(frame_matches,kpts_matched_prevf[ii].pt,kpts_matched_curf[ii].pt,cv::Scalar(255,255,0),4); + + std::cout << std::fixed << std::setprecision(4) << "\e[A" << "\e[A" << "Detection time: " << det_ptr->getTime() << " Description time: " << des_ptr->getTime() << " Matching time: " << mat_ptr->getTime() << " TOTAL time: " << det_ptr->getTime() + des_ptr->getTime() + mat_ptr->getTime() << std::endl; + std::cout << "Good matches: " << kpts_matched_curf.size() << std::endl; + + // Show frames + cv::imshow("OLD", frame_old); + cv::imshow("CURRENT", frame_cur); + cv::imshow("MATCHES", frame_matches); + cv::waitKey(1); + } + } + + // Update objects + copyKPVector(kpts, kpts_old); + descriptors_old = cv::Mat(descriptors.size(),descriptors.type()); + descriptors_old = descriptors.clone(); + } + + cv::destroyAllWindows(); +} diff --git a/src/examples/test_sensor.cpp b/src/examples/test_sensor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e69f5eb53288c54d76a0c99e4e5fa10419431548 --- /dev/null +++ b/src/examples/test_sensor.cpp @@ -0,0 +1,47 @@ +#include <iostream> +#include <iomanip> +#include <cstdlib> + +// Sensors +#include "../sensors/usb_cam/usb_cam.h" + +int main(void) +{ + using namespace vision_utils; + using std::shared_ptr; + using std::make_shared; + using std::static_pointer_cast; + + // Root dir path + std::string vu_root = _VU_ROOT_DIR; + + std::cout << "\n================ SENSOR TEST =================" << std::endl; + + std::string def_sensor = "USB_CAM"; + std::cout << std::endl << "Which SENSOR do you want to test? Type one of the registered names [default: " << def_sensor << "]: "; + std::string sen_name = readFromUser(def_sensor); + + std::string file_dot_yaml = "/src/examples/yaml/FAST.yaml"; // Any yaml with sensor configured + + SensorBasePtr sen_b_ptr = setupSensor(sen_name, sen_name + "_test", vu_root + file_dot_yaml); + SensorCameraPtr usb_cam_ptr = std::static_pointer_cast<SensorCamera>(sen_b_ptr); + + // Open camera + usb_cam_ptr->open(0); + + cv::startWindowThread(); + cv::namedWindow(usb_cam_ptr->getName(), cv::WINDOW_NORMAL); + + for (int nframe = 0; nframe < 1000; ++nframe) + { + // Get frame + cv::Mat frame; + usb_cam_ptr->getFrame(frame); + + // Show frame + cv::imshow(usb_cam_ptr->getName(), frame); + cv::waitKey(1); + } + + cv::destroyAllWindows(); +} diff --git a/src/examples/yaml/AGAST.yaml b/src/examples/yaml/AGAST.yaml new file mode 100644 index 0000000000000000000000000000000000000000..17a7b8875cf09afe1be1a2dd9896af8bdb137831 --- /dev/null +++ b/src/examples/yaml/AGAST.yaml @@ -0,0 +1,8 @@ +sensor: + type: "USB_CAM" +detector: + type: "AGAST" + threshold: 10 + nonmaxSuppression: true + detection type: 3 # AGAST_5_8=0, AGAST_7_12d=1, AGAST_7_12s=2, OAST_9_16=3, THRESHOLD=10000, NONMAX_SUPPRESSION=10001 + \ No newline at end of file diff --git a/src/examples/yaml/AKAZE.yaml b/src/examples/yaml/AKAZE.yaml new file mode 100644 index 0000000000000000000000000000000000000000..6dcd4edae5c1ab4199df1a44f63ae05060a61c1b --- /dev/null +++ b/src/examples/yaml/AKAZE.yaml @@ -0,0 +1,22 @@ +sensor: + type: "USB_CAM" + +detector: + type: "AKAZE" + descriptor_type: 5 # Type of the extracted descriptor. DESCRIPTOR_KAZE_UPRIGHT=2, DESCRIPTOR_KAZE=3, DESCRIPTOR_MLDB_UPRIGHT=4, DESCRIPTOR_MLDB=5 + descriptor_size: 0 + descriptor_channels: 3 + threshold: 0.001 + nOctaves: 4 + nOctaveLayers: 4 + diffusivity: 1 # Diffusivity type. DIFF_PM_G1=0, DIFF_PM_G2=1, DIFF_WEICKERT=2, DIFF_CHARBONNIER=3 + +descriptor: + type: "AKAZE" + descriptor_type: 5 # Type of the extracted descriptor. DESCRIPTOR_KAZE_UPRIGHT=2, DESCRIPTOR_KAZE=3, DESCRIPTOR_MLDB_UPRIGHT=4, DESCRIPTOR_MLDB=5 + descriptor_size: 0 + descriptor_channels: 3 + threshold: 0.001 + nOctaves: 4 + nOctaveLayers: 4 + diffusivity: 1 # Diffusivity type. DIFF_PM_G1=0, DIFF_PM_G2=1, DIFF_WEICKERT=2, DIFF_CHARBONNIER=3 \ No newline at end of file diff --git a/src/examples/yaml/BRIEF.yaml b/src/examples/yaml/BRIEF.yaml new file mode 100644 index 0000000000000000000000000000000000000000..63204a554e958540457ef925b0e4d2d47ef65dd6 --- /dev/null +++ b/src/examples/yaml/BRIEF.yaml @@ -0,0 +1,6 @@ +sensor: + type: "USB_CAM" +descriptor: + type: "BRIEF" + bytes: 32 + use_orientation: false \ No newline at end of file diff --git a/src/examples/yaml/BRISK.yaml b/src/examples/yaml/BRISK.yaml new file mode 100644 index 0000000000000000000000000000000000000000..fa57fe1980b72f814c182f4ac0cb6c9ca64e95dc --- /dev/null +++ b/src/examples/yaml/BRISK.yaml @@ -0,0 +1,14 @@ +sensor: + type: "USB_CAM" + +detector: + type: "BRISK" + thresh: 30 + octaves: 3 + patternScale: 1.0 + +descriptor: + type: "BRISK" + thresh: 30 + octaves: 3 + patternScale: 1.0 \ No newline at end of file diff --git a/src/examples/yaml/BRUTEFORCE.yaml b/src/examples/yaml/BRUTEFORCE.yaml new file mode 100644 index 0000000000000000000000000000000000000000..77ad4e1654ab71f603cd75642bb553e0227d2a7e --- /dev/null +++ b/src/examples/yaml/BRUTEFORCE.yaml @@ -0,0 +1,5 @@ +sensor: + type: "USB_CAM" +matcher: + type: "BRUTEFORCE" + match type: 1 # Match type. MATCH = 1, KNNMATCH = 2, RADIUSMATCH = 3 \ No newline at end of file diff --git a/src/examples/yaml/BRUTEFORCE_HAMMING.yaml b/src/examples/yaml/BRUTEFORCE_HAMMING.yaml new file mode 100644 index 0000000000000000000000000000000000000000..4a4bcf574afbb05c0a41245a8f7fce9608b84668 --- /dev/null +++ b/src/examples/yaml/BRUTEFORCE_HAMMING.yaml @@ -0,0 +1,5 @@ +sensor: + type: "USB_CAM" +matcher: + type: "BRUTEFORCE_HAMMING" + match type: 1 # Match type. MATCH = 1, KNNMATCH = 2, RADIUSMATCH = 3 \ No newline at end of file diff --git a/src/examples/yaml/BRUTEFORCE_HAMMING_2.yaml b/src/examples/yaml/BRUTEFORCE_HAMMING_2.yaml new file mode 100644 index 0000000000000000000000000000000000000000..86fe6203e9abe3e0db820ccbaa521aa36bde03a8 --- /dev/null +++ b/src/examples/yaml/BRUTEFORCE_HAMMING_2.yaml @@ -0,0 +1,5 @@ +sensor: + type: "USB_CAM" +matcher: + type: "BRUTEFORCE_HAMMING_2" + match type: 1 # Match type. MATCH = 1, KNNMATCH = 2, RADIUSMATCH = 3 \ No newline at end of file diff --git a/src/examples/yaml/BRUTEFORCE_L1.yaml b/src/examples/yaml/BRUTEFORCE_L1.yaml new file mode 100644 index 0000000000000000000000000000000000000000..b73c2cc24099b83017dd81dfcf28a22de42bf8dd --- /dev/null +++ b/src/examples/yaml/BRUTEFORCE_L1.yaml @@ -0,0 +1,5 @@ +sensor: + type: "USB_CAM" +matcher: + type: "BRUTEFORCE_L1" + match type: 1 # Match type. MATCH = 1, KNNMATCH = 2, RADIUSMATCH = 3 \ No newline at end of file diff --git a/src/examples/yaml/DAISY.yaml b/src/examples/yaml/DAISY.yaml new file mode 100644 index 0000000000000000000000000000000000000000..06d6bbe7c7340e62cdd3ece7d65c617e40a482bf --- /dev/null +++ b/src/examples/yaml/DAISY.yaml @@ -0,0 +1,11 @@ +sensor: + type: "USB_CAM" +descriptor: + type: "DAISY" + radius: 15 + q_radius: 3 + q_theta: 8 + q_hist: 8 + norm: 100 # Descriptors normalization type. DAISY::NRM_NONE=100 (default), DAISY::NRM_PARTIAL=101, DAISY::NRM_FULL=102, DAISY::NRM_SIFT=103 + interpolation: true + use_orientation: false \ No newline at end of file diff --git a/src/examples/yaml/FAST.yaml b/src/examples/yaml/FAST.yaml new file mode 100644 index 0000000000000000000000000000000000000000..42f8f70ed783cc1fca0b9932fb0cc7fe12e190b1 --- /dev/null +++ b/src/examples/yaml/FAST.yaml @@ -0,0 +1,7 @@ +sensor: + type: "USB_CAM" +detector: + type: "FAST" + threshold: 10 + nonmaxSuppression: true + neighbor type: 0 #enum { TYPE_9_16=0, TYPE_7_12=1, TYPE_5_8=2 }; diff --git a/src/examples/yaml/FLANNBASED.yaml b/src/examples/yaml/FLANNBASED.yaml new file mode 100644 index 0000000000000000000000000000000000000000..f68781e0282ac10cdf54fd06d72219eabbd55a54 --- /dev/null +++ b/src/examples/yaml/FLANNBASED.yaml @@ -0,0 +1,5 @@ +sensor: + type: "USB_CAM" +matcher: + type: "FLANNBASED" + match type: 1 # Match type. MATCH = 1, KNNMATCH = 2, RADIUSMATCH = 3 \ No newline at end of file diff --git a/src/examples/yaml/FREAK.yaml b/src/examples/yaml/FREAK.yaml new file mode 100644 index 0000000000000000000000000000000000000000..5f34c321277020e68065dbf9f442525306f261ab --- /dev/null +++ b/src/examples/yaml/FREAK.yaml @@ -0,0 +1,9 @@ +sensor: + type: "USB_CAM" +descriptor: + type: "FREAK" + orientationNormalized: true + scaleNormalized: true + patternScale: 22.0 + nOctaves: 4 + selectedPairs: [] \ No newline at end of file diff --git a/src/examples/yaml/GFTT.yaml b/src/examples/yaml/GFTT.yaml new file mode 100644 index 0000000000000000000000000000000000000000..239fa22f2f5f046733bd3d4622b4c8255005ac4d --- /dev/null +++ b/src/examples/yaml/GFTT.yaml @@ -0,0 +1,9 @@ +sensor: + type: "USB_CAM" +detector: + type: "GFTT" + maxCorners: 1000 + qualityLevel: 0.01 + minDistance: 1.0 + blockSize: 3 + k: 0.04 \ No newline at end of file diff --git a/src/examples/yaml/HARRIS.yaml b/src/examples/yaml/HARRIS.yaml new file mode 100644 index 0000000000000000000000000000000000000000..333ac86192f1a2246661e0b2b162b03c6ad4b367 --- /dev/null +++ b/src/examples/yaml/HARRIS.yaml @@ -0,0 +1,9 @@ +sensor: + type: "USB_CAM" +detector: + type: "HARRIS" + maxCorners: 1000 + qualityLevel: 0.01 + minDistance: 1.0 + blockSize: 3 + k: 0.04 \ No newline at end of file diff --git a/src/examples/yaml/KAZE.yaml b/src/examples/yaml/KAZE.yaml new file mode 100644 index 0000000000000000000000000000000000000000..d9c0c8cef7dacc0cc3119b452179c073d95c1994 --- /dev/null +++ b/src/examples/yaml/KAZE.yaml @@ -0,0 +1,21 @@ +sensor: + type: "USB_CAM" + +detector: + type: "KAZE" + extended: false + upright: false + threshold: 0.001 + nOctaves: 4 + nOctaveLayers: 4 + diffusivity: 1 # Diffusivity type. DIFF_PM_G1=0, DIFF_PM_G2=1, DIFF_WEICKERT=2, DIFF_CHARBONNIER=3 + +descriptor: + type: "KAZE" + extended: false + upright: false + threshold: 0.001 + nOctaves: 4 + nOctaveLayers: 4 + diffusivity: 1 # Diffusivity type. DIFF_PM_G1=0, DIFF_PM_G2=1, DIFF_WEICKERT=2, DIFF_CHARBONNIER=3 + \ No newline at end of file diff --git a/src/examples/yaml/LATCH.yaml b/src/examples/yaml/LATCH.yaml new file mode 100644 index 0000000000000000000000000000000000000000..8817312b9b84a8c0f1a28211fbdb009aef3d8f96 --- /dev/null +++ b/src/examples/yaml/LATCH.yaml @@ -0,0 +1,7 @@ +sensor: + type: "USB_CAM" +descriptor: + type: "LATCH" + bytes: 32 + rotationInvariance: true + half_ssd_size: 3 \ No newline at end of file diff --git a/src/examples/yaml/LUCID.yaml b/src/examples/yaml/LUCID.yaml new file mode 100644 index 0000000000000000000000000000000000000000..6889d085676c6cca2c631c54661f3f67ffe7ced5 --- /dev/null +++ b/src/examples/yaml/LUCID.yaml @@ -0,0 +1,6 @@ +sensor: + type: "USB_CAM" +descriptor: + type: "LUCID" + lucid_kernel: 1 + blur_kernel: 2 \ No newline at end of file diff --git a/src/examples/yaml/MSER.yaml b/src/examples/yaml/MSER.yaml new file mode 100644 index 0000000000000000000000000000000000000000..6a9ec2f8d949e04c6b2790cafcaec7c2698096f0 --- /dev/null +++ b/src/examples/yaml/MSER.yaml @@ -0,0 +1,15 @@ +sensor: + type: "USB_CAM" +detector: + type: "MSER" + delta: 5 + min_area: 60 + max_area: 14400 + max_variation: 0.25 + min_diversity: 0.2 + max_evolution: 200 + area_threshold: 1.01 + min_margin: 0.003 + edge_blur_size: 5 + + \ No newline at end of file diff --git a/src/examples/yaml/OPTFLOWPYRLK.yaml b/src/examples/yaml/OPTFLOWPYRLK.yaml new file mode 100644 index 0000000000000000000000000000000000000000..64a611aa2c696a8d168e1554eec8387ff967455e --- /dev/null +++ b/src/examples/yaml/OPTFLOWPYRLK.yaml @@ -0,0 +1,18 @@ +sensor: + type: "USB_CAM" +detector: + type: "HARRIS" + maxCorners: 1000 + qualityLevel: 0.01 + minDistance: 10 + blockSize: 3 + k: 0.04 +algorithm: + type: "OPTFLOWPYRLK" + window edge: 21 + max level: 10 + criteria max count: 30 + criteria epsilon: 0.01 + flags: 0 + min eigen threshold: 1e-4 + min error kpt match: 4.0 diff --git a/src/examples/yaml/ORB.yaml b/src/examples/yaml/ORB.yaml new file mode 100644 index 0000000000000000000000000000000000000000..a0246081df96fba0a69b4b03c1ab0acd9326ff48 --- /dev/null +++ b/src/examples/yaml/ORB.yaml @@ -0,0 +1,26 @@ +sensor: + type: "USB_CAM" + +detector: + type: "ORB" + nfeatures: 100 + scale factor: 2 + nlevels: 8 + edge threshold: 8 # 16 + first level: 0 + WTA_K: 2 # See: http://docs.opencv.org/trunk/db/d95/classcv_1_1ORB.html#a180ae17d3300cf2c619aa240d9b607e5 + score type: 1 #enum { kBytes = 32, HARRIS_SCORE=0, FAST_SCORE=1 }; + patch size: 15 # 31 + +descriptor: + type: "ORB" + nfeatures: 100 + scale factor: 2 + nlevels: 8 + edge threshold: 8 # 16 + first level: 0 + WTA_K: 2 # See: http://docs.opencv.org/trunk/db/d95/classcv_1_1ORB.html#a180ae17d3300cf2c619aa240d9b607e5 + score type: 1 #enum { kBytes = 32, HARRIS_SCORE=0, FAST_SCORE=1 }; + patch size: 15 # 31 + + diff --git a/src/examples/yaml/SBD.yaml b/src/examples/yaml/SBD.yaml new file mode 100644 index 0000000000000000000000000000000000000000..edfd8a5ce5378aa93222cb92ffd743748b7c572c --- /dev/null +++ b/src/examples/yaml/SBD.yaml @@ -0,0 +1,24 @@ +sensor: + type: "USB_CAM" +detector: + type: "SBD" + thresholdStep: 10.0 + minThreshold: 50.0 + maxThreshold: 220.0 + minRepeatability: 2 + minDistBetweenBlobs: 10.0 + filterByColor: false + blobColor: 0 + filterByArea: true + minArea: 25.0 + maxArea: 5000.0 + filterByCircularity: false + minCircularity: 0.8 + maxCircularity: 3.40282e+38 + filterByInertia: true + minInertiaRatio: 0.1 + maxInertiaRatio: 3.40282e+38 + filterByConvexity: true + minConvexity: 0.95 + maxConvexity: 3.40282e+38 + \ No newline at end of file diff --git a/src/examples/yaml/SIFT.yaml b/src/examples/yaml/SIFT.yaml new file mode 100644 index 0000000000000000000000000000000000000000..93404329a5d7367839f7805e066a0dfc3306d166 --- /dev/null +++ b/src/examples/yaml/SIFT.yaml @@ -0,0 +1,18 @@ +sensor: + type: "USB_CAM" + +detector: + type: "SIFT" + nfeatures: 0 + nOctaveLayers: 3 + contrastThreshold: 0.04 + edgeThreshold: 10 + sigma: 1.6 + +descriptor: + type: "SIFT" + nfeatures: 0 + nOctaveLayers: 3 + contrastThreshold: 0.04 + edgeThreshold: 10 + sigma: 1.6 \ No newline at end of file diff --git a/src/examples/yaml/SURF.yaml b/src/examples/yaml/SURF.yaml new file mode 100644 index 0000000000000000000000000000000000000000..69c61fec612b89cf3dba84c88f85c2ac9a58b152 --- /dev/null +++ b/src/examples/yaml/SURF.yaml @@ -0,0 +1,18 @@ +sensor: + type: "USB_CAM" + +detector: + type: "SURF" + hessianThreshold: 400 + nOctaves: 4 + nOctaveLayers: 2 + extended: true + upright: false + +descriptor: + type: "SURF" + hessianThreshold: 400 + nOctaves: 4 + nOctaveLayers: 2 + extended: true + upright: false \ No newline at end of file diff --git a/src/factory.h b/src/factory.h new file mode 100644 index 0000000000000000000000000000000000000000..f9500ed19a24ef65aecf41e390174242338991c2 --- /dev/null +++ b/src/factory.h @@ -0,0 +1,103 @@ +#ifndef _FACTORY_H_ +#define _FACTORY_H_ + +// std +#include <string> +#include <map> +#include <iostream> +#include <iomanip> + +namespace vision_utils +{ + +template<class TypeBase, typename... TypeInput> +class Factory +{ + typedef std::shared_ptr<TypeBase> TypeBasePtr; + public: + // example of creator callback (see typedefs below) + typedef TypeBasePtr (*CreatorCallback)(TypeInput... _input); + + // Main factory API + bool registerCreator(const std::string& _type, CreatorCallback createFn, const bool& print = false); + bool unregisterCreator(const std::string& _type); + TypeBasePtr create(const std::string& _type, TypeInput... _input); + std::string getClass(); + + private: + + typedef std::map<std::string, CreatorCallback> CallbackMap; + + CallbackMap callbacks_; + + // Singleton --------------------------------------------------- + // This class is a singleton. The code below guarantees this. + // See: http://stackoverflow.com/questions/1008019/c-singleton-design-pattern + public: + static Factory& get(); + Factory(const Factory&) = delete; + void operator=(Factory const&) = delete; + private: + Factory() { } + ~Factory() { } +}; + +template<class TypeBase, typename... TypeInput> +inline bool Factory<TypeBase, TypeInput...>::registerCreator(const std::string& _type, CreatorCallback createFn, const bool& print) +{ + bool reg = callbacks_.insert(typename CallbackMap::value_type(_type, createFn)).second; + if (print) + { + if (reg) + std::cout << std::setw(22) << std::left << getClass() << " <-- registered " << _type << std::endl; + else + std::cout << std::setw(22) << std::left << getClass() << " X-- skipping " << _type << ": already registered." << std::endl; + } + return reg; +} + +template<class TypeBase, typename... TypeInput> +inline bool Factory<TypeBase, TypeInput...>::unregisterCreator(const std::string& _type) +{ + return callbacks_.erase(_type) == 1; +} + +template<class TypeBase, typename... TypeInput> +inline typename Factory<TypeBase, TypeInput...>::TypeBasePtr Factory<TypeBase, TypeInput...>::create(const std::string& _type, TypeInput... _input) +{ + typename CallbackMap::const_iterator creator_callback_it = callbacks_.find(_type); + + if (creator_callback_it == callbacks_.end()) + // not found + throw std::runtime_error(getClass() + " : Unknown type \"" + _type + "\". Possibly you tried to use an unregistered creator."); + + // Invoke the creation function + return (creator_callback_it->second)(std::forward<TypeInput>(_input)...); +} + +template<class TypeBase, typename... TypeInput> +inline Factory<TypeBase, TypeInput...>& Factory<TypeBase, TypeInput...>::get() +{ + static Factory instance_; + return instance_; +} + +template<class TypeBase, typename... TypeInput> +inline std::string Factory<TypeBase, TypeInput...>::getClass() +{ + return "Factory<class TypeBase>"; +} + +// Parameters +struct ParamsBase; +typedef Factory<ParamsBase, + const std::string&> ParamsFactory; +template<> +inline std::string ParamsFactory::getClass() +{ + return "ParamsFactory"; +} + +} /* namespace vision_utils */ + +#endif diff --git a/src/feature_descriptor/feature_descriptor.cpp b/src/feature_descriptor/feature_descriptor.cpp deleted file mode 100644 index aca2e4049f7074d7d7f5a5fb420f6fc8e429c284..0000000000000000000000000000000000000000 --- a/src/feature_descriptor/feature_descriptor.cpp +++ /dev/null @@ -1,121 +0,0 @@ -#include "feature_descriptor.h" - -CFeature_Descriptor::CFeature_Descriptor(const std::string& _type, const CDescriptor_Params& _params) -{ - setAllTypes(); - - is_init_ = init(_type, _params); - - if (!is_init_) - { - std::cerr - << "[Feature Descriptor]: Something went wrong during initialization! Feature Descriptor not initialized." - << std::endl; - } -} - -CFeature_Descriptor::CFeature_Descriptor() -{ - setAllTypes(); -} - -CFeature_Descriptor::~CFeature_Descriptor() { -} - -void CFeature_Descriptor::setAllTypes(void) -{ - // Define all types - std::vector<std::string> types; - types += "ORB", "SIFT", "SURF", "KAZE", "AKAZE", "BRISK", "LATCH", "FREAK", "BRIEF", "DAISY", "LUCID"; - types_.set(types); - type_ = "ORB"; // Default value -} - -bool CFeature_Descriptor::init(const std::string& _type, const CDescriptor_Params& _params) -{ - if (is_init_) - { - std::cerr << "[CFeature_Descriptor]: Descriptor already initialized." << std::endl; - return false; - } - - // TODO: Set parameters for each detector type - if (_type.compare(types_(0))==0) - { - feature_descriptor_ = cv::ORB::create(); - type_ = types_(0); - } - else if (_type.compare(types_(1))==0) - { - feature_descriptor_ = cv::xfeatures2d::SIFT::create(); - type_ = types_(1); - } - else if (_type.compare(types_(2))==0) - { - feature_descriptor_ = cv::xfeatures2d::SURF::create(); - type_ = types_(2); - } - else if (_type.compare(types_(3))==0) - { - feature_descriptor_ = cv::KAZE::create(); - type_ = types_(3); - } - else if (_type.compare(types_(4))==0) - { - feature_descriptor_ = cv::AKAZE::create(); - type_ = types_(4); - } - else if (_type.compare(types_(5))==0) - { - feature_descriptor_ = cv::BRISK::create(); - type_ = types_(0); - } - else if (_type.compare(types_(6))==0) - { - feature_descriptor_ = cv::xfeatures2d::LATCH::create(); - type_ = types_(6); - } - else if (_type.compare(types_(7))==0) - { - feature_descriptor_ = cv::xfeatures2d::FREAK::create(); - type_ = types_(7); - } - else if (_type.compare(types_(8))==0) - { - feature_descriptor_ = cv::xfeatures2d::BriefDescriptorExtractor::create(); - type_ = types_(8); - } - else if (_type.compare(types_(9))==0) - { - feature_descriptor_ = cv::xfeatures2d::DAISY::create(); - type_ = types_(9); - } - else if (_type.compare(types_(10))==0) - { - feature_descriptor_ = cv::xfeatures2d::LUCID::create(1,2); - type_ = types_(10); - } - else - { - std::cerr << "[Feature Descriptor]: descriptor type " << _type << " doesn't exist !" << std::endl; - return false; - } - - is_init_ = true; - return true; -} - -cv::Mat CFeature_Descriptor::getDescriptor(const cv::Mat& _image, KeyPointVector& _kpts) -{ - if (!is_init_) - std::cerr << "[CFeature_Descriptor::getDescriptor]: Descriptor non initialized." << std::endl; - - cv::Mat descriptors; - - clock_t tStart = clock(); - if (!_kpts.empty()) - feature_descriptor_->compute(_image, _kpts, descriptors); - comp_time_ = (double)(clock() - tStart) / CLOCKS_PER_SEC; - - return descriptors; -} diff --git a/src/feature_descriptor/feature_descriptor.h b/src/feature_descriptor/feature_descriptor.h deleted file mode 100644 index 27cd86676dd7230dbf96a3cffefd70e33b2926e6..0000000000000000000000000000000000000000 --- a/src/feature_descriptor/feature_descriptor.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef _FEATURE_DESCRIPTOR_H -#define _FEATURE_DESCRIPTOR_H - -#include "../common/vu_base.h" - -typedef cv::Ptr<cv::DescriptorExtractor> FeatureDescriptorPtr; - -/** - * \brief Feature descriptor parameters class - */ -class CDescriptor_Params: public CParams { -public: - CDescriptor_Params(void) { - } - ; - ~CDescriptor_Params(void) { - } - ; -}; - -class CFeature_Descriptor: public CVu_Base <CDescriptor_Params>{ - -public: - - CFeature_Descriptor(const std::string& _type, const CDescriptor_Params& _params); - CFeature_Descriptor(void); - - ~CFeature_Descriptor(void); - - /** - * \brief Get descriptors - */ - cv::Mat getDescriptor(const cv::Mat& _image, - KeyPointVector& _kpts); - -private: - - FeatureDescriptorPtr feature_descriptor_; // Feature point descriptor - - /** - * \brief Set all types - */ - void setAllTypes(void); - - /** - * \brief Initialize descriptor - */ - bool init(const std::string &_type, const CDescriptor_Params &_params); -}; - -#endif diff --git a/src/feature_detector/feature_detector.cpp b/src/feature_detector/feature_detector.cpp deleted file mode 100644 index 9dacdec7fe9bd6d80213185a937893c25a5c369a..0000000000000000000000000000000000000000 --- a/src/feature_detector/feature_detector.cpp +++ /dev/null @@ -1,202 +0,0 @@ -#include "feature_detector.h" - -CFeature_Detector::CFeature_Detector(const std::string& _type, const CDetector_Params& _params) : - is_line_(false), is_limited_(false), keypoints_limit_(-1) -{ - setAllTypes(); - - is_init_ = init(_type, _params); - - if (!is_init_) - { - std::cerr << "[Feature Detector]: Something went wrong during initialization! Feature Detector not initialized." - << std::endl; - } -} - -CFeature_Detector::CFeature_Detector(void) : - is_line_(false), is_limited_(false), keypoints_limit_(-1) -{ - setAllTypes(); -} - -CFeature_Detector::~CFeature_Detector() -{ -} - -void CFeature_Detector::setAllTypes(void) -{ - // Define all types - std::vector<std::string> types; - types += "FAST", "SIFT", "SURF", "ORB", "BRISK", "MSER", "GFTT", "HARRIS", "SBD", "KAZE", "AKAZE", "AGAST", "LSD", "ED"; - types_.set(types); - type_ = "ORB"; // Default value -} - -bool CFeature_Detector::init(const std::string& _type, const CDetector_Params& _params) -{ - if (is_init_) - { - std::cerr << "[CFeature_Detector::init]: Detector already initialized." << std::endl; - return false; - } - - // TODO: Set parameters for each detector type - if (_type.compare(types_(0))==0) - { - feature_detector_ = cv::FastFeatureDetector::create(); - type_ = types_(0); - } - else if (_type.compare(types_(1))==0) - { - feature_detector_ = cv::xfeatures2d::SIFT::create(); - type_ = types_(1); - } - else if (_type.compare(types_(2))==0) - { - feature_detector_ = cv::xfeatures2d::SURF::create(); - type_ = types_(2); - } - else if (_type.compare(types_(3))==0) - { - feature_detector_ = cv::ORB::create(); - type_ = types_(3); - } - else if (_type.compare(types_(4))==0) - { - feature_detector_ = cv::BRISK::create(); - type_ = types_(4); - } - else if (_type.compare(types_(5))==0) - { - feature_detector_ = cv::MSER::create(); - type_ = types_(0); - } - else if (_type.compare(types_(6))==0) - { - feature_detector_ = cv::GFTTDetector::create(1000, 0.01, 1.0, 3, false, 0.04); - type_ = types_(6); - } - else if (_type.compare(types_(7))==0) - { - feature_detector_ = cv::GFTTDetector::create(1000, 0.01, 1.0, 3, true, 0.04); - type_ = types_(7); - } - else if (_type.compare(types_(8))==0) - { - feature_detector_ = cv::SimpleBlobDetector::create(); - type_ = types_(8); - } - else if (_type.compare(types_(9))==0) - { - feature_detector_ = cv::KAZE::create(); - type_ = types_(9); - } - else if (_type.compare(types_(10))==0) - { - feature_detector_ = cv::AKAZE::create(); - type_ = types_(10); - } - else if (_type.compare(types_(11))==0) - { - feature_detector_ = cv::AgastFeatureDetector::create(); - type_ = types_(11); - } - else if (_type.compare(types_(12))==0) - { - lsd_detector_ = cv::line_descriptor::LSDDetector::createLSDDetector(); - type_ = types_(12); - } - else if (_type.compare(types_(13))==0) - { - ed_detector_ = cv::line_descriptor::BinaryDescriptor::createBinaryDescriptor(); - type_ = types_(13); - } - else - { - std::cerr << "[Feature Detector]: detector_type " << _type << " doesn't exist !" << std::endl; - return false; - } - - is_init_ = true; - return true; -} - -bool CFeature_Detector::isLine(void) -{ - return is_line_; -} - -bool CFeature_Detector::isLimited(void) -{ - return is_limited_; -} - -int CFeature_Detector::getKeyPointsLimit(void) -{ - return keypoints_limit_; -} - -KeyPointVector CFeature_Detector::detectKeyPoints(const cv::Mat& _image) -{ - cv::Mat mask = cv::Mat::ones(_image.size(), CV_8U); - return detectKeyPoints(_image, mask); -} - -KeyPointVector CFeature_Detector::detectKeyPoints(const cv::Mat& _image, const cv::Mat& _mask) -{ - if (!is_init_) - std::cerr << "[CFeature_Detector::detectKeyPoints]: Detector non initialized." << std::endl; - - KeyPointVector kpts; - - clock_t tStart = clock(); - feature_detector_->detect(_image, kpts, _mask); - comp_time_ = (double)(clock() - tStart) / CLOCKS_PER_SEC; - - if (isLimited()) - { - cv::KeyPointsFilter filter; - filter.retainBest(kpts, this->getKeyPointsLimit()); - } - - return kpts; -} - -KeyLineVector CFeature_Detector::detectKeyLines(const cv::Mat& _image) -{ - cv::Mat mask = cv::Mat::ones(_image.size(), CV_8U); - return detectKeyLines(_image, mask); -} - -KeyLineVector CFeature_Detector::detectKeyLines(const cv::Mat& _image, const cv::Mat& _mask) -{ - if (!is_init_) - std::cerr << "[CFeature_Detector::detectKeyLines]: Detector non initialized." << std::endl; - - KeyLineVector kls; - KeyLineVector kls2; - - clock_t tStart = clock(); - if (type_.compare("LSD")==0) - lsd_detector_->detect(_image, kls, SCALE_FACTOR_LINE_DETECTOR, NUM_OCTAVE_LINE_DETECTOR, _mask); - else - ed_detector_->detect(_image, kls2, _mask); - comp_time_ = (double)(clock() - tStart) / CLOCKS_PER_SEC; - kls.insert(kls.end(), kls2.begin(), kls2.end()); - - return kls; -} - -bool CFeature_Detector::setLimitKeypts(unsigned int _nFeatures) -{ - if (_nFeatures > 0) - { - keypoints_limit_ = _nFeatures; - return is_limited_ = true; - } - - return false; -} - - diff --git a/src/feature_detector/feature_detector.h b/src/feature_detector/feature_detector.h deleted file mode 100644 index fc0d945f90064f91d695244db4ebe7e68f3eb4db..0000000000000000000000000000000000000000 --- a/src/feature_detector/feature_detector.h +++ /dev/null @@ -1,94 +0,0 @@ -#ifndef _FEATURE_DETECTOR_H -#define _FEATURE_DETECTOR_H - -#include "../common/vu_base.h" - -#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 Feature detector parameters class - */ -class CDetector_Params: public CParams { -public: - CDetector_Params(void) { - } - ; - ~CDetector_Params(void) { - } - ; -}; - -/** - * \brief Main feature detector class - */ -class CFeature_Detector: public CVu_Base <CDetector_Params> { -public: - - /** - * \brief Constructor - */ - CFeature_Detector(const std::string& _type, const CDetector_Params& _params); - CFeature_Detector(void); - - /** - * \brief Destructor - */ - ~CFeature_Detector(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); - - /** - * \brief Set number of maximum keypoints allowed - */ - bool setLimitKeypts(unsigned int _nFeatures); - - /** - * \brief Detect features (points or lines) - */ - KeyPointVector detectKeyPoints(const cv::Mat& _image); - KeyPointVector detectKeyPoints(const cv::Mat& _image, const cv::Mat& _mask); - KeyLineVector detectKeyLines(const cv::Mat& _image); - KeyLineVector detectKeyLines(const cv::Mat& _image, const cv::Mat& _mask); - -private: - - // Flags - bool is_line_; - bool is_limited_; - - unsigned int keypoints_limit_; // Max. number of keypoints (saturation) - - FeatureDetectorPtr feature_detector_; // Feature point detectors - LSDDetector lsd_detector_; // Feature line detector - EDDetector ed_detector_; // Feature line detector - - /** - * \brief Set all types - */ - void setAllTypes(void); - - /** - * \brief Initialize detector - */ - bool init(const std::string &_type, const CDetector_Params &_params); -}; - -#endif diff --git a/src/feature_matcher/feature_matcher.cpp b/src/feature_matcher/feature_matcher.cpp deleted file mode 100644 index de1b97a53bd2c30f3e811a6af26ec13564c0020e..0000000000000000000000000000000000000000 --- a/src/feature_matcher/feature_matcher.cpp +++ /dev/null @@ -1,195 +0,0 @@ -#include "feature_matcher.h" - -CFeature_Matcher::CFeature_Matcher(const std::string& _type, const std::string& _match_out_type, const CMatcher_Params& _params) -{ - setAllTypes(); - - is_init_ = init(_type, _params); - - if (!is_init_) - { - std::cerr << "[Feature Matcher]: Something went wrong during initialization! Feature Matcher not initialized." - << std::endl; - } -} - -CFeature_Matcher::CFeature_Matcher(void) -{ - setAllTypes(); -} - -CFeature_Matcher::~CFeature_Matcher(void) -{ -} - -void CFeature_Matcher::setAllTypes(void) -{ - // Define all types - std::vector<std::string> types; - types += "FlannBased", "BruteForce", "BruteForce-L1", "BruteForce-Hamming", "BruteForce-Hamming(2)"; - types_.set(types); - type_ = "BruteForce"; // Default value - - // Define all match output variants - std::vector<std::string> out_types; - out_types += "Match", "knnMatch", "radiusMatch"; - match_search_types_.set(out_types); - match_search_type_ = "knnMatch"; // Default value -} - -std::vector<std::string> CFeature_Matcher::listSearchTypes(void) -{ - return match_search_types_.list(); -} - -void CFeature_Matcher::getSearchType(int& _type) -{ - _type = match_search_types_(match_search_type_); -} - -void CFeature_Matcher::getSearchType(std::string& _type) -{ - _type = match_search_type_; -} - -bool CFeature_Matcher::setSearchType(const std::string& _type, const CMatcher_Params& _params) -{ - // TODO: Set parameters for each matcher type - for (unsigned int ii = 0; ii < match_search_types_.size(); ++ii) - { - if (_type.compare(match_search_types_(ii))==0) - { - match_search_type_ = _type; - match_search_params_ = _params; - return true; - } - } - - std::cerr << "[Feature Matcher]: matcher output type " << _type << " doesn't exist !" << std::endl; - return false; -} - - -bool CFeature_Matcher::init(const std::string& _type, const CMatcher_Params& _params) -{ - if (is_init_) - { - std::cerr - << "[CFeature_Matcher::init]: Matcher already initialized." - << std::endl; - return false; - } - - std::cout << _type << std::endl; - - - // TODO: Set parameters for each matcher type - if (_type.compare(types_(0))==0) - { - feature_matcher_ = cv::DescriptorMatcher::create(_type); - type_ = types_(0); - } - else if (_type.compare(types_(1))==0) - { - feature_matcher_ = cv::DescriptorMatcher::create(_type); - type_ = types_(1); - } - else if (_type.compare(types_(2))==0) - { - feature_matcher_ = cv::DescriptorMatcher::create(_type); - type_ = types_(2); - } - else if (_type.compare(types_(3))==0) - { - feature_matcher_ = cv::DescriptorMatcher::create(_type); - type_ = types_(3); - } - else if (_type.compare(types_(4))==0) - { - feature_matcher_ = cv::DescriptorMatcher::create(_type); - type_ = types_(4); - } - else - { - std::cerr << "[Feature Matcher]: mathcer_type " << _type << " doesn't exist !" << std::endl; - return false; - } - - is_init_ = true; - return true; -} - -// TODO: Match features and process matches (e.g. https://github.com/kipr/opencv/blob/master/samples/cpp/detector_descriptor_matcher_evaluation.cpp) -void CFeature_Matcher::match(const cv::Mat& _desc1, const cv::Mat& _desc2, std::vector<cv::DMatch>& matches) -{ - std::cout << __LINE__ << std::endl; - if (!is_init_) - std::cerr << "[CFeature_Matcher::match]: Matcher non initialized." << std::endl; - - if (match_search_type_.compare(match_search_types_(0))==0) - { - clock_t tStart = clock(); - // TODO: use parameters related with the search type (match_search_params_) - std::cout << __LINE__ << " " << _desc1.size() << " " << _desc2.size() << std::endl; - if (!_desc1.empty() && !_desc2.empty()) - feature_matcher_->match( _desc1, _desc2, matches); - comp_time_ = (double)(clock() - tStart) / CLOCKS_PER_SEC; - } - else - std::cerr << "[CFeature_Matcher::match]: The selected matcher output is different than your object." << std::endl; -} - -// TODO: Match features and process matches (e.g. https://github.com/kipr/opencv/blob/master/samples/cpp/detector_descriptor_matcher_evaluation.cpp) -void CFeature_Matcher::match(const cv::Mat& _desc1, const cv::Mat& _desc2, std::vector< std::vector<cv::DMatch> >& matches) -{ - if (!is_init_) - std::cerr << "[CFeature_Matcher::match]: Matcher non initialized." << std::endl; - - if (match_search_type_.compare(match_search_types_(1))==0)// knn match - { - clock_t tStart = clock(); - // TODO: use parameters related with the search type (match_search_params_) - if (!_desc1.empty() && !_desc2.empty()) - feature_matcher_->knnMatch(_desc1, _desc2, matches, 2); - comp_time_ = (double)(clock() - tStart) / CLOCKS_PER_SEC; - } - else if (match_search_type_.compare(match_search_types_(2))==0) // radius match - { - clock_t tStart = clock(); - // TODO: use parameters related with the search type (match_search_params_) - if (!_desc1.empty() && !_desc2.empty()) - feature_matcher_->radiusMatch(_desc1, _desc2, matches, 2); - comp_time_ = (double)(clock() - tStart) / CLOCKS_PER_SEC; - } - else - std::cerr << "[CFeature_Matcher::match]: The selected matcher output is different than your object." << std::endl; -} - -void CFeature_Matcher::filterMatches(const KeyPointVector& _kpts1,const KeyPointVector& _kpts2, const std::vector< std::vector<cv::DMatch> >& _dirty, const int& _img_width, const int& _img_height, std::vector<cv::DMatch>& _filtered_matches, KeyPointVector& _filtered_kpts) -{ - //only 25% of maximum of possible distance - double tresholdDist = 0.25 * sqrt(double(_img_height*_img_height + _img_width*_img_width)); - - std::vector< cv::DMatch > good_matches2; - _filtered_matches.reserve(_dirty.size()); - for (size_t ii = 0; ii < _dirty.size(); ++ii) - { - for (unsigned int jj = 0; jj < _dirty[ii].size(); jj++) - { - cv::Point2f from = _kpts1[_dirty[ii][jj].queryIdx].pt; - cv::Point2f to = _kpts2[_dirty[ii][jj].trainIdx].pt; - - //calculate local distance for each possible match - double dist = std::sqrt((from.x - to.x) * (from.x - to.x) + (from.y - to.y) * (from.y - to.y)); - - //save as best match if local distance is in specified area and on same height - if (dist < tresholdDist && std::abs(from.y-to.y)<5) - { - _filtered_matches.push_back(_dirty[ii][jj]); - cv::KeyPoint kpt = cv::KeyPoint(to,1); - _filtered_kpts.push_back(kpt); - jj = _dirty[ii].size(); - } - } - } -} diff --git a/src/feature_matcher/feature_matcher.h b/src/feature_matcher/feature_matcher.h deleted file mode 100644 index 6c5eda9a36f625f89a08bb430099ea8653f7d16b..0000000000000000000000000000000000000000 --- a/src/feature_matcher/feature_matcher.h +++ /dev/null @@ -1,81 +0,0 @@ -#ifndef _FEATURE_MATCHER_H -#define _FEATURE_MATCHER_H - -#include "../common/vu_base.h" - -typedef cv::Ptr<cv::DescriptorMatcher> FeatureMatcherPtr; - -/** - * \brief Feature descriptor parameters class - */ -class CMatcher_Params: public CParams { -public: - CMatcher_Params(void) { - } - ; - ~CMatcher_Params(void) { - } - ; -}; - -class CFeature_Matcher: public CVu_Base<CMatcher_Params> -{ - public: - - CFeature_Matcher(const std::string& _type, const std::string& _match_out_type, const CMatcher_Params& _params); - CFeature_Matcher(void); - - ~CFeature_Matcher(void); - - /** - * \brief list all possible match output types (All, K nearest, in a radius search, ...) - */ - std::vector<std::string> listSearchTypes(void); - - /** - * \brief Set matcher search method - */ - bool setSearchType(const std::string& _type, const CMatcher_Params& _params); - - /** - * \brief Get matcher search method - */ - void getSearchType(int& _type); - void getSearchType(std::string& _type); - /** - * \brief Find Matches - */ - void match(const cv::Mat& _desc1, const cv::Mat& _desc2, std::vector<cv::DMatch>& matches); - - /** - * \brief Find K best matches or matches in a radius (depending on selected match_search_type_) - */ - void match(const cv::Mat& _desc1, const cv::Mat& _desc2, std::vector< std::vector<cv::DMatch> >& matches); - - /** - * \brief Look whether the match is inside a defined area of the image - * - * From https://stackoverflow.com/questions/17967950/improve-matching-of-feature-points-with-opencv - */ - void filterMatches(const KeyPointVector& _kpts1,const KeyPointVector& _kpts2, const std::vector< std::vector<cv::DMatch> >& _dirty, const int& _img_width, const int& _img_height, std::vector<cv::DMatch>& _filtered_matches, KeyPointVector& _filtered_kpts); - - private: - - FeatureMatcherPtr feature_matcher_; // Feature matcher - - CTypes match_search_types_; // Match type (match with all, knn and radius search). - CMatcher_Params match_search_params_; // Search type parameters. - std::string match_search_type_; // Match type (match with all, knn and radius search). - - /** - * \brief Set all types - */ - void setAllTypes(void); - - /** - * \brief Initialize matcher - */ - bool init(const std::string &_type, const CMatcher_Params &_params); -}; - -#endif diff --git a/src/matchers/bruteforce/matcher_bruteforce.cpp b/src/matchers/bruteforce/matcher_bruteforce.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6acd1f57c535eac54dbe337ac6648594c97e5f10 --- /dev/null +++ b/src/matchers/bruteforce/matcher_bruteforce.cpp @@ -0,0 +1,17 @@ +#include "matcher_bruteforce.h" + +namespace vision_utils { + +MatcherBRUTEFORCE::MatcherBRUTEFORCE(void) +{} + +MatcherBRUTEFORCE::~MatcherBRUTEFORCE(void) +{} + +} /* namespace vision_utils */ + +// Register in the MatchersFactory +namespace vision_utils +{ +VU_REGISTER_MATCHER("BRUTEFORCE", MatcherBRUTEFORCE); +} /* namespace vision_utils */ diff --git a/src/matchers/bruteforce/matcher_bruteforce.h b/src/matchers/bruteforce/matcher_bruteforce.h new file mode 100644 index 0000000000000000000000000000000000000000..2aee80f80b022110b794ec66697c96eb1bb6b48b --- /dev/null +++ b/src/matchers/bruteforce/matcher_bruteforce.h @@ -0,0 +1,66 @@ +#ifndef _MATCHER_BRUTEFORCE_H_ +#define _MATCHER_BRUTEFORCE_H_ + +#include "../matcher_base.h" +#include "../matcher_factory.h" + +// yaml-cpp library +#ifdef USING_YAML + #include <yaml-cpp/yaml.h> +#endif + +namespace vision_utils { + +// Create all pointers +VU_PTR_TYPEDEFS(MatcherBRUTEFORCE); +VU_PTR_TYPEDEFS(MatcherParamsBRUTEFORCE); + +/** \brief Class parameters + * + */ +struct MatcherParamsBRUTEFORCE: public MatcherParamsBase +{ + // TODO: Add possible parameters +}; + +/** \brief DETECTOR class + * + */ +class MatcherBRUTEFORCE : public MatcherBase { + + public: + MatcherBRUTEFORCE(); + virtual ~MatcherBRUTEFORCE(void); + + // Factory method + static MatcherBasePtr create(const std::string& _unique_name, const ParamsBasePtr _params); + + private: + + void defineMatcher(const ParamsBasePtr _params); +}; + +/* + * brief Define detector + */ +inline void MatcherBRUTEFORCE::defineMatcher(const ParamsBasePtr _params) +{ + params_base_ptr_ = std::static_pointer_cast<MatcherParamsBase>(_params); + MatcherParamsBRUTEFORCEPtr params_ptr = std::static_pointer_cast<MatcherParamsBRUTEFORCE>(_params); + matcher_ = cv::DescriptorMatcher::create("BruteForce"); +} + +/* + * brief Create object in factory + */ +inline MatcherBasePtr MatcherBRUTEFORCE::create(const std::string& _unique_name, const ParamsBasePtr _params) +{ + MatcherBRUTEFORCEPtr mat_ptr = std::make_shared<MatcherBRUTEFORCE>(); + mat_ptr->setName(_unique_name); + mat_ptr->defineMatcher(_params); + return mat_ptr; +} + +} /* namespace vision_utils */ + +#endif /* _MATCHER_BRUTEFORCE_H_ */ diff --git a/src/matchers/bruteforce/matcher_bruteforce_load_yaml.cpp b/src/matchers/bruteforce/matcher_bruteforce_load_yaml.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1749c0f2e035b303be6510bc5e9c8a46e0f95566 --- /dev/null +++ b/src/matchers/bruteforce/matcher_bruteforce_load_yaml.cpp @@ -0,0 +1,46 @@ +#include "matcher_bruteforce.h" + +#ifdef USING_YAML + +// yaml-cpp library +#include <yaml-cpp/yaml.h> + +namespace vision_utils +{ + +namespace +{ + +static ParamsBasePtr createParamsBRUTEFORCEMatcher(const std::string & _filename_dot_yaml) +{ + MatcherParamsBRUTEFORCEPtr params_ptr = std::make_shared<MatcherParamsBRUTEFORCE>(); + + using std::string; + using YAML::Node; + Node yaml_params = YAML::LoadFile(_filename_dot_yaml); + if (!yaml_params.IsNull()) + { + Node d_yaml = yaml_params["matcher"]; + if(d_yaml["type"].as<string>() == "BRUTEFORCE") + { + params_ptr->match_type = d_yaml["match type"].as<int>(); + // TODO: Add possible parameters + }else + { + std::cerr << "Bad configuration file. Wrong type " << d_yaml["type"].as<string>() << std::endl; + return nullptr; + } + } + + return params_ptr; +} + +// Register in the SensorFactory +const bool registered_matBRUTEFORCE_params = ParamsFactory::get().registerCreator("BRUTEFORCE MAT", createParamsBRUTEFORCEMatcher); + +} /* namespace [unnamed] */ + +} /* namespace vision_utils */ + +#endif /* IF USING_YAML */ + diff --git a/src/matchers/bruteforce_hamming/matcher_bruteforce_hamming.cpp b/src/matchers/bruteforce_hamming/matcher_bruteforce_hamming.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0d1dbd3a174542952577c84e4e883cdfaa8a7b63 --- /dev/null +++ b/src/matchers/bruteforce_hamming/matcher_bruteforce_hamming.cpp @@ -0,0 +1,17 @@ +#include "matcher_bruteforce_hamming.h" + +namespace vision_utils { + +MatcherBRUTEFORCE_HAMMING::MatcherBRUTEFORCE_HAMMING(void) +{} + +MatcherBRUTEFORCE_HAMMING::~MatcherBRUTEFORCE_HAMMING(void) +{} + +} /* namespace vision_utils */ + +// Register in the MatchersFactory +namespace vision_utils +{ +VU_REGISTER_MATCHER("BRUTEFORCE_HAMMING", MatcherBRUTEFORCE_HAMMING); +} /* namespace vision_utils */ diff --git a/src/matchers/bruteforce_hamming/matcher_bruteforce_hamming.h b/src/matchers/bruteforce_hamming/matcher_bruteforce_hamming.h new file mode 100644 index 0000000000000000000000000000000000000000..bc2c1606ab38ae190fa79b5f699cfce82a03f260 --- /dev/null +++ b/src/matchers/bruteforce_hamming/matcher_bruteforce_hamming.h @@ -0,0 +1,66 @@ +#ifndef _MATCHER_BRUTEFORCE_HAMMING_H_ +#define _MATCHER_BRUTEFORCE_HAMMING_H_ + +#include "../matcher_base.h" +#include "../matcher_factory.h" + +// yaml-cpp library +#ifdef USING_YAML + #include <yaml-cpp/yaml.h> +#endif + +namespace vision_utils { + +// Create all pointers +VU_PTR_TYPEDEFS(MatcherBRUTEFORCE_HAMMING); +VU_PTR_TYPEDEFS(MatcherParamsBRUTEFORCE_HAMMING); + +/** \brief Class parameters + * + */ +struct MatcherParamsBRUTEFORCE_HAMMING: public MatcherParamsBase +{ + // TODO: Add possible parameters +}; + +/** \brief DETECTOR class + * + */ +class MatcherBRUTEFORCE_HAMMING : public MatcherBase { + + public: + MatcherBRUTEFORCE_HAMMING(); + virtual ~MatcherBRUTEFORCE_HAMMING(void); + + // Factory method + static MatcherBasePtr create(const std::string& _unique_name, const ParamsBasePtr _params); + + private: + + void defineMatcher(const ParamsBasePtr _params); +}; + +/* + * brief Define detector + */ +inline void MatcherBRUTEFORCE_HAMMING::defineMatcher(const ParamsBasePtr _params) +{ + params_base_ptr_ = std::static_pointer_cast<MatcherParamsBase>(_params); + MatcherParamsBRUTEFORCE_HAMMINGPtr params_ptr = std::static_pointer_cast<MatcherParamsBRUTEFORCE_HAMMING>(_params); + matcher_ = cv::DescriptorMatcher::create("BruteForce-Hamming"); +} + +/* + * brief Create object in factory + */ +inline MatcherBasePtr MatcherBRUTEFORCE_HAMMING::create(const std::string& _unique_name, const ParamsBasePtr _params) +{ + MatcherBRUTEFORCE_HAMMINGPtr mat_ptr = std::make_shared<MatcherBRUTEFORCE_HAMMING>(); + mat_ptr->setName(_unique_name); + mat_ptr->defineMatcher(_params); + return mat_ptr; +} + +} /* namespace vision_utils */ + +#endif /* _MATCHER_BRUTEFORCE_HAMMING_H_ */ diff --git a/src/matchers/bruteforce_hamming/matcher_bruteforce_hamming_load_yaml.cpp b/src/matchers/bruteforce_hamming/matcher_bruteforce_hamming_load_yaml.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cae5c2ec08361cb52dcd18fbc799c4cd28c60dc6 --- /dev/null +++ b/src/matchers/bruteforce_hamming/matcher_bruteforce_hamming_load_yaml.cpp @@ -0,0 +1,46 @@ +#include "matcher_bruteforce_hamming.h" + +#ifdef USING_YAML + +// yaml-cpp library +#include <yaml-cpp/yaml.h> + +namespace vision_utils +{ + +namespace +{ + +static ParamsBasePtr createParamsBRUTEFORCE_HAMMINGMatcher(const std::string & _filename_dot_yaml) +{ + MatcherParamsBRUTEFORCE_HAMMINGPtr params_ptr = std::make_shared<MatcherParamsBRUTEFORCE_HAMMING>(); + + using std::string; + using YAML::Node; + Node yaml_params = YAML::LoadFile(_filename_dot_yaml); + if (!yaml_params.IsNull()) + { + Node d_yaml = yaml_params["matcher"]; + if(d_yaml["type"].as<string>() == "BRUTEFORCE_HAMMING") + { + params_ptr->match_type = d_yaml["match type"].as<int>(); + // TODO: Add possible parameters + }else + { + std::cerr << "Bad configuration file. Wrong type " << d_yaml["type"].as<string>() << std::endl; + return nullptr; + } + } + + return params_ptr; +} + +// Register in the SensorFactory +const bool registered_matBRUTEFORCE_HAMMING_params = ParamsFactory::get().registerCreator("BRUTEFORCE_HAMMING MAT", createParamsBRUTEFORCE_HAMMINGMatcher); + +} /* namespace [unnamed] */ + +} /* namespace vision_utils */ + +#endif /* IF USING_YAML */ + diff --git a/src/matchers/bruteforce_hamming_2/matcher_bruteforce_hamming_2.cpp b/src/matchers/bruteforce_hamming_2/matcher_bruteforce_hamming_2.cpp new file mode 100644 index 0000000000000000000000000000000000000000..493f7dcfdb9fbd54930812f3b120e3739dd3f09d --- /dev/null +++ b/src/matchers/bruteforce_hamming_2/matcher_bruteforce_hamming_2.cpp @@ -0,0 +1,17 @@ +#include "matcher_bruteforce_hamming_2.h" + +namespace vision_utils { + +MatcherBRUTEFORCE_HAMMING_2::MatcherBRUTEFORCE_HAMMING_2(void) +{} + +MatcherBRUTEFORCE_HAMMING_2::~MatcherBRUTEFORCE_HAMMING_2(void) +{} + +} /* namespace vision_utils */ + +// Register in the MatchersFactory +namespace vision_utils +{ +VU_REGISTER_MATCHER("BRUTEFORCE_HAMMING_2", MatcherBRUTEFORCE_HAMMING_2); +} /* namespace vision_utils */ diff --git a/src/matchers/bruteforce_hamming_2/matcher_bruteforce_hamming_2.h b/src/matchers/bruteforce_hamming_2/matcher_bruteforce_hamming_2.h new file mode 100644 index 0000000000000000000000000000000000000000..acec6949a938d0b743c551a6150326fcd88bb7c3 --- /dev/null +++ b/src/matchers/bruteforce_hamming_2/matcher_bruteforce_hamming_2.h @@ -0,0 +1,66 @@ +#ifndef _MATCHER_BRUTEFORCE_HAMMING_2_H_ +#define _MATCHER_BRUTEFORCE_HAMMING_2_H_ + +#include "../matcher_base.h" +#include "../matcher_factory.h" + +// yaml-cpp library +#ifdef USING_YAML + #include <yaml-cpp/yaml.h> +#endif + +namespace vision_utils { + +// Create all pointers +VU_PTR_TYPEDEFS(MatcherBRUTEFORCE_HAMMING_2); +VU_PTR_TYPEDEFS(MatcherParamsBRUTEFORCE_HAMMING_2); + +/** \brief Class parameters + * + */ +struct MatcherParamsBRUTEFORCE_HAMMING_2: public MatcherParamsBase +{ + // TODO: Add possible parameters +}; + +/** \brief DETECTOR class + * + */ +class MatcherBRUTEFORCE_HAMMING_2 : public MatcherBase { + + public: + MatcherBRUTEFORCE_HAMMING_2(); + virtual ~MatcherBRUTEFORCE_HAMMING_2(void); + + // Factory method + static MatcherBasePtr create(const std::string& _unique_name, const ParamsBasePtr _params); + + private: + + void defineMatcher(const ParamsBasePtr _params); +}; + +/* + * brief Define detector + */ +inline void MatcherBRUTEFORCE_HAMMING_2::defineMatcher(const ParamsBasePtr _params) +{ + params_base_ptr_ = std::static_pointer_cast<MatcherParamsBase>(_params); + MatcherParamsBRUTEFORCE_HAMMING_2Ptr params_ptr = std::static_pointer_cast<MatcherParamsBRUTEFORCE_HAMMING_2>(_params); + matcher_ = cv::DescriptorMatcher::create("BruteForce-Hamming(2)"); +} + +/* + * brief Create object in factory + */ +inline MatcherBasePtr MatcherBRUTEFORCE_HAMMING_2::create(const std::string& _unique_name, const ParamsBasePtr _params) +{ + MatcherBRUTEFORCE_HAMMING_2Ptr mat_ptr = std::make_shared<MatcherBRUTEFORCE_HAMMING_2>(); + mat_ptr->setName(_unique_name); + mat_ptr->defineMatcher(_params); + return mat_ptr; +} + +} /* namespace vision_utils */ + +#endif /* _MATCHER_BRUTEFORCE_HAMMING_2_H_ */ diff --git a/src/matchers/bruteforce_hamming_2/matcher_bruteforce_hamming_2_load_yaml.cpp b/src/matchers/bruteforce_hamming_2/matcher_bruteforce_hamming_2_load_yaml.cpp new file mode 100644 index 0000000000000000000000000000000000000000..41fd170f08bb4bc59d68f945d3e9629f20cdff0c --- /dev/null +++ b/src/matchers/bruteforce_hamming_2/matcher_bruteforce_hamming_2_load_yaml.cpp @@ -0,0 +1,46 @@ +#include "matcher_bruteforce_hamming_2.h" + +#ifdef USING_YAML + +// yaml-cpp library +#include <yaml-cpp/yaml.h> + +namespace vision_utils +{ + +namespace +{ + +static ParamsBasePtr createParamsBRUTEFORCE_HAMMING_2Matcher(const std::string & _filename_dot_yaml) +{ + MatcherParamsBRUTEFORCE_HAMMING_2Ptr params_ptr = std::make_shared<MatcherParamsBRUTEFORCE_HAMMING_2>(); + + using std::string; + using YAML::Node; + Node yaml_params = YAML::LoadFile(_filename_dot_yaml); + if (!yaml_params.IsNull()) + { + Node d_yaml = yaml_params["matcher"]; + if(d_yaml["type"].as<string>() == "BRUTEFORCE_HAMMING_2") + { + params_ptr->match_type = d_yaml["match type"].as<int>(); + // TODO: Add possible parameters + }else + { + std::cerr << "Bad configuration file. Wrong type " << d_yaml["type"].as<string>() << std::endl; + return nullptr; + } + } + + return params_ptr; +} + +// Register in the SensorFactory +const bool registered_matBRUTEFORCE_HAMMING_2_params = ParamsFactory::get().registerCreator("BRUTEFORCE_HAMMING_2 MAT", createParamsBRUTEFORCE_HAMMING_2Matcher); + +} /* namespace [unnamed] */ + +} /* namespace vision_utils */ + +#endif /* IF USING_YAML */ + diff --git a/src/matchers/bruteforce_l1/matcher_bruteforce_l1.cpp b/src/matchers/bruteforce_l1/matcher_bruteforce_l1.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0aab20a626919c9d844e17ce434d14ae65a49a87 --- /dev/null +++ b/src/matchers/bruteforce_l1/matcher_bruteforce_l1.cpp @@ -0,0 +1,17 @@ +#include "matcher_bruteforce_l1.h" + +namespace vision_utils { + +MatcherBRUTEFORCE_L1::MatcherBRUTEFORCE_L1(void) +{} + +MatcherBRUTEFORCE_L1::~MatcherBRUTEFORCE_L1(void) +{} + +} /* namespace vision_utils */ + +// Register in the MatchersFactory +namespace vision_utils +{ +VU_REGISTER_MATCHER("BRUTEFORCE_L1", MatcherBRUTEFORCE_L1); +} /* namespace vision_utils */ diff --git a/src/matchers/bruteforce_l1/matcher_bruteforce_l1.h b/src/matchers/bruteforce_l1/matcher_bruteforce_l1.h new file mode 100644 index 0000000000000000000000000000000000000000..22c6cccf12f9fee5685b134997dc9d6ef7113b68 --- /dev/null +++ b/src/matchers/bruteforce_l1/matcher_bruteforce_l1.h @@ -0,0 +1,66 @@ +#ifndef _MATCHER_BRUTEFORCE_L1_H_ +#define _MATCHER_BRUTEFORCE_L1_H_ + +#include "../matcher_base.h" +#include "../matcher_factory.h" + +// yaml-cpp library +#ifdef USING_YAML + #include <yaml-cpp/yaml.h> +#endif + +namespace vision_utils { + +// Create all pointers +VU_PTR_TYPEDEFS(MatcherBRUTEFORCE_L1); +VU_PTR_TYPEDEFS(MatcherParamsBRUTEFORCE_L1); + +/** \brief Class parameters + * + */ +struct MatcherParamsBRUTEFORCE_L1: public MatcherParamsBase +{ + // TODO: Add possible parameters +}; + +/** \brief DETECTOR class + * + */ +class MatcherBRUTEFORCE_L1 : public MatcherBase { + + public: + MatcherBRUTEFORCE_L1(); + virtual ~MatcherBRUTEFORCE_L1(void); + + // Factory method + static MatcherBasePtr create(const std::string& _unique_name, const ParamsBasePtr _params); + + private: + + void defineMatcher(const ParamsBasePtr _params); +}; + +/* + * brief Define detector + */ +inline void MatcherBRUTEFORCE_L1::defineMatcher(const ParamsBasePtr _params) +{ + params_base_ptr_ = std::static_pointer_cast<MatcherParamsBase>(_params); + MatcherParamsBRUTEFORCE_L1Ptr params_ptr = std::static_pointer_cast<MatcherParamsBRUTEFORCE_L1>(_params); + matcher_ = cv::DescriptorMatcher::create("BruteForce-L1"); +} + +/* + * brief Create object in factory + */ +inline MatcherBasePtr MatcherBRUTEFORCE_L1::create(const std::string& _unique_name, const ParamsBasePtr _params) +{ + MatcherBRUTEFORCE_L1Ptr mat_ptr = std::make_shared<MatcherBRUTEFORCE_L1>(); + mat_ptr->setName(_unique_name); + mat_ptr->defineMatcher(_params); + return mat_ptr; +} + +} /* namespace vision_utils */ + +#endif /* _MATCHER_BRUTEFORCE_L1_H_ */ diff --git a/src/matchers/bruteforce_l1/matcher_bruteforce_l1_load_yaml.cpp b/src/matchers/bruteforce_l1/matcher_bruteforce_l1_load_yaml.cpp new file mode 100644 index 0000000000000000000000000000000000000000..128ddc54ebb2d4b0e527a9b8c93b78e87d49b136 --- /dev/null +++ b/src/matchers/bruteforce_l1/matcher_bruteforce_l1_load_yaml.cpp @@ -0,0 +1,46 @@ +#include "matcher_bruteforce_l1.h" + +#ifdef USING_YAML + +// yaml-cpp library +#include <yaml-cpp/yaml.h> + +namespace vision_utils +{ + +namespace +{ + +static ParamsBasePtr createParamsBRUTEFORCE_L1Matcher(const std::string & _filename_dot_yaml) +{ + MatcherParamsBRUTEFORCE_L1Ptr params_ptr = std::make_shared<MatcherParamsBRUTEFORCE_L1>(); + + using std::string; + using YAML::Node; + Node yaml_params = YAML::LoadFile(_filename_dot_yaml); + if (!yaml_params.IsNull()) + { + Node d_yaml = yaml_params["matcher"]; + if(d_yaml["type"].as<string>() == "BRUTEFORCE_L1") + { + params_ptr->match_type = d_yaml["match type"].as<int>(); + // TODO: Add possible parameters + }else + { + std::cerr << "Bad configuration file. Wrong type " << d_yaml["type"].as<string>() << std::endl; + return nullptr; + } + } + + return params_ptr; +} + +// Register in the SensorFactory +const bool registered_matBRUTEFORCE_L1_params = ParamsFactory::get().registerCreator("BRUTEFORCE_L1 MAT", createParamsBRUTEFORCE_L1Matcher); + +} /* namespace [unnamed] */ + +} /* namespace vision_utils */ + +#endif /* IF USING_YAML */ + diff --git a/src/matchers/flannbased/matcher_flannbased.cpp b/src/matchers/flannbased/matcher_flannbased.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2286433e8039bfc8d2a6ea718759712aca78292b --- /dev/null +++ b/src/matchers/flannbased/matcher_flannbased.cpp @@ -0,0 +1,17 @@ +#include "matcher_flannbased.h" + +namespace vision_utils { + +MatcherFLANNBASED::MatcherFLANNBASED(void) +{} + +MatcherFLANNBASED::~MatcherFLANNBASED(void) +{} + +} /* namespace vision_utils */ + +// Register in the MatchersFactory +namespace vision_utils +{ +VU_REGISTER_MATCHER("FLANNBASED", MatcherFLANNBASED); +} /* namespace vision_utils */ diff --git a/src/matchers/flannbased/matcher_flannbased.h b/src/matchers/flannbased/matcher_flannbased.h new file mode 100644 index 0000000000000000000000000000000000000000..8638a40d217a04912f9f6408b2978b2fbd8fdd8b --- /dev/null +++ b/src/matchers/flannbased/matcher_flannbased.h @@ -0,0 +1,66 @@ +#ifndef _MATCHER_FLANNBASED_H_ +#define _MATCHER_FLANNBASED_H_ + +#include "../matcher_base.h" +#include "../matcher_factory.h" + +// yaml-cpp library +#ifdef USING_YAML + #include <yaml-cpp/yaml.h> +#endif + +namespace vision_utils { + +// Create all pointers +VU_PTR_TYPEDEFS(MatcherFLANNBASED); +VU_PTR_TYPEDEFS(MatcherParamsFLANNBASED); + +/** \brief Class parameters + * + */ +struct MatcherParamsFLANNBASED: public MatcherParamsBase +{ + // TODO: Add possible parameters +}; + +/** \brief DETECTOR class + * + */ +class MatcherFLANNBASED : public MatcherBase { + + public: + MatcherFLANNBASED(); + virtual ~MatcherFLANNBASED(void); + + // Factory method + static MatcherBasePtr create(const std::string& _unique_name, const ParamsBasePtr _params); + + private: + + void defineMatcher(const ParamsBasePtr _params); +}; + +/* + * brief Define detector + */ +inline void MatcherFLANNBASED::defineMatcher(const ParamsBasePtr _params) +{ + params_base_ptr_ = std::static_pointer_cast<MatcherParamsBase>(_params); + MatcherParamsFLANNBASEDPtr params_ptr = std::static_pointer_cast<MatcherParamsFLANNBASED>(_params); + matcher_ = cv::DescriptorMatcher::create("FlannBased"); +} + +/* + * brief Create object in factory + */ +inline MatcherBasePtr MatcherFLANNBASED::create(const std::string& _unique_name, const ParamsBasePtr _params) +{ + MatcherFLANNBASEDPtr mat_ptr = std::make_shared<MatcherFLANNBASED>(); + mat_ptr->setName(_unique_name); + mat_ptr->defineMatcher(_params); + return mat_ptr; +} + +} /* namespace vision_utils */ + +#endif /* _MATCHER_FLANNBASED_H_ */ diff --git a/src/matchers/flannbased/matcher_flannbased_load_yaml.cpp b/src/matchers/flannbased/matcher_flannbased_load_yaml.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a9f334deb89d1bedebefa1da6bb0ac73682c7940 --- /dev/null +++ b/src/matchers/flannbased/matcher_flannbased_load_yaml.cpp @@ -0,0 +1,46 @@ +#include "matcher_flannbased.h" + +#ifdef USING_YAML + +// yaml-cpp library +#include <yaml-cpp/yaml.h> + +namespace vision_utils +{ + +namespace +{ + +static ParamsBasePtr createParamsFLANNBASEDMatcher(const std::string & _filename_dot_yaml) +{ + MatcherParamsFLANNBASEDPtr params_ptr = std::make_shared<MatcherParamsFLANNBASED>(); + + using std::string; + using YAML::Node; + Node yaml_params = YAML::LoadFile(_filename_dot_yaml); + if (!yaml_params.IsNull()) + { + Node d_yaml = yaml_params["matcher"]; + if(d_yaml["type"].as<string>() == "FLANNBASED") + { + params_ptr->match_type = d_yaml["match type"].as<int>(); + // TODO: Add possible parameters + }else + { + std::cerr << "Bad configuration file. Wrong type " << d_yaml["type"].as<string>() << std::endl; + return nullptr; + } + } + + return params_ptr; +} + +// Register in the SensorFactory +const bool registered_matFLANNBASED_params = ParamsFactory::get().registerCreator("FLANNBASED MAT", createParamsFLANNBASEDMatcher); + +} /* namespace [unnamed] */ + +} /* namespace vision_utils */ + +#endif /* IF USING_YAML */ + diff --git a/src/matchers/matcher_base.cpp b/src/matchers/matcher_base.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6e0ca67edb34704bd58ee6116f04cdba99ddeffa --- /dev/null +++ b/src/matchers/matcher_base.cpp @@ -0,0 +1,157 @@ +#include "matcher_base.h" + +namespace vision_utils { + +MatcherBase::MatcherBase(void) +{ +} + +MatcherBase::~MatcherBase(void) +{ +} + +void MatcherBase::match(const cv::Mat& _desc1, const cv::Mat& _desc2, std::vector<cv::DMatch>& matches, cv::InputArray _mask) +{ + if (params_base_ptr_->match_type==MATCH) + { + clock_t tStart = clock(); + if (!_desc1.empty() && !_desc2.empty()) + { + // The following line is needed because flann by default is built with . + // This conversion is required when using with hamming descriptors outputs + // like BRIEF, ORB, FREAK, AKAZE etc + if (_desc1.type()!=CV_32F) + { + matcher_ = new cv::FlannBasedMatcher(new cv::flann::LshIndexParams(LSH_TABLE_NUM, LSH_KEY_SIZE, LSH_MULTI_PROBE_LEVEL)); + } + + matcher_->match( _desc1, _desc2, matches, _mask); + } + comp_time_ = (double)(clock() - tStart) / CLOCKS_PER_SEC; + } + else + std::cerr << "[" << name_ << "]:Wrong match type or output object." << std::endl; +} + +void MatcherBase::match(const cv::Mat& _desc1, const cv::Mat& _desc2, std::vector< std::vector<cv::DMatch> >& matches, cv::InputArray _mask) +{ + if (params_base_ptr_->match_type == KNNMATCH)// knn match + { + clock_t tStart = clock(); + if (!_desc1.empty() && !_desc2.empty()) + { + // The following line is needed because flann by default is built with . + // This conversion is required when using with hamming descriptors outputs + // like BRIEF, ORB, FREAK, AKAZE etc + if (_desc1.type()!=CV_32F) + matcher_ = new cv::FlannBasedMatcher(new cv::flann::LshIndexParams(LSH_TABLE_NUM, LSH_KEY_SIZE, LSH_MULTI_PROBE_LEVEL)); + matcher_->knnMatch(_desc1, _desc2, matches, 2); + } + comp_time_ = (double)(clock() - tStart) / CLOCKS_PER_SEC; + } + else if (params_base_ptr_->match_type == RADIUSMATCH) // radius match + { + clock_t tStart = clock(); + if (!_desc1.empty() && !_desc2.empty()) + { + // The following line is needed because flann by default is built with . + // This conversion is required when using with hamming descriptors outputs + // like BRIEF, ORB, FREAK, AKAZE etc + if (_desc1.type()!=CV_32F) + matcher_ = new cv::FlannBasedMatcher(new cv::flann::LshIndexParams(LSH_TABLE_NUM, LSH_KEY_SIZE, LSH_MULTI_PROBE_LEVEL)); + matcher_->radiusMatch(_desc1, _desc2, matches, 2, _mask); + } + comp_time_ = (double)(clock() - tStart) / CLOCKS_PER_SEC; + } + else + std::cerr << "[" << name_ << "]:Wrong match type or output object." << std::endl; +} + +void MatcherBase::filterByDistance(const int& _max_pixel_dist, const float& _img_size_percentage, const KeyPointVector& _kpts1,const KeyPointVector& _kpts2, const std::vector< std::vector<cv::DMatch> >& _dirty, const int& _img_width, const int& _img_height, std::vector<cv::DMatch>& _filtered_matches, KeyPointVector& _filtered_kpts, KeyPointVector& _filtered_kpts_prev) +{ + if (params_base_ptr_->match_type == KNNMATCH || params_base_ptr_->match_type == RADIUSMATCH) + { + double tresholdDist = _img_size_percentage * sqrt(double(_img_height*_img_height + _img_width*_img_width)); + + std::vector< cv::DMatch > good_matches2; + _filtered_matches.reserve(_dirty.size()); + for (size_t ii = 0; ii < _dirty.size(); ++ii) + { + for (unsigned int jj = 0; jj < _dirty[ii].size(); jj++) + { + cv::Point2f from = _kpts1[_dirty[ii][jj].queryIdx].pt; + cv::Point2f to = _kpts2[_dirty[ii][jj].trainIdx].pt; + + //calculate local distance for each possible match + double dist = std::sqrt((from.x - to.x) * (from.x - to.x) + (from.y - to.y) * (from.y - to.y)); + + //save as best match if local distance is in specified area and on same height + if (dist < tresholdDist && std::abs(from.y-to.y)<_max_pixel_dist && std::abs(from.x-to.x)<_max_pixel_dist) + { + _filtered_matches.push_back(_dirty[ii][jj]); + cv::KeyPoint kpt = cv::KeyPoint(to,1); + cv::KeyPoint kpt_prev = cv::KeyPoint(from,1); + _filtered_kpts.push_back(kpt); + _filtered_kpts_prev.push_back(kpt_prev); + jj = _dirty[ii].size(); + } + } + } + } + else + std::cerr << "[" << name_ << "]: Wrong input type in filterByDistance method." << std::endl; +} + +void MatcherBase::filterByDistance(const int& _max_pixel_dist, const float& _img_size_percentage, const KeyPointVector& _kpts1,const KeyPointVector& _kpts2, const std::vector<cv::DMatch>& _dirty, const int& _img_width, const int& _img_height, std::vector<cv::DMatch>& _filtered_matches, KeyPointVector& _filtered_kpts, KeyPointVector& _filtered_kpts_prev) +{ + if (params_base_ptr_->match_type == MATCH) + { + double tresholdDist = _img_size_percentage * sqrt(double(_img_height*_img_height + _img_width*_img_width)); + + std::vector< cv::DMatch > good_matches2; + _filtered_matches.reserve(_dirty.size()); + for (size_t ii = 0; ii < _dirty.size(); ++ii) + { + cv::Point2f from = _kpts1[_dirty[ii].queryIdx].pt; + cv::Point2f to = _kpts2[_dirty[ii].trainIdx].pt; + + //calculate local distance for each possible match + double dist = std::sqrt((from.x - to.x) * (from.x - to.x) + (from.y - to.y) * (from.y - to.y)); + + //save as best match if local distance is in specified area + if (dist < tresholdDist && std::abs(from.y-to.y)<_max_pixel_dist && std::abs(from.x-to.x)<_max_pixel_dist) + { + _filtered_matches.push_back(_dirty[ii]); + cv::KeyPoint kpt = cv::KeyPoint(to,1); + cv::KeyPoint kpt_prev = cv::KeyPoint(from,1); + _filtered_kpts.push_back(kpt); + _filtered_kpts_prev.push_back(kpt_prev); + } + } + } + else + std::cerr << "[" << name_ << "]: Wrong input type in filterByDistance method." << std::endl; +} + +} /* namespace vision_utils */ + +#include "matcher_factory.h" + +namespace vision_utils +{ + +MatcherBasePtr setupMatcher(const std::string& _type, const std::string& _unique_name, const ParamsBasePtr& _params) +{ + MatcherBasePtr mat_ptr = MatcherFactory::get().create(_type, _unique_name, _params); + return mat_ptr; +}; + +#ifdef USING_YAML +MatcherBasePtr setupMatcher(const std::string& _type, const std::string& _unique_name, const std::string& _filename_dot_yaml) +{ + ParamsBasePtr params_ptr = ParamsFactory::get().create(_type+" MAT", _filename_dot_yaml); + return setupMatcher(_type, _unique_name, params_ptr); +} +#endif + +} /* namespace vision_utils */ diff --git a/src/matchers/matcher_base.h b/src/matchers/matcher_base.h new file mode 100644 index 0000000000000000000000000000000000000000..12c50e6622c2a2f8d5176f32621d2d5a1b15d8c3 --- /dev/null +++ b/src/matchers/matcher_base.h @@ -0,0 +1,110 @@ +#ifndef _MATCHER_BASE_H_ +#define _MATCHER_BASE_H_ + +// vision_utils +#include "../vision_utils.h" + +typedef cv::Ptr<cv::DescriptorMatcher> FeatureMatcherPtr; + +// The following definitions are required because flann by default is built with . +// This conversion is required when using with hamming descriptors outputs +// like BRIEF, ORB, FREAK, AKAZE etc +#define LSH_TABLE_NUM 20 // The number of hash tables to use (between 10 and 30 usually). +#define LSH_KEY_SIZE 15 // The size of the hash key in bits (between 10 and 20 usually) +#define LSH_MULTI_PROBE_LEVEL 2 // The number of bits to shift to check for neighboring buckets (0 is regular LSH, 2 is recommended) + +namespace vision_utils +{ + +///////////////////////////////////////////////////////////////////////// +// CLASS DEFINITIONS +///////////////////////////////////////////////////////////////////////// + +// Create all pointers +VU_PTR_TYPEDEFS(MatcherBase); +VU_PTR_TYPEDEFS(MatcherParamsBase); + +enum MATCH_TYPE{ + MATCH = 1, + KNNMATCH = 2, + RADIUSMATCH = 3 +}; + +/** \brief Class parameters + * + */ +struct MatcherParamsBase: public ParamsBase +{ + int match_type = MATCH; // Type of Match. MATCH = 1, KNNMATCH = 2, RADIUSMATCH = 3 +}; + +/** \brief base class for Matcher base + * + * Derive from this class to create Matcher base class parameters. + */ +class MatcherBase : public VUBase, public std::enable_shared_from_this<MatcherBase> +{ + public: + + /** + * \brief Constructor without parameters + */ + MatcherBase(void); + + /** + * \brief Virtual destructor + */ + virtual ~MatcherBase(void); + + void match(const cv::Mat& _desc1, const cv::Mat& _desc2, std::vector<cv::DMatch>& matches, cv::InputArray _mask=cv::noArray()); + void match(const cv::Mat& _desc1, const cv::Mat& _desc2, std::vector< std::vector<cv::DMatch> >& matches, cv::InputArray _mask=cv::noArray()); + + std::string getName(void); + + MatcherParamsBasePtr getParams(void); + + void filterByDistance(const int& _max_pixel_dist, const float& _percentage, const KeyPointVector& _kpts1,const KeyPointVector& _kpts2, const std::vector<cv::DMatch>& _dirty, const int& _img_width, const int& _img_height, std::vector<cv::DMatch>& _filtered_matches, KeyPointVector& _filtered_kpts, KeyPointVector& _filtered_kpts_prev); + void filterByDistance(const int& _max_pixel_dist, const float& _percentage, const KeyPointVector& _kpts1,const KeyPointVector& _kpts2, const std::vector< std::vector<cv::DMatch> >& _dirty, const int& _img_width, const int& _img_height, std::vector<cv::DMatch>& _filtered_matches, KeyPointVector& _filtered_kpts, KeyPointVector& _filtered_kpts_prev); + + // Factory method + static MatcherBasePtr create(const std::string& _unique_name, const ParamsBasePtr _params); + + protected: + + std::string name_; + + FeatureMatcherPtr matcher_; + + MatcherParamsBasePtr params_base_ptr_; + + void setName(const std::string& _name); + + virtual void defineMatcher(const ParamsBasePtr _params) = 0; +}; + +/* + * brief Retrieve object name + */ +inline std::string MatcherBase::getName(void) { return name_; } + +/* + * brief Set object name + */ +inline void MatcherBase::setName(const std::string& _name){ name_ = _name; } + +/* + * brief Retrieve object parameters + */ +inline MatcherParamsBasePtr MatcherBase::getParams(void) { return params_base_ptr_; } + +/* + * brief Setup and get the corresponding pointer + */ +MatcherBasePtr setupMatcher(const std::string& _type, const std::string& _unique_name, const ParamsBasePtr& _params); +#ifdef USING_YAML +MatcherBasePtr setupMatcher(const std::string& _type, const std::string& _unique_name, const std::string& _filename_dot_yaml); +#endif + +} /* namespace vision_utils */ + +#endif /* _MATCHER_BASE_H_ */ diff --git a/src/matchers/matcher_factory.h b/src/matchers/matcher_factory.h new file mode 100644 index 0000000000000000000000000000000000000000..b1f75692c6bf9c07d73469468297dea1aa415289 --- /dev/null +++ b/src/matchers/matcher_factory.h @@ -0,0 +1,32 @@ +#ifndef _MATCHER_FACTORY_H_ +#define _MATCHER_FACTORY_H_ + +namespace vision_utils +{ +class MatcherBase; +struct MatcherParamsBase; +} + +#include "../factory.h" + +namespace vision_utils +{ + +/* Matcher Factory */ +typedef Factory<MatcherBase, + const std::string&, + const ParamsBasePtr> MatcherFactory; + +template<> +inline std::string MatcherFactory::getClass() +{ + return "MatcherFactory"; +} + +#define VU_REGISTER_MATCHER(MatcherType, MatcherName) \ + namespace{ const bool MatcherName##Registered = \ + MatcherFactory::get().registerCreator(MatcherType, MatcherName::create, true); }\ + +} /* namespace vision_utils */ + +#endif /* _MATCHER_FACTORY_H_ */ diff --git a/src/sensors/sensor_base.cpp b/src/sensors/sensor_base.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8e698583743849cb8e4c25023afcbca62b4389f9 --- /dev/null +++ b/src/sensors/sensor_base.cpp @@ -0,0 +1,34 @@ +#include "sensor_base.h" + +namespace vision_utils { + +SensorBase::SensorBase(void) +{ +} + +SensorBase::~SensorBase(void) +{ +} + +} // namespace vision_utils + +#include "sensor_factory.h" + +namespace vision_utils +{ + +SensorBasePtr setupSensor(const std::string& _type, const std::string& _unique_name, const ParamsBasePtr& _params) +{ + SensorBasePtr sen_ptr = SensorFactory::get().create(_type, _unique_name, _params); + return sen_ptr; +}; + +#ifdef USING_YAML +SensorBasePtr setupSensor(const std::string& _type, const std::string& _unique_name, const std::string& _filename_dot_yaml) +{ + ParamsBasePtr params_ptr = ParamsFactory::get().create(_type, _filename_dot_yaml); + return setupSensor(_type, _unique_name, params_ptr); +} +#endif + +} /* namespace vision_utils */ diff --git a/src/sensors/sensor_base.h b/src/sensors/sensor_base.h new file mode 100644 index 0000000000000000000000000000000000000000..9021410dd7e42a7de5dfdac9b22561fed6db6100 --- /dev/null +++ b/src/sensors/sensor_base.h @@ -0,0 +1,64 @@ +#ifndef _SENSOR_BASE_H_ +#define _SENSOR_BASE_H_ + +// vision_utils +#include "../vision_utils.h" + +namespace vision_utils +{ + +///////////////////////////////////////////////////////////////////////// +// CLASS DEFINITIONS +///////////////////////////////////////////////////////////////////////// + +// Create all pointers +VU_PTR_TYPEDEFS(SensorBase); + +/** \brief base class for DETECTOR base + * + * Derive from this class to create DETECTOR base class parameters. + */ +class SensorBase : public VUBase, public std::enable_shared_from_this<SensorBase> +{ + public: + + /** + * \brief Constructor without parameters + */ + SensorBase(void); + + /** + * \brief Virtual destructor + */ + virtual ~SensorBase(void); + + std::string getName(void); + + protected: + + std::string name_; + + void setName(const std::string& _name); +}; + +/* + * brief Retrieve object name + */ +inline std::string SensorBase::getName(void) { return name_; } + +/* + * brief Set object name + */ +inline void SensorBase::setName(const std::string& _name){ name_ = _name; } + +/* + * brief Setup and get the corresponding pointer + */ +SensorBasePtr setupSensor(const std::string& _type, const std::string& _unique_name, const ParamsBasePtr& _intrinsics); +#ifdef USING_YAML +SensorBasePtr setupSensor(const std::string& _type, const std::string& _unique_name, const std::string& _filename_dot_yaml); +#endif + +} /* namespace vision_utils */ + +#endif /* _SENSOR_BASE_H_ */ diff --git a/src/sensors/sensor_factory.h b/src/sensors/sensor_factory.h new file mode 100644 index 0000000000000000000000000000000000000000..d3567245734b3814276ca3b295d3de498d9d43bf --- /dev/null +++ b/src/sensors/sensor_factory.h @@ -0,0 +1,32 @@ +#ifndef _SENSOR_FACTORY_H_ +#define _SENSOR_FACTORY_H_ + +namespace vision_utils +{ +class SensorBase; +struct SensorParamsBase; +} + +#include "../factory.h" + +namespace vision_utils +{ + +/* Sensor Factory */ +typedef Factory<SensorBase, + const std::string&, + const ParamsBasePtr> SensorFactory; + +template<> +inline std::string SensorFactory::getClass() +{ + return "SensorFactory"; +} + +#define VU_REGISTER_SENSOR(SensorType, SensorName) \ + namespace{ const bool SensorName##Registered = \ + SensorFactory::get().registerCreator(SensorType, SensorName::create, true); }\ + +} /* namespace vision_utils */ + +#endif /* SENSOR_FACTORY_H_ */ diff --git a/src/sensors/usb_cam/usb_cam.cpp b/src/sensors/usb_cam/usb_cam.cpp new file mode 100644 index 0000000000000000000000000000000000000000..235023fcfb202ca717d3ff30fc796e87a62f9a85 --- /dev/null +++ b/src/sensors/usb_cam/usb_cam.cpp @@ -0,0 +1,18 @@ +#include "usb_cam.h" + +namespace vision_utils { + +SensorCamera::SensorCamera(void) +{} + +SensorCamera::~SensorCamera(void) +{} + +} /* namespace vision_utils */ + +// Register in the DetectorsFactory +#include "../sensor_factory.h" +namespace vision_utils +{ +VU_REGISTER_SENSOR("USB_CAM", SensorCamera); +} /* namespace vision_utils */ diff --git a/src/sensors/usb_cam/usb_cam.h b/src/sensors/usb_cam/usb_cam.h new file mode 100644 index 0000000000000000000000000000000000000000..2727a252f400af6c4ed1c56aa5df757da0e44690 --- /dev/null +++ b/src/sensors/usb_cam/usb_cam.h @@ -0,0 +1,136 @@ +#ifndef _USB_CAM_H_ +#define _USB_CAM_H_ + +#include "../sensor_base.h" + +// yaml-cpp library +#ifdef USING_YAML + #include <yaml-cpp/yaml.h> +#endif + +namespace vision_utils { + +// Create all pointers +VU_PTR_TYPEDEFS(SensorCamera); +VU_PTR_TYPEDEFS(IntrinsicsCamera); + +/** \brief class parameters + * + */ +struct IntrinsicsCamera: public ParamsBase +{ + // TODO: Define camera intrinsic parameters +}; + +/** \brief ORB DETECTOR class + * + */ +class SensorCamera : public SensorBase { + + public: + + SensorCamera(); + virtual ~SensorCamera(void); + + /** + * \brief Open Webcam + * + * This method opens the specified webcam using OpenCV + * Inputs: + * _cam_num: system camera number (int) + * _ cam: camera handle (cv::VideoCapture) + * Returns true if the camera is correctly opened + * + */ + bool open(const int& _cam_num); + + /** + * \brief Get frame + * + * This method gets a frame from the specified webcam + * Inputs: + * _cam: camera handle (cv::VideoCapture) + * _frame: filled frame (cv::Mat) + * Returns true if the frame is correctly obtained + */ + bool getFrame(cv::Mat& _frame); + + /** + *\brief Show Frame + * + * This method shows the specified frame using OpenCV + * Inputs: + * _window_name: Window name inwhich the frame will be displayed (string) + * _frame: Frame to be displayed (cv::Mat) + * Returns true if the frame is correctly displayed + */ + bool showFrame(const std::string& _window_name, const cv::Mat& _frame); + + // Factory method + static SensorBasePtr create(const std::string& _unique_name, const ParamsBasePtr _intrinsics); + + private: + + cv::VideoCapture vidcapture_; + + void setParams(const ParamsBasePtr _params); +}; + +/* + * brief Set object name + */ +inline void SensorCamera::setParams(const ParamsBasePtr _params) +{ + IntrinsicsCameraPtr intrinsics_ptr = std::static_pointer_cast<IntrinsicsCamera>(_params); + // TODO: depending on intrinsics structure +} + +inline bool SensorCamera::open(const int& _cam_num) +{ + cv::VideoCapture camera(_cam_num); + if (!camera.isOpened()) // check if we succeeded + { + std::cerr << "[" << getName() << "]: ERROR opening camera " << _cam_num << std::endl; + return false; + } + vidcapture_ = camera; + return true; +} + +inline bool SensorCamera::getFrame(cv::Mat& _frame) +{ + try { vidcapture_ >> _frame; } + catch (cv::Exception& e) + { + std::cout << "[" << getName() << "]: An exception occurred. Ignoring frame. " << e.err << std::endl; + return false; + } + return true; +} + +inline bool SensorCamera::showFrame(const std::string& _window_name, const cv::Mat& _frame) +{ + try { cv::imshow(_window_name, _frame); } + catch (cv::Exception& e) + { + std::cout << "[" << getName() << "]: An exception occurred. Dropping frame. " << e.err << std::endl; + return false; + } + return true; +} + +/* + * brief Create object in factory + */ +inline SensorBasePtr SensorCamera::create(const std::string& _unique_name, const ParamsBasePtr _intrinsics) +{ + SensorCameraPtr sen_ptr = std::make_shared<SensorCamera>(); + IntrinsicsCameraPtr sen_params_ptr = std::static_pointer_cast<IntrinsicsCamera>(_intrinsics); + sen_ptr->setName(_unique_name); + sen_ptr->setParams(sen_params_ptr); + return sen_ptr; +} + +} /* namespace vision_utils */ + +#endif /* _USB_CAM_H_ */ diff --git a/src/sensors/usb_cam/usb_cam_load_yaml.cpp b/src/sensors/usb_cam/usb_cam_load_yaml.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9fa57b2e3d2e7bd50e3a51110cfaaf3572502103 --- /dev/null +++ b/src/sensors/usb_cam/usb_cam_load_yaml.cpp @@ -0,0 +1,45 @@ +#include "usb_cam.h" +#include "../../factory.h" + +#ifdef USING_YAML + +// yaml-cpp library +#include <yaml-cpp/yaml.h> + +namespace vision_utils +{ + +namespace +{ + +static ParamsBasePtr createParamsUSBCAMSensor(const std::string & _filename_dot_yaml) +{ + IntrinsicsCameraPtr params_ptr = std::make_shared<IntrinsicsCamera>(); + + using std::string; + using YAML::Node; + Node yaml_params = YAML::LoadFile(_filename_dot_yaml); + if (!yaml_params.IsNull()) + { + Node d_yaml = yaml_params["sensor"]; + if(d_yaml["type"].as<string>() == "USB_CAM") + { + // TODO: Load intrinsic parametes if any function needs them. + }else + { + std::cerr << "Bad configuration file. Wrong type " << d_yaml["type"].as<string>() << std::endl; + } + } + + return params_ptr; +} + +// Register in the SensorFactory +const bool registered_usbcam_params = ParamsFactory::get().registerCreator("USB_CAM", createParamsUSBCAMSensor); + +} /* namespace [unnamed] */ + +} /* namespace vision_utils */ + +#endif /* IF USING_YAML */ + diff --git a/src/vision_utils.cpp b/src/vision_utils.cpp index 1776b3afacf6519ebf4ead7f93c4f31384bb6460..c7622516f4a53031a53f951ab850067b6b38aade 100644 --- a/src/vision_utils.cpp +++ b/src/vision_utils.cpp @@ -1,34 +1,57 @@ #include "vision_utils.h" -CVision_Utils::CVision_Utils() { -} - -CVision_Utils::~CVision_Utils() { -} - -bool LessPoints(const cv::Point2f& lhs, const cv::Point2f& rhs) +namespace vision_utils { - return (lhs.x < rhs.x) || ((lhs.x == rhs.x) && (lhs.y < rhs.y)); -} -std::vector<cv::Point2f> vecIntersec(std::vector<cv::Point2f> v1, std::vector<cv::Point2f> v2) +void whoHasMoved(const KeyPointVector& _kpts1, const KeyPointVector& _kpts2, KeyPointVector& _common_kpts, KeyPointVector& _new_in_kpts2) { - std::vector<cv::Point2f> v3; - // Sort vectors - std::sort(v1.begin(), v1.end(), LessPoints); - std::sort(v2.begin(), v2.end(), LessPoints); - // Intersect - std::set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), std::back_inserter(v3), LessPoints); - return v3; + _new_in_kpts2.clear(); + _common_kpts.clear(); + + for (int ii = 0; ii < _kpts2.size(); ++ii) + { + bool existing = false; + for (int jj = 0; jj < _kpts1.size(); ++jj) + { + cv::Point2f p1 = _kpts2[ii].pt; + cv::Point2f p2 = _kpts1[ii].pt; + if (p1.x-p2.x < 1.0 || p1.y-p2.y < 1.0) + { + existing = true; + break; + } + } + if (!existing) // New feature + _new_in_kpts2.push_back(_kpts2[ii]); + else + _common_kpts.push_back(_kpts2[ii]); + } } -std::vector<cv::Point2f> vecUnion(std::vector<cv::Point2f> v1, std::vector<cv::Point2f> v2) +void whoHasMoved(const PointVector& _pts1, const PointVector& _pts2, PointVector& _common_pts, PointVector& _new_in_pts2) { - std::vector<cv::Point2f> v3; - // Sort vectors - std::sort(v1.begin(), v1.end(), LessPoints); - std::sort(v2.begin(), v2.end(), LessPoints); - // Intersect - std::set_union(v1.begin(), v1.end(), v2.begin(), v2.end(), std::back_inserter(v3), LessPoints); - return v3; + _new_in_pts2.clear(); + _common_pts.clear(); + + for (int ii = 0; ii < _pts2.size(); ++ii) + { + bool existing = false; + for (int jj = 0; jj < _pts1.size(); ++jj) + { + cv::Point2f p1 = _pts2[ii]; + cv::Point2f p2 = _pts1[ii]; + if (p1.x-p2.x < 1.0 || p1.y-p2.y < 1.0) + { + existing = true; + break; + } + } + if (!existing) // New feature + _new_in_pts2.push_back(_pts2[ii]); + else + _common_pts.push_back(_pts2[ii]); + } } + +} /* namespace vision_utils */ + diff --git a/src/vision_utils.h b/src/vision_utils.h index a384bbbbaf163be055aed2afe542687aa878091b..09ad728f50f5fb8b8cdbb848f210fdc3a5aaaaee 100644 --- a/src/vision_utils.h +++ b/src/vision_utils.h @@ -1,24 +1,119 @@ -#ifndef _VISION_UTILS_H -#define _VISION_UTILS_H +#ifndef _VU_UTILS_H +#define _VU_UTILS_H -#include "cam_utils/cam_utils.h" -#include "feature_detector/feature_detector.h" -#include "feature_descriptor/feature_descriptor.h" -#include "feature_matcher/feature_matcher.h" +#include "_internal/config.h" +// std #include <functional> #include <set> +#include <iostream> +#include <map> +#include <vector> +#include <string> +#include <iostream> +#include <time.h> +#include <memory> // shared_ptr and weak_ptr -class CVision_Utils { +// Boost +#include <boost/assign/std/vector.hpp> // for 'operator+=()' +using namespace boost::assign; // bring 'operator+=()' into scope + +// OpenCV +#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/features2d.hpp> +#include <opencv2/xfeatures2d/nonfree.hpp> +#include <opencv2/xfeatures2d.hpp> +#include <opencv2/line_descriptor/descriptor.hpp> + +typedef std::vector<cv::Point2f> PointVector; +typedef std::vector<cv::KeyPoint> KeyPointVector; +typedef std::vector<cv::line_descriptor::KeyLine> KeyLineVector; + +namespace vision_utils { + +///////////////////////////////////////////////////////////////////////// +// TYPEDEFS FOR POINTERS, LISTS AND ITERATORS +///////////////////////////////////////////////////////////////////////// + +#define VU_PTR_TYPEDEFS(ClassName) \ + class ClassName; \ + typedef std::shared_ptr<ClassName> ClassName##Ptr; \ + typedef std::shared_ptr<const ClassName> ClassName##ConstPtr; \ + typedef std::weak_ptr<ClassName> ClassName##WPtr; + +#define VU_LIST_TYPEDEFS(ClassName) \ + class ClassName; \ + typedef std::list<ClassName##Ptr> ClassName##List; \ + typedef ClassName##List::iterator ClassName##Iter; + +#define VU_STRUCT_PTR_TYPEDEFS(StructName) \ + struct StructName; \ + typedef std::shared_ptr<StructName> StructName##Ptr; \ + typedef std::shared_ptr<const StructName> StructName##ConstPtr; \ + +///////////////////////////////////////////////////////////////////////// +// CLASS DEFINITIONS +///////////////////////////////////////////////////////////////////////// + +/** + * \brief Class to set object parameters + * + * Derive from this class to create classes of parameters. + */ +class ParamsBase { public: - CVision_Utils(); - ~CVision_Utils(); + ParamsBase(void) { + } + ; + ~ParamsBase(void) { + } + ; + std::string type; + std::string name; }; +/** + * \brief base Class + */ +class VUBase { + +public: + + VUBase(void){}; + + virtual ~VUBase(void){}; + + /** + * \brief Get detection duration + */ + double getTime(void); + +protected: + + double comp_time_; // Detection time +}; + +inline double VUBase::getTime(void) +{ + return comp_time_; +}; + +// Create all pointers +VU_PTR_TYPEDEFS(ParamsBase); +VU_PTR_TYPEDEFS(VUBase); + +///////////////////////////////////////////////////////////////////////// +// USEFUL FUNCTIONS +///////////////////////////////////////////////////////////////////////// + template <typename T> -T readFromUser(const T& def_num) +T readFromUser(const T& _default) { - T read = def_num; + T read = _default; std::string input; std::getline( std::cin, input ); if ( !input.empty() ) @@ -28,11 +123,69 @@ T readFromUser(const T& def_num) } return read; -} +}; + +inline bool LessPoints(const cv::Point2f& lhs, const cv::Point2f& rhs) +{ + return (lhs.x < rhs.x) || ((lhs.x == rhs.x) && (lhs.y < rhs.y)); +}; + +inline bool LessKPoints(const cv::KeyPoint& lhs, const cv::KeyPoint& rhs) +{ + return (lhs.pt.x < rhs.pt.x) || ((lhs.pt.x == rhs.pt.x) && (lhs.pt.y < rhs.pt.y)); +}; + +inline std::vector<cv::Point2f> vecIntersec(std::vector<cv::Point2f> v1, std::vector<cv::Point2f> v2) +{ + std::vector<cv::Point2f> v3; + // Sort vectors + std::sort(v1.begin(), v1.end(), LessPoints); + std::sort(v2.begin(), v2.end(), LessPoints); + // Intersect + std::set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), std::back_inserter(v3), LessPoints); + return v3; +}; + +inline std::vector<cv::Point2f> vecUnion(std::vector<cv::Point2f> v1, std::vector<cv::Point2f> v2) +{ + // Sort vectors and intersect + std::vector<cv::Point2f> v3; + std::sort(v1.begin(), v1.end(), LessPoints); + std::sort(v2.begin(), v2.end(), LessPoints); + std::set_union(v1.begin(), v1.end(), v2.begin(), v2.end(), std::back_inserter(v3), LessPoints); + return v3; +}; + +inline void drawKeyPoints(cv::Mat& _image, const KeyPointVector& _kp_vec, const int& _radius=5, const cv::Scalar& _color=cv::Scalar(0, 0, 255), const int& _thickness=-1) +{ + for (unsigned int ii = 0; ii < _kp_vec.size(); ++ii) + cv::circle(_image, _kp_vec[ii].pt, _radius, _color, _thickness); +}; + +inline void drawKeyLines(cv::Mat& _image, const KeyLineVector& _kl_vec) +{ + for (unsigned int ii = 0; ii < _kl_vec.size(); ++ii) + cv::line(_image, _kl_vec[ii].getStartPoint(), _kl_vec[ii].getEndPoint(), cv::Scalar(128, 128, 255), 3); +}; + +inline void copyKPVector(const KeyPointVector& kpv_from, KeyPointVector& kpv_to) +{ + kpv_to.clear(); + for (int ii=0; ii<kpv_from.size(); ii++) + kpv_to.push_back(kpv_from[ii]); +}; + +inline PointVector KPToP(const KeyPointVector& kpts) +{ + PointVector pts; + for (unsigned int ii=0; ii<kpts.size(); ii++) + pts.push_back(kpts[ii].pt); + return pts; +}; -bool LessPoints(const cv::Point2f& lhs, const cv::Point2f& rhs); -std::vector<cv::Point2f> vecIntersec(std::vector<cv::Point2f> v1, std::vector<cv::Point2f> v2); -std::vector<cv::Point2f> vecUnion(std::vector<cv::Point2f> v1, std::vector<cv::Point2f> v2); +void whoHasMoved(const KeyPointVector& _kpts1, const KeyPointVector& _kpts2, KeyPointVector& _common_kpts, KeyPointVector& _new_in_kpts2); +void whoHasMoved(const PointVector& _pts1, const PointVector& _pts2, PointVector& _common_pts, PointVector& _new_in_pts2); +} /* namespace vision_utils */ #endif