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 &quot;${INPUTS}&quot;" 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