├── datasets └── iguazu │ ├── H1to2p │ ├── H1to3p │ ├── H1to4p │ ├── H1to5p │ ├── H1to6p │ ├── H1to1p │ ├── img1.pgm │ ├── img2.pgm │ ├── img3.pgm │ ├── img4.pgm │ ├── img5.pgm │ └── img6.pgm ├── timer ├── CMakeLists.txt ├── timer.hpp └── timer.cpp ├── cimg ├── Licence_CeCILL_V2-en.txt ├── Licence_CeCILL-C_V1-en.txt ├── cmake-modules │ ├── FindFFTW3F.cmake │ ├── FindEZMINC.cmake │ ├── FindBOARD.cmake │ ├── FindMINC.cmake │ ├── FindTIFF.cmake │ ├── FindZLIB.cmake │ ├── FindJPEG.cmake │ ├── FindPNG.cmake │ ├── FindTest.cmake │ ├── FindFFMPEG.cmake │ ├── FindFFTW3.cmake │ ├── FindOpenMP.cmake │ ├── FindOpenEXR.cmake │ ├── FindOpenCV.cmake │ ├── FindImageMagick.cmake │ ├── FindNetCDF.cmake │ └── FindLAPACK.cmake ├── CMakeLists.txt └── README.txt ├── LICENSE ├── src ├── convolution.h ├── fed.h ├── fed.cpp ├── utils.h ├── nldiffusion_functions.h ├── AKAZEConfig.h ├── convolution.cpp ├── AKAZE.h └── nldiffusion_functions.cpp ├── CMakeLists.txt ├── README.md ├── cmake ├── FindEigen.cmake ├── OptimizeCompilerFlags.cmake └── CheckSSEFeatures.cmake ├── akaze_features.cpp └── akaze_match.cpp /datasets/iguazu/H1to2p: -------------------------------------------------------------------------------- 1 | 1 0 0 2 | 0 1 0 3 | 0 0 1 4 | -------------------------------------------------------------------------------- /datasets/iguazu/H1to3p: -------------------------------------------------------------------------------- 1 | 1 0 0 2 | 0 1 0 3 | 0 0 1 4 | -------------------------------------------------------------------------------- /datasets/iguazu/H1to4p: -------------------------------------------------------------------------------- 1 | 1 0 0 2 | 0 1 0 3 | 0 0 1 4 | -------------------------------------------------------------------------------- /datasets/iguazu/H1to5p: -------------------------------------------------------------------------------- 1 | 1 0 0 2 | 0 1 0 3 | 0 0 1 4 | -------------------------------------------------------------------------------- /datasets/iguazu/H1to6p: -------------------------------------------------------------------------------- 1 | 1 0 0 2 | 0 1 0 3 | 0 0 1 4 | -------------------------------------------------------------------------------- /datasets/iguazu/H1to1p: -------------------------------------------------------------------------------- 1 | 1.0 0.0 0.0 2 | 0.0 1.0 0.0 3 | 0.0 0.0 1.0 4 | -------------------------------------------------------------------------------- /timer/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(timer) 2 | 3 | INCLUDE_DIRECTORIES(./) 4 | ADD_LIBRARY(timer timer.cpp) -------------------------------------------------------------------------------- /datasets/iguazu/img1.pgm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sweeneychris/akaze-eigen/HEAD/datasets/iguazu/img1.pgm -------------------------------------------------------------------------------- /datasets/iguazu/img2.pgm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sweeneychris/akaze-eigen/HEAD/datasets/iguazu/img2.pgm -------------------------------------------------------------------------------- /datasets/iguazu/img3.pgm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sweeneychris/akaze-eigen/HEAD/datasets/iguazu/img3.pgm -------------------------------------------------------------------------------- /datasets/iguazu/img4.pgm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sweeneychris/akaze-eigen/HEAD/datasets/iguazu/img4.pgm -------------------------------------------------------------------------------- /datasets/iguazu/img5.pgm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sweeneychris/akaze-eigen/HEAD/datasets/iguazu/img5.pgm -------------------------------------------------------------------------------- /datasets/iguazu/img6.pgm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sweeneychris/akaze-eigen/HEAD/datasets/iguazu/img6.pgm -------------------------------------------------------------------------------- /cimg/Licence_CeCILL_V2-en.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sweeneychris/akaze-eigen/HEAD/cimg/Licence_CeCILL_V2-en.txt -------------------------------------------------------------------------------- /cimg/Licence_CeCILL-C_V1-en.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sweeneychris/akaze-eigen/HEAD/cimg/Licence_CeCILL-C_V1-en.txt -------------------------------------------------------------------------------- /cimg/cmake-modules/FindFFTW3F.cmake: -------------------------------------------------------------------------------- 1 | # - Try to find FFTW 2 | # Once done this will define 3 | # FFTW_FOUND - System has FFTW3 4 | # FFTW_INCLUDE_DIRS - The FFTW3 include directories 5 | # FFTW_LIBRARIES - The libraries needed to use FFTW3 6 | # FFTW_DEFINITIONS - Compiler switches required for using FFTW3 7 | 8 | find_package(PkgConfig) 9 | 10 | pkg_check_modules(PC_FFTW3F QUIET fftw3f) 11 | 12 | set(FFTW3F_DEFINITIONS ${PC_FFTW3F_CFLAGS_OTHER}) 13 | 14 | find_path(FFTW3F_INCLUDE_DIR fftw3.h 15 | HINTS ${PC_FFTW3F_INCLUDEDIR} ${PC_FFTW3F_INCLUDE_DIRS} 16 | NAMES fftw3.h ) 17 | 18 | find_library(FFTW3F_LIBRARY NAMES fftw3f libfftw3f 19 | HINTS ${PC_FFTW3F_LIBDIR} ${PC_FFTW3F_LIBRARY_DIRS} ) 20 | 21 | set(FFTW3F_LIBRARIES ${FFTW3F_LIBRARY} ) 22 | set(FFTW3F_INCLUDE_DIRS ${FFTW3F_INCLUDE_DIR} ) 23 | 24 | include(FindPackageHandleStandardArgs) 25 | # handle the QUIETLY and REQUIRED arguments and set FFTW3F_FOUND to TRUE 26 | # if all listed variables are TRUE 27 | find_package_handle_standard_args(FFTW3F DEFAULT_MSG 28 | FFTW3F_LIBRARY FFTW3F_INCLUDE_DIR) 29 | 30 | mark_as_advanced(FFTW3F_INCLUDE_DIR FFTW3F_LIBRARY ) -------------------------------------------------------------------------------- /cimg/cmake-modules/FindEZMINC.cmake: -------------------------------------------------------------------------------- 1 | # FindEZMINC.cmake module 2 | 3 | # Find the native MINC includes and library 4 | # This module defines 5 | # EZMINC_INCLUDE_DIR, where to find jpeglib.h, etc. 6 | # EZMINC_LIBRARIES, the libraries needed to use EZMINC. 7 | # EZMINC_FOUND, If false, do not try to use EZMINC. 8 | # also defined, but not for general use are 9 | # EZMINC_LIBRARY, where to find the MINC library. 10 | 11 | 12 | FIND_PATH(EZMINC_INCLUDE_DIR minc_1_rw.h /usr/include /usr/local/include /usr/local/bic/include /opt/minc-toolkit/include) 13 | FIND_LIBRARY(EZMINC_minc_io_LIBRARY NAMES minc_io HINTS /usr/lib /usr/local/lib /usr/local/bic/lib /opt/minc-toolkit/lib) 14 | 15 | 16 | IF (EZMINC_INCLUDE_DIR AND EZMINC_minc_io_LIBRARY) 17 | set(EZMINC_LIBRARIES 18 | ${EZMINC_minc_io_LIBRARY} 19 | ) 20 | SET(EZMINC_FOUND TRUE) 21 | 22 | ENDIF (EZMINC_INCLUDE_DIR AND EZMINC_minc_io_LIBRARY) 23 | 24 | 25 | IF (EZMINC_FOUND) 26 | IF (NOT Minc_FIND_QUIETLY) 27 | MESSAGE(STATUS "Found EZMINC: ${EZMINC_LIBRARIES}") 28 | ENDIF (NOT Minc_FIND_QUIETLY) 29 | ELSE (EZMINC_FOUND) 30 | IF (Minc_FIND_REQUIRED) 31 | MESSAGE(FATAL_ERROR "Cound not find EZMINC") 32 | ENDIF (Minc_FIND_REQUIRED) 33 | ENDIF (EZMINC_FOUND) 34 | 35 | 36 | mark_as_advanced( 37 | EZMINC_minc_io_LIBRARY 38 | ) 39 | -------------------------------------------------------------------------------- /cimg/cmake-modules/FindBOARD.cmake: -------------------------------------------------------------------------------- 1 | # - Find BOARD 2 | # Find the native BOARD includes and library 3 | # This module defines 4 | # BOARD_INCLUDE_DIR, where to find jpeglib.h, etc. 5 | # BOARD_LIBRARIES, the libraries needed to use BOARD. 6 | # BOARD_FOUND, If false, do not try to use BOARD. 7 | # also defined, but not for general use are 8 | # BOARD_LIBRARY, where to find the BOARD library. 9 | 10 | FIND_PATH(BOARD_INCLUDE_DIR board.h 11 | /usr/local/include 12 | /usr/include 13 | ) 14 | 15 | SET(BOARD_NAMES ${BOARD_NAMES} board) 16 | FIND_LIBRARY(BOARD_LIBRARY 17 | NAMES ${BOARD_NAMES} 18 | PATHS /usr/lib /usr/local/lib 19 | ) 20 | 21 | IF (BOARD_LIBRARY AND BOARD_INCLUDE_DIR) 22 | SET(BOARD_LIBRARIES ${BOARD_LIBRARY}) 23 | SET(BOARD_FOUND "YES") 24 | ELSE (BOARD_LIBRARY AND BOARD_INCLUDE_DIR) 25 | SET(BOARD_FOUND "NO") 26 | ENDIF (BOARD_LIBRARY AND BOARD_INCLUDE_DIR) 27 | 28 | 29 | IF (BOARD_FOUND) 30 | IF (NOT BOARD_FIND_QUIETLY) 31 | MESSAGE(STATUS "Found BOARD: ${BOARD_LIBRARIES}") 32 | ENDIF (NOT BOARD_FIND_QUIETLY) 33 | ELSE (BOARD_FOUND) 34 | IF (BOARD_FIND_REQUIRED) 35 | MESSAGE(FATAL_ERROR "Could not find BOARD library") 36 | ENDIF (BOARD_FIND_REQUIRED) 37 | ENDIF (BOARD_FOUND) 38 | 39 | # Deprecated declarations. 40 | SET (NATIVE_BOARD_INCLUDE_PATH ${BOARD_INCLUDE_DIR} ) 41 | GET_FILENAME_COMPONENT (NATIVE_BOARD_LIB_PATH ${BOARD_LIBRARY} PATH) 42 | 43 | MARK_AS_ADVANCED( 44 | BOARD_LIBRARY 45 | BOARD_INCLUDE_DIR 46 | ) 47 | -------------------------------------------------------------------------------- /cimg/cmake-modules/FindMINC.cmake: -------------------------------------------------------------------------------- 1 | # FindMINC.cmake module 2 | 3 | # Find the native MINC includes and library 4 | # This module defines 5 | # MINC_INCLUDE_DIR, where to find jpeglib.h, etc. 6 | # MINC_LIBRARIES, the libraries needed to use MINC. 7 | # MINC_FOUND, If false, do not try to use MINC. 8 | # also defined, but not for general use are 9 | # MINC_LIBRARY, where to find the MINC library. 10 | 11 | 12 | FIND_PATH(MINC_INCLUDE_DIR minc2.h /usr/include /usr/local/include /usr/local/bic/include /opt/minc-toolkit/include) 13 | FIND_LIBRARY(MINC_volume_io2_LIBRARY NAMES volume_io2 HINTS /usr/lib /usr/local/lib /usr/local/bic/lib /opt/minc-toolkit/include) 14 | FIND_LIBRARY(MINC_minc2_LIBRARY NAMES minc2 HINTS /usr/lib /usr/local/lib /usr/local/bic/lib /opt/minc-toolkit/include) 15 | 16 | 17 | IF (MINC_INCLUDE_DIR AND MINC_minc2_LIBRARY AND MINC_volume_io2_LIBRARY) 18 | set(MINC_LIBRARIES 19 | ${MINC_volume_io2_LIBRARY} 20 | ${MINC_minc2_LIBRARY} 21 | ) 22 | SET(MINC_FOUND TRUE) 23 | 24 | ENDIF (MINC_INCLUDE_DIR AND MINC_minc2_LIBRARY AND MINC_volume_io2_LIBRARY) 25 | 26 | 27 | IF (MINC_FOUND) 28 | IF (NOT Minc_FIND_QUIETLY) 29 | MESSAGE(STATUS "Found MINC: ${MINC_LIBRARIES}") 30 | ENDIF (NOT Minc_FIND_QUIETLY) 31 | ELSE (MINC_FOUND) 32 | IF (Minc_FIND_REQUIRED) 33 | MESSAGE(FATAL_ERROR "Cound not find MINC") 34 | ENDIF (Minc_FIND_REQUIRED) 35 | ENDIF (MINC_FOUND) 36 | 37 | 38 | mark_as_advanced( 39 | MINC_minc2_LIBRARY 40 | MINC_volume_io2_LIBRARY 41 | ) 42 | -------------------------------------------------------------------------------- /cimg/cmake-modules/FindTIFF.cmake: -------------------------------------------------------------------------------- 1 | # - Find TIFF library 2 | # Find the native TIFF includes and library 3 | # This module defines 4 | # TIFF_INCLUDE_DIR, where to find tiff.h, etc. 5 | # TIFF_LIBRARIES, libraries to link against to use TIFF. 6 | # TIFF_FOUND, If false, do not try to use TIFF. 7 | # also defined, but not for general use are 8 | # TIFF_LIBRARY, where to find the TIFF library. 9 | 10 | #============================================================================= 11 | # Copyright 2002-2009 Kitware, Inc. 12 | # 13 | # Distributed under the OSI-approved BSD License (the "License"); 14 | # see accompanying file Copyright.txt for details. 15 | # 16 | # This software is distributed WITHOUT ANY WARRANTY; without even the 17 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 18 | # See the License for more information. 19 | #============================================================================= 20 | # (To distributed this file outside of CMake, substitute the full 21 | # License text for the above reference.) 22 | 23 | FIND_PATH(TIFF_INCLUDE_DIR tiff.h) 24 | 25 | SET(TIFF_NAMES ${TIFF_NAMES} tiff libtiff libtiff3) 26 | FIND_LIBRARY(TIFF_LIBRARY NAMES ${TIFF_NAMES} ) 27 | 28 | # handle the QUIETLY and REQUIRED arguments and set TIFF_FOUND to TRUE if 29 | # all listed variables are TRUE 30 | INCLUDE(FindPackageHandleStandardArgs) 31 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(TIFF DEFAULT_MSG TIFF_LIBRARY TIFF_INCLUDE_DIR) 32 | 33 | IF(TIFF_FOUND) 34 | SET( TIFF_LIBRARIES ${TIFF_LIBRARY} ) 35 | ENDIF(TIFF_FOUND) 36 | 37 | MARK_AS_ADVANCED(TIFF_INCLUDE_DIR TIFF_LIBRARY) 38 | -------------------------------------------------------------------------------- /cimg/cmake-modules/FindZLIB.cmake: -------------------------------------------------------------------------------- 1 | # - Find zlib 2 | # Find the native ZLIB includes and library 3 | # 4 | # ZLIB_INCLUDE_DIRS - where to find zlib.h, etc. 5 | # ZLIB_LIBRARIES - List of libraries when using zlib. 6 | # ZLIB_FOUND - True if zlib found. 7 | 8 | #============================================================================= 9 | # Copyright 2001-2009 Kitware, Inc. 10 | # 11 | # Distributed under the OSI-approved BSD License (the "License"); 12 | # see accompanying file Copyright.txt for details. 13 | # 14 | # This software is distributed WITHOUT ANY WARRANTY; without even the 15 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | # See the License for more information. 17 | #============================================================================= 18 | # (To distributed this file outside of CMake, substitute the full 19 | # License text for the above reference.) 20 | 21 | IF (ZLIB_INCLUDE_DIR) 22 | # Already in cache, be silent 23 | SET(ZLIB_FIND_QUIETLY TRUE) 24 | ENDIF (ZLIB_INCLUDE_DIR) 25 | 26 | FIND_PATH(ZLIB_INCLUDE_DIR zlib.h) 27 | 28 | SET(ZLIB_NAMES z zlib zdll) 29 | FIND_LIBRARY(ZLIB_LIBRARY NAMES ${ZLIB_NAMES} ) 30 | MARK_AS_ADVANCED( ZLIB_LIBRARY ZLIB_INCLUDE_DIR ) 31 | 32 | # Per-recommendation 33 | SET(ZLIB_INCLUDE_DIRS "${ZLIB_INCLUDE_DIR}") 34 | SET(ZLIB_LIBRARIES "${ZLIB_LIBRARY}") 35 | 36 | # handle the QUIETLY and REQUIRED arguments and set ZLIB_FOUND to TRUE if 37 | # all listed variables are TRUE 38 | INCLUDE(FindPackageHandleStandardArgs) 39 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(ZLIB DEFAULT_MSG ZLIB_LIBRARIES ZLIB_INCLUDE_DIRS) 40 | 41 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014, Chris Sweeney, Pablo Fernandez Alcantarilla, Jesus Nuevo 2 | All Rights Reserved 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, 8 | this list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of the copyright holders nor the names of its contributors 15 | may be used to endorse or promote products derived from this software without 16 | specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 19 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 21 | SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 22 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 23 | TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24 | BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY 26 | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | -------------------------------------------------------------------------------- /cimg/cmake-modules/FindJPEG.cmake: -------------------------------------------------------------------------------- 1 | # - Find JPEG 2 | # Find the native JPEG includes and library 3 | # This module defines 4 | # JPEG_INCLUDE_DIR, where to find jpeglib.h, etc. 5 | # JPEG_LIBRARIES, the libraries needed to use JPEG. 6 | # JPEG_FOUND, If false, do not try to use JPEG. 7 | # also defined, but not for general use are 8 | # JPEG_LIBRARY, where to find the JPEG library. 9 | 10 | #============================================================================= 11 | # Copyright 2001-2009 Kitware, Inc. 12 | # 13 | # Distributed under the OSI-approved BSD License (the "License"); 14 | # see accompanying file Copyright.txt for details. 15 | # 16 | # This software is distributed WITHOUT ANY WARRANTY; without even the 17 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 18 | # See the License for more information. 19 | #============================================================================= 20 | # (To distributed this file outside of CMake, substitute the full 21 | # License text for the above reference.) 22 | 23 | FIND_PATH(JPEG_INCLUDE_DIR jpeglib.h) 24 | 25 | SET(JPEG_NAMES ${JPEG_NAMES} jpeg) 26 | FIND_LIBRARY(JPEG_LIBRARY NAMES ${JPEG_NAMES} ) 27 | 28 | # handle the QUIETLY and REQUIRED arguments and set JPEG_FOUND to TRUE if 29 | # all listed variables are TRUE 30 | INCLUDE(FindPackageHandleStandardArgs) 31 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(JPEG DEFAULT_MSG JPEG_LIBRARY JPEG_INCLUDE_DIR) 32 | 33 | IF(JPEG_FOUND) 34 | SET(JPEG_LIBRARIES ${JPEG_LIBRARY}) 35 | ENDIF(JPEG_FOUND) 36 | 37 | # Deprecated declarations. 38 | SET (NATIVE_JPEG_INCLUDE_PATH ${JPEG_INCLUDE_DIR} ) 39 | IF(JPEG_LIBRARY) 40 | GET_FILENAME_COMPONENT (NATIVE_JPEG_LIB_PATH ${JPEG_LIBRARY} PATH) 41 | ENDIF(JPEG_LIBRARY) 42 | 43 | MARK_AS_ADVANCED(JPEG_LIBRARY JPEG_INCLUDE_DIR ) 44 | -------------------------------------------------------------------------------- /timer/timer.hpp: -------------------------------------------------------------------------------- 1 | // The following code was taken from the OpenMVG library and is unmodified other 2 | // than the namespace and header guard. 3 | // To see the original source code, please visit OpenMVG's repository: 4 | // https://github.com/openMVG/openMVG 5 | // The original software license is given below. 6 | 7 | // ========================================================================== // 8 | // 9 | // Copyright (C) 2013 David Ok 10 | // Copyright (C) 2014 Pierre Moulon 11 | // 12 | // Adapted from DO++, a basic set of libraries in C++ for computer 13 | // vision. 14 | // 15 | // This Source Code Form is subject to the terms of the Mozilla Public 16 | // License v. 2.0. If a copy of the MPL was not distributed with this file, 17 | // you can obtain one at http://mozilla.org/MPL/2.0/. 18 | // ========================================================================== // 19 | 20 | #ifndef TIMER_HPP 21 | #define TIMER_HPP 22 | 23 | #ifdef HAVE_CXX11_CHRONO 24 | #include 25 | #endif 26 | #include 27 | 28 | namespace timer { 29 | 30 | //! \brief Timer class with microsecond accuracy. 31 | class Timer 32 | { 33 | public: 34 | //! Default constructor 35 | Timer(); 36 | //! Reset the timer to zero. 37 | void reset(); 38 | //! Returns the elapsed time in seconds. 39 | double elapsed() const; 40 | //! Returns the elapsed time in milliseconds. 41 | double elapsedMs() const; 42 | private: 43 | 44 | #ifdef HAVE_CXX11_CHRONO 45 | std::chrono::high_resolution_clock::time_point start_; 46 | #else 47 | double start_; 48 | #ifdef _WIN32 49 | double frequency_; 50 | #endif 51 | #endif // HAVE_CXX11_CHRONO 52 | }; 53 | 54 | // print the elapsed time 55 | std::ostream& operator << (std::ostream&, const Timer&); 56 | 57 | } // namespace timer 58 | 59 | #endif // TIMER_HPP 60 | -------------------------------------------------------------------------------- /cimg/cmake-modules/FindPNG.cmake: -------------------------------------------------------------------------------- 1 | # - Find the native PNG includes and library 2 | # 3 | # This module defines 4 | # PNG_INCLUDE_DIR, where to find png.h, etc. 5 | # PNG_LIBRARIES, the libraries to link against to use PNG. 6 | # PNG_DEFINITIONS - You should add_definitons(${PNG_DEFINITIONS}) before compiling code that includes png library files. 7 | # PNG_FOUND, If false, do not try to use PNG. 8 | # also defined, but not for general use are 9 | # PNG_LIBRARY, where to find the PNG library. 10 | # None of the above will be defined unles zlib can be found. 11 | # PNG depends on Zlib 12 | 13 | #============================================================================= 14 | # Copyright 2002-2009 Kitware, Inc. 15 | # 16 | # Distributed under the OSI-approved BSD License (the "License"); 17 | # see accompanying file Copyright.txt for details. 18 | # 19 | # This software is distributed WITHOUT ANY WARRANTY; without even the 20 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 21 | # See the License for more information. 22 | #============================================================================= 23 | # (To distributed this file outside of CMake, substitute the full 24 | # License text for the above reference.) 25 | 26 | if(PNG_FIND_QUIETLY) 27 | set(_FIND_ZLIB_ARG QUIET) 28 | endif(PNG_FIND_QUIETLY) 29 | find_package(ZLIB ${_FIND_ZLIB_ARG}) 30 | 31 | if(ZLIB_FOUND) 32 | find_path(PNG_PNG_INCLUDE_DIR png.h 33 | /usr/local/include/libpng # OpenBSD 34 | ) 35 | 36 | set(PNG_NAMES ${PNG_NAMES} png libpng png12 libpng12) 37 | find_library(PNG_LIBRARY NAMES ${PNG_NAMES} ) 38 | 39 | if (PNG_LIBRARY AND PNG_PNG_INCLUDE_DIR) 40 | # png.h includes zlib.h. Sigh. 41 | SET(PNG_INCLUDE_DIR ${PNG_PNG_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR} ) 42 | SET(PNG_LIBRARIES ${PNG_LIBRARY} ${ZLIB_LIBRARY}) 43 | 44 | if (CYGWIN) 45 | if(BUILD_SHARED_LIBS) 46 | # No need to define PNG_USE_DLL here, because it's default for Cygwin. 47 | else(BUILD_SHARED_LIBS) 48 | SET (PNG_DEFINITIONS -DPNG_STATIC) 49 | endif(BUILD_SHARED_LIBS) 50 | endif (CYGWIN) 51 | 52 | endif (PNG_LIBRARY AND PNG_PNG_INCLUDE_DIR) 53 | 54 | endif(ZLIB_FOUND) 55 | 56 | # handle the QUIETLY and REQUIRED arguments and set PNG_FOUND to TRUE if 57 | # all listed variables are TRUE 58 | include(FindPackageHandleStandardArgs) 59 | find_package_handle_standard_args(PNG DEFAULT_MSG PNG_LIBRARY PNG_PNG_INCLUDE_DIR) 60 | 61 | mark_as_advanced(PNG_PNG_INCLUDE_DIR PNG_LIBRARY ) 62 | -------------------------------------------------------------------------------- /cimg/cmake-modules/FindTest.cmake: -------------------------------------------------------------------------------- 1 | # - Try to find FFMPEG 2 | # Once done this will define 3 | # 4 | # FFMPEG_FOUND - system has FFMPEG 5 | # FFMPEG_INCLUDE_DIRS - the FFMPEG include directory 6 | # FFMPEG_LIBRARIES - Link these to use FFMPEG 7 | # FFMPEG_DEFINITIONS - Compiler switches required for using FFMPEG 8 | # 9 | # Copyright (c) 2006 Andreas Schneider 10 | # 11 | # Redistribution and use is allowed according to the terms of the New 12 | # BSD license. 13 | # For details see the accompanying COPYING-CMAKE-SCRIPTS file. 14 | # 15 | 16 | 17 | if (FFMPEG_LIBRARIES AND FFMPEG_INCLUDE_DIRS) 18 | # in cache already 19 | set(FFMPEG_FOUND TRUE) 20 | else (FFMPEG_LIBRARIES AND FFMPEG_INCLUDE_DIRS) 21 | # use pkg-config to get the directories and then use these values 22 | # in the FIND_PATH() and FIND_LIBRARY() calls 23 | include(UsePkgConfig) 24 | 25 | pkgconfig(libavcodec _FFMPEGIncDir _FFMPEGLinkDir _FFMPEGLinkFlags _FFMPEGCflags) 26 | 27 | set(FFMPEG_DEFINITIONS ${_FFMPEGCflags}) 28 | 29 | find_path(FFMPEG_INCLUDE_DIR 30 | NAMES 31 | avcodec.h 32 | PATHS 33 | ${_FFMPEGIncDir} 34 | /usr/include 35 | /usr/local/include 36 | /opt/local/include 37 | /sw/include 38 | PATH_SUFFIXES 39 | ffmpeg 40 | ) 41 | 42 | if (NOT APPLE) 43 | find_library(AVUTIL_LIBRARY 44 | NAMES 45 | avutil 46 | PATHS 47 | ${_FFMPEGLinkDir} 48 | /usr/lib 49 | /usr/local/lib 50 | /opt/local/lib 51 | /sw/lib 52 | ) 53 | endif (NOT APPLE) 54 | 55 | find_library(AVCODEC_LIBRARY 56 | NAMES 57 | avcodec 58 | PATHS 59 | ${_FFMPEGLinkDir} 60 | /usr/lib 61 | /usr/local/lib 62 | /opt/local/lib 63 | /sw/lib 64 | ) 65 | 66 | find_library(AVFORMAT_LIBRARY 67 | NAMES 68 | avformat 69 | PATHS 70 | ${_FFMPEGLinkDir} 71 | /usr/lib 72 | /usr/local/lib 73 | /opt/local/lib 74 | /sw/lib 75 | ) 76 | 77 | set(FFMPEG_INCLUDE_DIRS 78 | ${FFMPEG_INCLUDE_DIR} 79 | ) 80 | 81 | set(FFMPEG_LIBRARIES 82 | ${AVUTIL_LIBRARY} 83 | ${AVCODEC_LIBRARY} 84 | ${AVFORMAT_LIBRARY} 85 | ) 86 | 87 | if (FFMPEG_INCLUDE_DIRS AND FFMPEG_LIBRARIES) 88 | set(FFMPEG_FOUND TRUE) 89 | endif (FFMPEG_INCLUDE_DIRS AND FFMPEG_LIBRARIES) 90 | 91 | if (FFMPEG_FOUND) 92 | if (NOT FFMPEG_FIND_QUIETLY) 93 | message(STATUS "Found FFMPEG: ${FFMPEG_LIBRARIES}") 94 | endif (NOT FFMPEG_FIND_QUIETLY) 95 | else (FFMPEG_FOUND) 96 | if (FFMPEG_FIND_REQUIRED) 97 | message(FATAL_ERROR "Could not find FFMPEG") 98 | endif (FFMPEG_FIND_REQUIRED) 99 | endif (FFMPEG_FOUND) 100 | 101 | # show the FFMPEG_INCLUDE_DIRS and FFMPEG_LIBRARIES variables only in the advanced view 102 | mark_as_advanced(FFMPEG_INCLUDE_DIRS FFMPEG_LIBRARIES) 103 | 104 | endif (FFMPEG_LIBRARIES AND FFMPEG_INCLUDE_DIRS) 105 | -------------------------------------------------------------------------------- /src/convolution.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2014 The Regents of the University of California (Regents). 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following 13 | // disclaimer in the documentation and/or other materials provided 14 | // with the distribution. 15 | // 16 | // * Neither the name of The Regents or University of California nor the 17 | // names of its contributors may be used to endorse or promote products 18 | // derived from this software without specific prior written permission. 19 | // 20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE 24 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 | // POSSIBILITY OF SUCH DAMAGE. 31 | // 32 | // Please contact the author of this library if you have any questions. 33 | // Author: Chris Sweeney (cmsweeney@cs.ucsb.edu) 34 | 35 | #ifndef CONVOLUTION_H_ 36 | #define CONVOLUTION_H_ 37 | 38 | #include 39 | 40 | typedef Eigen::Matrix 41 | RowMatrixXf; 42 | 43 | enum BorderType { 44 | REFLECT = 0, 45 | REPLICATE = 1, 46 | DEFAULT = REFLECT 47 | }; 48 | 49 | // Performs separable convolution using two filters of the same size. 50 | void SeparableConvolution2d(const RowMatrixXf& image, 51 | const Eigen::RowVectorXf& kernel_x, 52 | const Eigen::RowVectorXf& kernel_y, 53 | const BorderType& border_type, 54 | RowMatrixXf* out); 55 | 56 | // Computes the image derivative using the Scharr filter. 57 | void ScharrDerivative(const RowMatrixXf& image, 58 | const int x_deg, 59 | const int y_deg, 60 | const int size, 61 | const bool normalize, 62 | RowMatrixXf* out); 63 | 64 | void GaussianBlur(const RowMatrixXf& image, 65 | const double sigma, 66 | RowMatrixXf* out); 67 | 68 | #endif // CONVOLUTION_H_ 69 | -------------------------------------------------------------------------------- /src/fed.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file fed.h 3 | * @brief Functions for performing Fast Explicit Diffusion and building the 4 | * nonlinear scale space 5 | * @date Oct 07, 2014 6 | * @author Pablo F. Alcantarilla, Jesus Nuevo 7 | * @note This code is derived from FED/FJ library from Grewenig et al., 8 | * The FED/FJ library allows solving more advanced problems 9 | * Please look at the following papers for more information about FED: 10 | * [1] S. Grewenig, J. Weickert, C. Schroers, A. Bruhn. Cyclic Schemes for 11 | * PDE-Based Image Analysis. Technical Report No. 327, Department of Mathematics, 12 | * Saarland University, Saarbrücken, Germany, March 2013 13 | * [2] S. Grewenig, J. Weickert, A. Bruhn. From box filtering to fast explicit 14 | * diffusion. 15 | * DAGM, 2010 16 | * 17 | */ 18 | 19 | #ifndef AKAZE_SRC_FED_H_ 20 | #define AKAZE_SRC_FED_H_ 21 | 22 | /* ************************************************************************* */ 23 | // System 24 | #include 25 | 26 | namespace libAKAZE { 27 | 28 | /* ************************************************************************* */ 29 | /// This function allocates an array of the least number of time steps such 30 | /// that a certain stopping time for the whole process can be obtained and fills 31 | /// it with the respective FED time step sizes for one cycle 32 | /// The function returns the number of time steps per cycle or 0 on failure 33 | /// @param T Desired process stopping time 34 | /// @param M Desired number of cycles 35 | /// @param tau_max Stability limit for the explicit scheme 36 | /// @param reordering Reordering flag 37 | /// @param tau The vector with the dynamic step sizes 38 | int fed_tau_by_process_time(const float T, const int M, const float tau_max, 39 | const bool reordering, std::vector& tau); 40 | 41 | /// This function allocates an array of the least number of time steps such 42 | /// that a certain stopping time for the whole process can be obtained and fills 43 | /// it with the respective FED time step sizes for one cycle 44 | /// The function returns the number of time steps per cycle or 0 on failure 45 | /// @param t Desired cycle stopping time 46 | /// @param tau_max Stability limit for the explicit scheme 47 | /// @param reordering Reordering flag 48 | /// @param tau The vector with the dynamic step sizes 49 | int fed_tau_by_cycle_time(const float t, const float tau_max, 50 | const bool reordering, std::vector& tau); 51 | 52 | /// This function allocates an array of time steps and fills it with FED 53 | /// time step sizes 54 | /// The function returns the number of time steps per cycle or 0 on failure 55 | /// @param n Number of internal steps 56 | /// @param scale Ratio of t we search to maximal t 57 | /// @param tau_max Stability limit for the explicit scheme 58 | /// @param reordering Reordering flag 59 | /// @param tau The vector with the dynamic step sizes 60 | int fed_tau_internal(const int n, const float scale, const float tau_max, 61 | const bool reordering, std::vector& tau); 62 | 63 | /// This function checks if a number is prime or not 64 | bool fed_is_prime_internal(const int number); 65 | 66 | } // namespace libAKAZE 67 | 68 | #endif // AKAZE_SRC_FED_H_ 69 | -------------------------------------------------------------------------------- /timer/timer.cpp: -------------------------------------------------------------------------------- 1 | // The following code was taken from the OpenMVG library and is unmodified other 2 | // than the namespace and header guard. 3 | // To see the original source code, please visit OpenMVG's repository: 4 | // https://github.com/openMVG/openMVG 5 | // The original software license is given below. 6 | 7 | // ========================================================================== // 8 | // 9 | // Copyright (C) 2013 David Ok 10 | // Copyright (C) 2014 Pierre Moulon 11 | // 12 | // Adapted from DO++, a basic set of libraries in C++ for computer 13 | // vision. 14 | // 15 | // This Source Code Form is subject to the terms of the Mozilla Public 16 | // License v. 2.0. If a copy of the MPL was not distributed with this file, 17 | // you can obtain one at http://mozilla.org/MPL/2.0/. 18 | // ========================================================================== // 19 | 20 | #include "timer.hpp" 21 | #ifdef _WIN32 22 | # include 23 | #else 24 | # include 25 | #endif 26 | 27 | namespace timer { 28 | 29 | Timer::Timer() 30 | { 31 | #ifdef HAVE_CXX11_CHRONO 32 | #else 33 | #ifdef _WIN32 34 | LARGE_INTEGER freq; 35 | if (!QueryPerformanceFrequency(&freq)) 36 | { 37 | const char *msg = "Failed to initialize high resolution timer!"; 38 | std::cerr << msg << std::endl; 39 | throw std::runtime_error(msg); 40 | } 41 | frequency_ = static_cast(freq.QuadPart); 42 | #endif 43 | #endif 44 | reset(); 45 | } 46 | 47 | void Timer::reset() 48 | { 49 | #ifdef HAVE_CXX11_CHRONO 50 | start_ = std::chrono::high_resolution_clock::now(); 51 | #else 52 | 53 | #ifdef _WIN32 54 | LARGE_INTEGER li_start_; 55 | QueryPerformanceCounter(&li_start_); 56 | start_ = static_cast(li_start_.QuadPart); 57 | #else 58 | timeval start; 59 | gettimeofday(&start, NULL); 60 | start_ = start.tv_sec + start.tv_usec * 1e-6; 61 | #endif 62 | 63 | #endif // HAVE_CXX11_CHRONO 64 | } 65 | 66 | double Timer::elapsed() const 67 | { 68 | double elapsed_; 69 | #ifdef HAVE_CXX11_CHRONO 70 | auto end_ = std::chrono::high_resolution_clock::now(); 71 | elapsed_ = std::chrono::duration_cast(end_ - start_).count() / 1000.; 72 | #else 73 | 74 | #ifdef _WIN32 75 | LARGE_INTEGER end_; 76 | QueryPerformanceCounter(&end_); 77 | elapsed_ = (static_cast(end_.QuadPart) - start_) / frequency_; 78 | #else 79 | timeval end; 80 | gettimeofday(&end, NULL); 81 | double end_ = end.tv_sec + end.tv_usec * 1e-6; 82 | elapsed_ = end_ - start_; 83 | #endif 84 | #endif // HAVE_CXX11_CHRONO 85 | return elapsed_; 86 | } 87 | 88 | double Timer::elapsedMs() const 89 | { 90 | #ifdef HAVE_CXX11_CHRONO 91 | auto end_ = std::chrono::high_resolution_clock::now(); 92 | double elapsed_ = std::chrono::duration_cast(end_ - start_).count(); 93 | return elapsed_; 94 | #else 95 | return elapsed() * 1000.; 96 | #endif // HAVE_CXX11_CHRONO 97 | } 98 | 99 | std::ostream& operator << (std::ostream& str, const Timer& t) 100 | { 101 | return str << t.elapsed() << " s elapsed"; 102 | } 103 | 104 | } // namespace timer 105 | -------------------------------------------------------------------------------- /cimg/cmake-modules/FindFFMPEG.cmake: -------------------------------------------------------------------------------- 1 | # - Try to find FFMPEG 2 | # Once done this will define 3 | # 4 | # FFMPEG_FOUND - system has FFMPEG 5 | # FFMPEG_INCLUDE_DIR - the include directories 6 | # FFMPEG_LIBRARY_DIR - the directory containing the libraries 7 | # FFMPEG_LIBRARIES - link these to use FFMPEG 8 | # FFMPEG_SWSCALE_FOUND - FFMPEG also has SWSCALE 9 | # 10 | 11 | SET( FFMPEG_HEADERS avformat.h avcodec.h avutil.h ) 12 | SET( FFMPEG_PATH_SUFFIXES libavformat libavcodec libavutil ) 13 | SET( FFMPEG_SWS_HEADERS swscale.h ) 14 | SET( FFMPEG_SWS_PATH_SUFFIXES libswscale ) 15 | 16 | SET( FFMPEG_LIBRARIES avformat avcodec avutil ) 17 | SET( FFMPEG_SWS_LIBRARIES swscale ) 18 | INCLUDE(FindPkgConfig) 19 | if ( PKG_CONFIG_FOUND ) 20 | pkg_check_modules( AVFORMAT libavformat ) 21 | pkg_check_modules( AVCODEC libavcodec ) 22 | pkg_check_modules( AVUTIL libavutil ) 23 | pkg_check_modules( SWSCALE libswscale ) 24 | endif ( PKG_CONFIG_FOUND ) 25 | 26 | SET( FFMPEG_LIBRARY_DIR ${AVFORMAT_LIBRARY_DIRS} 27 | ${AVCODEC_LIBRARY_DIRS} 28 | ${AVUTIL_LIBRARY_DIRS} ) 29 | SET( FFMPEG_INCLUDE_PATHS ${AVFORMAT_INCLUDE_DIRS} 30 | ${AVCODEC_INCLUDE_DIRS} 31 | ${AVUTIL_INCLUDE_DIRS} ) 32 | 33 | # add in swscale if found 34 | IF ( SWSCALE_FOUND ) 35 | SET( FFMPEG_LIBRARY_DIR ${FFMPEG_LIBRARY_DIR} 36 | ${SWSCALE_LIBRARY_DIRS} ) 37 | SET( FFMPEG_INCLUDE_PATHS ${FFMPEG_INCLUDE_PATHS} 38 | ${SWSCALE_INCLUDE_DIRS} ) 39 | SET( FFMPEG_HEADERS ${FFMPEG_HEADERS} 40 | ${FFMPEG_SWS_HEADERS} ) 41 | SET( FFMPEG_PATH_SUFFIXES ${FFMPEG_PATH_SUFFIXES} 42 | ${FFMPEG_SWS_PATH_SUFFIXES} ) 43 | SET( FFMPEG_LIBRARIES ${FFMPEG_LIBRARIES} 44 | ${FFMPEG_SWS_LIBRARIES} ) 45 | ENDIF ( SWSCALE_FOUND ) 46 | 47 | # find includes 48 | SET( INC_SUCCESS 0 ) 49 | SET( TMP_ TMP-NOTFOUND ) 50 | SET( FFMPEG_INCLUDE_DIR ${FFMPEG_INCLUDE_PATHS} ) 51 | 52 | FOREACH( INC_ ${FFMPEG_HEADERS} ) 53 | # message( "checking: " ${INC_} ) 54 | 55 | FIND_PATH( TMP_ ${INC_} 56 | PATHS ${FFMPEG_INCLUDE_PATHS} 57 | PATH_SUFFIXES ${FFMPEG_PATH_SUFFIXES} ) 58 | IF ( TMP_ ) 59 | # message( "found: " ${TMP_} ) 60 | MATH( EXPR INC_SUCCESS ${INC_SUCCESS}+1 ) 61 | SET( FFMPEG_INCLUDE_DIR ${FFMPEG_INCLUDE_DIR} ${TMP_} ) 62 | ENDIF ( TMP_ ) 63 | SET( TMP_ TMP-NOTFOUND ) 64 | ENDFOREACH( INC_ ) 65 | 66 | # clear out duplicates 67 | #LIST( REMOVE_DUPLICATES FFMPEG_INCLUDE_DIR ) 68 | #LIST( REMOVE_DUPLICATES FFMPEG_LIBRARY_DIR ) 69 | 70 | # find the full paths of the libraries 71 | SET( TMP_ TMP-NOTFOUND ) 72 | FOREACH( LIB_ ${FFMPEG_LIBRARIES} ) 73 | FIND_LIBRARY( TMP_ NAMES ${LIB_} PATHS ${FFMPEG_LIBRARY_DIR} ) 74 | IF ( TMP_ ) 75 | SET( FFMPEG_LIBRARIES_FULL ${FFMPEG_LIBRARIES_FULL} ${TMP_} ) 76 | ENDIF ( TMP_ ) 77 | SET( TMP_ TMP-NOTFOUND ) 78 | ENDFOREACH( LIB_ ) 79 | SET ( FFMPEG_LIBRARIES ${FFMPEG_LIBRARIES_FULL} ) 80 | 81 | LIST( LENGTH FFMPEG_HEADERS LIST_SIZE_ ) 82 | 83 | SET( FFMPEG_FOUND FALSE ) 84 | SET( FFMPEG_SWSCALE_FOUND FALSE ) 85 | IF ( ${INC_SUCCESS} EQUAL ${LIST_SIZE_} ) 86 | SET( FFMPEG_FOUND TRUE ) 87 | SET( FFMPEG_SWSCALE_FOUND ${SWSCALE_FOUND} ) 88 | ENDIF ( ${INC_SUCCESS} EQUAL ${LIST_SIZE_} ) 89 | -------------------------------------------------------------------------------- /cimg/cmake-modules/FindFFTW3.cmake: -------------------------------------------------------------------------------- 1 | # - Try to find FFTW3. 2 | # Usage: find_package(FFTW3 [COMPONENTS [single double long-double threads]]) 3 | # 4 | # Variables used by this module: 5 | # FFTW3_ROOT_DIR - FFTW3 root directory 6 | # Variables defined by this module: 7 | # FFTW3_FOUND - system has FFTW3 8 | # FFTW3_INCLUDE_DIR - the FFTW3 include directory (cached) 9 | # FFTW3_INCLUDE_DIRS - the FFTW3 include directories 10 | # (identical to FFTW3_INCLUDE_DIR) 11 | # FFTW3[FL]?_LIBRARY - the FFTW3 library - double, single(F), 12 | # long-double(L) precision (cached) 13 | # FFTW3[FL]?_THREADS_LIBRARY - the threaded FFTW3 library - double, single(F), 14 | # long-double(L) precision (cached) 15 | # FFTW3_LIBRARIES - list of all FFTW3 libraries found 16 | 17 | # Copyright (C) 2009-2010 18 | # ASTRON (Netherlands Institute for Radio Astronomy) 19 | # P.O.Box 2, 7990 AA Dwingeloo, The Netherlands 20 | # 21 | # This file is part of the LOFAR software suite. 22 | # The LOFAR software suite is free software: you can redistribute it and/or 23 | # modify it under the terms of the GNU General Public License as published 24 | # by the Free Software Foundation, either version 3 of the License, or 25 | # (at your option) any later version. 26 | # 27 | # The LOFAR software suite is distributed in the hope that it will be useful, 28 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 29 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 30 | # GNU General Public License for more details. 31 | # 32 | # You should have received a copy of the GNU General Public License along 33 | # with the LOFAR software suite. If not, see . 34 | # 35 | # $Id: FindFFTW3.cmake 15918 2010-06-25 11:12:42Z loose $ 36 | 37 | # Use double precision by default. 38 | if(FFTW3_FIND_COMPONENTS MATCHES "^$") 39 | set(_components double) 40 | else() 41 | set(_components ${FFTW3_FIND_COMPONENTS}) 42 | endif() 43 | 44 | # Loop over each component. 45 | set(_libraries) 46 | foreach(_comp ${_components}) 47 | if(_comp STREQUAL "single") 48 | list(APPEND _libraries fftw3f) 49 | elseif(_comp STREQUAL "double") 50 | list(APPEND _libraries fftw3) 51 | elseif(_comp STREQUAL "long-double") 52 | list(APPEND _libraries fftw3l) 53 | elseif(_comp STREQUAL "threads") 54 | set(_use_threads ON) 55 | else(_comp STREQUAL "single") 56 | message(FATAL_ERROR "FindFFTW3: unknown component `${_comp}' specified. " 57 | "Valid components are `single', `double', `long-double', and `threads'.") 58 | endif(_comp STREQUAL "single") 59 | endforeach(_comp ${_components}) 60 | 61 | # If using threads, we need to link against threaded libraries as well. 62 | if(_use_threads) 63 | set(_thread_libs) 64 | foreach(_lib ${_libraries}) 65 | list(APPEND _thread_libs ${_lib}_threads) 66 | endforeach(_lib ${_libraries}) 67 | set(_libraries ${_thread_libs} ${_libraries}) 68 | endif(_use_threads) 69 | 70 | # Keep a list of variable names that we need to pass on to 71 | # find_package_handle_standard_args(). 72 | set(_check_list) 73 | 74 | # Search for all requested libraries. 75 | foreach(_lib ${_libraries}) 76 | string(TOUPPER ${_lib} _LIB) 77 | find_library(${_LIB}_LIBRARY ${_lib} 78 | HINTS ${FFTW3_ROOT_DIR} PATH_SUFFIXES lib) 79 | mark_as_advanced(${_LIB}_LIBRARY) 80 | list(APPEND FFTW3_LIBRARIES ${${_LIB}_LIBRARY}) 81 | list(APPEND _check_list ${_LIB}_LIBRARY) 82 | endforeach(_lib ${_libraries}) 83 | 84 | # Search for the header file. 85 | -------------------------------------------------------------------------------- /cimg/cmake-modules/FindOpenMP.cmake: -------------------------------------------------------------------------------- 1 | # - Finds OpenMP support 2 | # This module can be used to detect OpenMP support in a compiler. 3 | # If the compiler supports OpenMP, the flags required to compile with 4 | # openmp support are set. 5 | # 6 | # The following variables are set: 7 | # OpenMP_C_FLAGS - flags to add to the C compiler for OpenMP support 8 | # OpenMP_CXX_FLAGS - flags to add to the CXX compiler for OpenMP support 9 | # OPENMP_FOUND - true if openmp is detected 10 | # 11 | # Supported compilers can be found at http://openmp.org/wp/openmp-compilers/ 12 | 13 | #============================================================================= 14 | # Copyright 2009 Kitware, Inc. 15 | # Copyright 2008-2009 André Rigland Brodtkorb 16 | # 17 | # Distributed under the OSI-approved BSD License (the "License"); 18 | # see accompanying file Copyright.txt for details. 19 | # 20 | # This software is distributed WITHOUT ANY WARRANTY; without even the 21 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 22 | # See the License for more information. 23 | #============================================================================= 24 | # (To distributed this file outside of CMake, substitute the full 25 | # License text for the above reference.) 26 | 27 | include(CheckCSourceCompiles) 28 | include(CheckCXXSourceCompiles) 29 | include(FindPackageHandleStandardArgs) 30 | 31 | set(OpenMP_C_FLAG_CANDIDATES 32 | #Gnu 33 | "-fopenmp" 34 | #Microsoft Visual Studio 35 | "/openmp" 36 | #Intel windows 37 | "-Qopenmp" 38 | #Intel 39 | "-openmp" 40 | #Empty, if compiler automatically accepts openmp 41 | " " 42 | #Sun 43 | "-xopenmp" 44 | #HP 45 | "+Oopenmp" 46 | #IBM XL C/c++ 47 | "-qsmp" 48 | #Portland Group 49 | "-mp" 50 | ) 51 | set(OpenMP_CXX_FLAG_CANDIDATES ${OpenMP_C_FLAG_CANDIDATES}) 52 | 53 | # sample openmp source code to test 54 | set(OpenMP_C_TEST_SOURCE 55 | " 56 | #include 57 | int main() { 58 | #ifdef _OPENMP 59 | return 0; 60 | #else 61 | breaks_on_purpose 62 | #endif 63 | } 64 | ") 65 | # use the same source for CXX as C for now 66 | set(OpenMP_CXX_TEST_SOURCE ${OpenMP_C_TEST_SOURCE}) 67 | # if these are set then do not try to find them again, 68 | # by avoiding any try_compiles for the flags 69 | if(DEFINED OpenMP_C_FLAGS AND DEFINED OpenMP_CXX_FLAGS) 70 | set(OpenMP_C_FLAG_CANDIDATES) 71 | set(OpenMP_CXX_FLAG_CANDIDATES) 72 | endif(DEFINED OpenMP_C_FLAGS AND DEFINED OpenMP_CXX_FLAGS) 73 | 74 | # check c compiler 75 | foreach(FLAG ${OpenMP_C_FLAG_CANDIDATES}) 76 | set(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") 77 | set(CMAKE_REQUIRED_FLAGS "${FLAG}") 78 | unset(OpenMP_FLAG_DETECTED CACHE) 79 | message(STATUS "Try OpenMP C flag = [${FLAG}]") 80 | check_c_source_compiles("${OpenMP_CXX_TEST_SOURCE}" OpenMP_FLAG_DETECTED) 81 | set(CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}") 82 | if(OpenMP_FLAG_DETECTED) 83 | set(OpenMP_C_FLAGS_INTERNAL "${FLAG}") 84 | break() 85 | endif(OpenMP_FLAG_DETECTED) 86 | endforeach(FLAG ${OpenMP_C_FLAG_CANDIDATES}) 87 | 88 | # check cxx compiler 89 | foreach(FLAG ${OpenMP_CXX_FLAG_CANDIDATES}) 90 | set(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") 91 | set(CMAKE_REQUIRED_FLAGS "${FLAG}") 92 | unset(OpenMP_FLAG_DETECTED CACHE) 93 | message(STATUS "Try OpenMP CXX flag = [${FLAG}]") 94 | check_cxx_source_compiles("${OpenMP_C_TEST_SOURCE}" OpenMP_FLAG_DETECTED) 95 | set(CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}") 96 | if(OpenMP_FLAG_DETECTED) 97 | set(OpenMP_CXX_FLAGS_INTERNAL "${FLAG}") 98 | break() 99 | endif(OpenMP_FLAG_DETECTED) 100 | endforeach(FLAG ${OpenMP_CXX_FLAG_CANDIDATES}) 101 | 102 | set(OpenMP_C_FLAGS "${OpenMP_C_FLAGS_INTERNAL}" 103 | CACHE STRING "C compiler flags for OpenMP parallization") 104 | 105 | set(OpenMP_CXX_FLAGS "${OpenMP_CXX_FLAGS_INTERNAL}" 106 | CACHE STRING "C++ compiler flags for OpenMP parallization") 107 | # handle the standard arguments for find_package 108 | find_package_handle_standard_args(OpenMP DEFAULT_MSG 109 | OpenMP_C_FLAGS OpenMP_CXX_FLAGS ) 110 | 111 | mark_as_advanced( 112 | OpenMP_C_FLAGS 113 | OpenMP_CXX_FLAGS 114 | ) 115 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8) 2 | project( akaze ) 3 | set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake) 4 | 5 | OPTION(OPENMP "Enable multithreading (requires OpenMP)" ON) 6 | 7 | # Where to output binaries and libraries 8 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/lib") 9 | set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/lib") 10 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin") 11 | 12 | FIND_PACKAGE(Eigen REQUIRED) 13 | INCLUDE_DIRECTORIES(${EIGEN_INCLUDE_DIRS}) 14 | IF (EIGEN_FOUND) 15 | MESSAGE("-- Found Eigen version ${EIGEN_VERSION}: ${EIGEN_INCLUDE_DIRS}") 16 | ENDIF (EIGEN_FOUND) 17 | 18 | # CImg is needed for reading/displaying the images. 19 | ADD_SUBDIRECTORY(cimg) 20 | ADD_SUBDIRECTORY(timer) 21 | INCLUDE_DIRECTORIES(${cimg_INCLUDE_DIR} ${timer_INCLUDE_DIR} ./) 22 | 23 | # Use a larger inlining threshold for Clang, since it hobbles Eigen, 24 | # resulting in an unreasonably slow version of the blas routines. The 25 | # -Qunused-arguments is needed because CMake passes the inline 26 | # threshold to the linker and clang complains about it and dies. 27 | IF (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") 28 | SET(CMAKE_CXX_FLAGS 29 | "${CMAKE_CXX_FLAGS} -Qunused-arguments -mllvm -inline-threshold=600") 30 | # Older versions of Clang (<= 2.9) do not support the 'return-type-c-linkage' 31 | # option, so check for its presence before adding it to the default flags set. 32 | INCLUDE(CheckCXXCompilerFlag) 33 | CHECK_CXX_COMPILER_FLAG("-Wno-return-type-c-linkage" 34 | HAVE_RETURN_TYPE_C_LINKAGE) 35 | IF (HAVE_RETURN_TYPE_C_LINKAGE) 36 | SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-return-type-c-linkage") 37 | ENDIF(HAVE_RETURN_TYPE_C_LINKAGE) 38 | ENDIF () 39 | 40 | IF (OPENMP) 41 | # Clang does not (yet) support OpenMP. 42 | IF (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") 43 | # Retain the help string associated with the OPENMP option 44 | # when updating it to disable use of OPENMP. 45 | GET_PROPERTY(HELP_STRING CACHE OPENMP PROPERTY HELPSTRING) 46 | SET(OPENMP OFF CACHE BOOL "${HELP_STRING}" FORCE) 47 | MESSAGE("-- Compiler is Clang, disabling OpenMP.") 48 | ELSE (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") 49 | # Find quietly s/t as we can continue without OpenMP if it is not found. 50 | FIND_PACKAGE(OpenMP QUIET) 51 | IF (OPENMP_FOUND) 52 | MESSAGE("-- Building with OpenMP.") 53 | ADD_DEFINITIONS(-DAKAZE_USE_OPENMP) 54 | SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") 55 | IF (UNIX) 56 | # At least on Linux, we need pthreads to be enabled for mutex to 57 | # compile. This may not work on Windows or Android. 58 | FIND_PACKAGE(Threads REQUIRED) 59 | SET(STATIC_LIBRARY_FLAGS 60 | "${STATIC_LIBRARY_FLAGS} ${CMAKE_THREAD_LIBS_INIT}") 61 | SET(CMAKE_SHARED_LINKER_FLAGS 62 | "${CMAKE_SHARED_LINKER_FLAGS} ${CMAKE_THREAD_LIBS_INIT}") 63 | ENDIF (UNIX) 64 | ELSE (OPENMP_FOUND) 65 | MESSAGE("-- Failed to find OpenMP, disabling.") 66 | # Retain the help string associated with the OPENMP option 67 | # when updating it to disable use of OPENMP. 68 | GET_PROPERTY(HELP_STRING CACHE OPENMP PROPERTY HELPSTRING) 69 | SET(OPENMP OFF CACHE BOOL "${HELP_STRING}" FORCE) 70 | ENDIF (OPENMP_FOUND) 71 | ENDIF (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") 72 | ELSE (OPENMP) 73 | MESSAGE("-- Building without OpenMP.") 74 | ENDIF (OPENMP) 75 | 76 | Include("${CMAKE_MODULE_PATH}/OptimizeCompilerFlags.cmake") 77 | OptimizeCompilerFlags() 78 | 79 | # Support for Debug mode. 80 | IF (CMAKE_BUILD_TYPE STREQUAL "Debug") 81 | MESSAGE("========== Warning: Compiling with Debug mode ==========") 82 | ENDIF (CMAKE_BUILD_TYPE STREQUAL "Debug") 83 | 84 | mark_as_advanced( 85 | Gperftools_ROOT_DIR 86 | GPERFTOOLS_TCMALLOC 87 | GPERFTOOLS_PROFILER 88 | GPERFTOOLS_TCMALLOC_AND_PROFILER 89 | GPERFTOOLS_LIBRARIES 90 | GPERFTOOLS_INCLUDE_DIR) 91 | 92 | SET(AKAZE_SRCS 93 | src/AKAZE.cpp 94 | src/convolution.cpp 95 | src/fed.cpp 96 | src/nldiffusion_functions.cpp 97 | src/utils.cpp) 98 | ADD_LIBRARY(akaze ${AKAZE_SRCS}) 99 | TARGET_LINK_LIBRARIES(akaze ${EIGEN_LIBRARIES} ${CIMG_LIBRARIES} timer) 100 | 101 | # Demo program extracting akaze features. 102 | ADD_EXECUTABLE(akaze_features akaze_features.cpp) 103 | TARGET_LINK_LIBRARIES(akaze_features akaze ${CIMG_LIBRARIES}) 104 | 105 | # Demo program matching akaze features. 106 | ADD_EXECUTABLE(akaze_match akaze_match.cpp) 107 | TARGET_LINK_LIBRARIES(akaze_match akaze ${CIMG_LIBRARIES}) 108 | -------------------------------------------------------------------------------- /src/fed.cpp: -------------------------------------------------------------------------------- 1 | //============================================================================= 2 | // 3 | // fed.cpp 4 | // Authors: Pablo F. Alcantarilla (1), Jesus Nuevo (2) 5 | // Institutions: Toshiba Research Europe Ltd (1) 6 | // TrueVision Solutions (2) 7 | // Date: 07/10/2014 8 | // Email: pablofdezalc@gmail.com 9 | // 10 | // AKAZE Features Copyright 2014, Pablo F. Alcantarilla, Jesus Nuevo 11 | // All Rights Reserved 12 | // See LICENSE for the license information 13 | //============================================================================= 14 | 15 | /** 16 | * @file fed.cpp 17 | * @brief Functions for performing Fast Explicit Diffusion and building the 18 | * nonlinear scale space 19 | * @date Oct 07, 2014 20 | * @author Pablo F. Alcantarilla, Jesus Nuevo 21 | * @note This code is derived from FED/FJ library from Grewenig et al., 22 | * The FED/FJ library allows solving more advanced problems 23 | * Please look at the following papers for more information about FED: 24 | * [1] S. Grewenig, J. Weickert, C. Schroers, A. Bruhn. Cyclic Schemes for 25 | * PDE-Based Image Analysis. Technical Report No. 327, Department of 26 | * Mathematics, 27 | * Saarland University, Saarbrücken, Germany, March 2013 28 | * [2] S. Grewenig, J. Weickert, A. Bruhn. From box filtering to fast explicit 29 | * diffusion. 30 | * DAGM, 2010 31 | * 32 | */ 33 | 34 | #define _USE_MATH_DEFINES 35 | #include "fed.h" 36 | 37 | // System 38 | #include 39 | #include 40 | 41 | namespace libAKAZE { 42 | 43 | /* ************************************************************************* */ 44 | int fed_tau_by_process_time(const float T, const int M, const float tau_max, 45 | const bool reordering, std::vector& tau) { 46 | // All cycles have the same fraction of the stopping time 47 | return fed_tau_by_cycle_time(T / (float) M, tau_max, reordering, tau); 48 | } 49 | 50 | /* ************************************************************************* */ 51 | int fed_tau_by_cycle_time(const float t, const float tau_max, 52 | const bool reordering, std::vector& tau) { 53 | 54 | int n = 0; // Number of time steps 55 | float scale = 0.0; // Ratio of t we search to maximal t 56 | 57 | // Compute necessary number of time steps 58 | n = (int)(ceil(sqrt(3.0 * t / tau_max + 0.25f) - 0.5f - 1.0e-8f) + 0.5f); 59 | scale = 3.0 * t / (tau_max * (float)(n * (n + 1))); 60 | 61 | // Call internal FED time step creation routine 62 | return fed_tau_internal(n, scale, tau_max, reordering, tau); 63 | } 64 | 65 | /* ************************************************************************* */ 66 | int fed_tau_internal(const int n, const float scale, const float tau_max, 67 | const bool reordering, std::vector& tau) { 68 | // Time savers 69 | float c = 0.0, d = 0.0; 70 | // Helper vector for unsorted taus 71 | std::vector tauh; 72 | 73 | if (n <= 0) return 0; 74 | 75 | // Allocate memory for the time step size 76 | tau = std::vector(n); 77 | 78 | if (reordering) tauh = std::vector(n); 79 | 80 | // Compute time saver 81 | c = 1.0f / (4.0f * (float) n + 2.0f); 82 | d = scale * tau_max / 2.0f; 83 | 84 | // Set up originally ordered tau vector 85 | for (int k = 0; k < n; ++k) { 86 | float h = cos(M_PI * (2.0f * (float) k + 1.0f) * c); 87 | 88 | if (reordering) 89 | tauh[k] = d / (h * h); 90 | else 91 | tau[k] = d / (h * h); 92 | } 93 | 94 | // Permute list of time steps according to chosen reordering function 95 | int kappa = 0, prime = 0; 96 | 97 | if (reordering == true) { 98 | // Choose kappa cycle with k = n/2 99 | // This is a heuristic. We can use Leja ordering instead!! 100 | kappa = n / 2; 101 | 102 | // Get modulus for permutation 103 | prime = n + 1; 104 | 105 | while (!fed_is_prime_internal(prime)) { 106 | prime++; 107 | } 108 | 109 | // Perform permutation 110 | for (int k = 0, l = 0; l < n; ++k, ++l) { 111 | int index = 0; 112 | while ((index = ((k + 1) * kappa) % prime - 1) >= n) { 113 | k++; 114 | } 115 | 116 | tau[l] = tauh[index]; 117 | } 118 | } 119 | 120 | return n; 121 | } 122 | 123 | /* ************************************************************************* */ 124 | bool fed_is_prime_internal(const int number) { 125 | 126 | if (number <= 1) { 127 | return false; 128 | } else if (number == 2 || number == 3 || number == 5 || number == 7) { 129 | return true; 130 | } else if ((number % 2) == 0 || (number % 3) == 0 || (number % 5) == 0 || 131 | (number % 7) == 0) { 132 | return false; 133 | } else { 134 | int upperLimit = sqrt(number + 1.0); 135 | int divisor = 11; 136 | 137 | while (divisor <= upperLimit) { 138 | if (number % divisor == 0) { 139 | return false; 140 | } 141 | 142 | divisor += 2; 143 | } 144 | 145 | return true; 146 | } 147 | } 148 | 149 | } // namespace libAKAZE 150 | -------------------------------------------------------------------------------- /src/utils.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file utils.h 3 | * @brief Some utilities functions 4 | * @date Oct 07, 2014 5 | * @author Pablo F. Alcantarilla, Jesus Nuevo 6 | */ 7 | 8 | #ifndef AKAZE_UTILS_H_ 9 | #define AKAZE_UTILS_H_ 10 | 11 | /* ************************************************************************* */ 12 | #include "cimg/CImg.h" 13 | #include "src/AKAZE.h" 14 | 15 | // System 16 | #include 17 | #include 18 | #include 19 | 20 | /* ************************************************************************* */ 21 | // Stringify common types such as int, double and others. 22 | template inline std::string to_string(const T& x) { 23 | std::stringstream oss; 24 | oss << x; 25 | return oss.str(); 26 | } 27 | 28 | // Stringify and format integral types as follows: 29 | // to_formatted_string( 1, 2) produces string: '01' 30 | // to_formatted_string( 5, 2) produces string: '05' 31 | // to_formatted_string( 19, 2) produces string: '19' 32 | // to_formatted_string( 19, 3) produces string: '019' 33 | template 34 | inline std::string to_formatted_string(Integer x, int num_digits) { 35 | std::stringstream oss; 36 | oss << std::setfill('0') << std::setw(num_digits) << x; 37 | return oss.str(); 38 | } 39 | 40 | /* ************************************************************************* */ 41 | 42 | // Converts to a CImg type and adjusts the scale for image displaying. 43 | void ConvertEigenToCImg(const RowMatrixXf& mat, 44 | cimg_library::CImg& cimg); 45 | 46 | /* ************************************************************************* */ 47 | 48 | // Converts a CImg object to a grayscale floating point Eigen matrix. 49 | void ConvertCImgToEigen(const cimg_library::CImg& image, 50 | RowMatrixXf& eigen_image); 51 | 52 | /* ************************************************************************* */ 53 | // This function matches the descriptors from floating point AKAZE methods using 54 | // L2 distance and the nearest neighbor distance ratio (Lowes ratio) 55 | void match_features(const std::vector& desc1, 56 | const std::vector& desc2, 57 | const double ratio, 58 | std::vector >& matches); 59 | // This function matches the descriptors from binary AKAZE (MLDB) methods using 60 | // Hamming distance and the nearest neighbor distance ratio (Lowes ratio) 61 | void match_features(const std::vector& desc1, 62 | const std::vector& desc2, 63 | const double ratio, 64 | std::vector >& matches); 65 | 66 | /// This function computes the set of inliers given a ground truth homography 67 | /// @param kpts1 Keypoints from first image 68 | /// @param kpts2 Keypoints from second image 69 | /// @param matches Vector of putative matches 70 | /// @param inliers Vector of inliers 71 | /// @param H Ground truth homography matrix 3x3 72 | /// @param min_error The minimum pixelic error to accept an inlier 73 | void compute_inliers_homography( 74 | const std::vector& kpts1, 75 | const std::vector& kpts2, 76 | const std::vector >& matches, 77 | std::vector >& inliers, const Eigen::Matrix3f& H, 78 | float min_error); 79 | 80 | /// This function draws the list of detected keypoints 81 | void draw_keypoints(cimg_library::CImg& img, 82 | const std::vector& kpts); 83 | 84 | void draw_matches(cimg_library::CImg& image1, 85 | cimg_library::CImg& image2, 86 | const std::vector& kpts1, 87 | const std::vector& kpts2, 88 | const std::vector >& matches, 89 | cimg_library::CImg& matched_image); 90 | 91 | /// This function saves the interest points to a regular ASCII file 92 | /// @note The format is compatible with Mikolajczyk and Schmid evaluation 93 | /// @param outFile Name of the output file where the points will be stored 94 | /// @param kpts Vector of points of interest 95 | /// @param desc Matrix that contains the extracted descriptors 96 | /// @param save_desc Set to 1 if we want to save the descriptors 97 | int save_keypoints(const std::string& outFile, 98 | const std::vector& kpts, 99 | const std::vector& desc, 100 | bool save_desc); 101 | 102 | int save_keypoints(const std::string& outFile, 103 | const std::vector& kpts, 104 | const std::vector& desc, 105 | bool save_desc); 106 | 107 | /// Function for reading the ground truth homography from a txt file 108 | bool read_homography(const std::string& hFile, Eigen::Matrix3f& H1toN); 109 | 110 | /// This function shows the possible command line configuration options 111 | void show_input_options_help(int example); 112 | 113 | #endif // AKAZE_UTILS_H_ 114 | -------------------------------------------------------------------------------- /cimg/cmake-modules/FindOpenEXR.cmake: -------------------------------------------------------------------------------- 1 | # Try to find the OpenEXR libraries 2 | # This check defines: 3 | # 4 | # OPENEXR_FOUND - system has OpenEXR 5 | # OPENEXR_INCLUDE_DIR - OpenEXR include directory 6 | # OPENEXR_LIBRARIES - Libraries needed to use OpenEXR 7 | # 8 | # Copyright (c) 2006, Alexander Neundorf, 9 | # 10 | # Redistribution and use is allowed according to the terms of the BSD license. 11 | # For details see the accompanying COPYING-CMAKE-SCRIPTS file. 12 | 13 | 14 | if (OPENEXR_INCLUDE_DIR AND OPENEXR_LIBRARIES) 15 | # in cache already 16 | SET(OPENEXR_FOUND TRUE) 17 | 18 | else (OPENEXR_INCLUDE_DIR AND OPENEXR_LIBRARIES) 19 | IF (NOT WIN32 OR MINGW) 20 | # use pkg-config to get the directories and then use these values 21 | # in the FIND_PATH() and FIND_LIBRARY() calls 22 | INCLUDE(UsePkgConfig) 23 | 24 | PKGCONFIG(OpenEXR _OpenEXRIncDir _OpenEXRLinkDir _OpenEXRLinkFlags _OpenEXRCflags) 25 | ENDIF (NOT WIN32 OR MINGW) 26 | FIND_PATH(OPENEXR_INCLUDE_DIR ImfRgbaFile.h 27 | ${_OpenEXRIncDir} 28 | ${_OpenEXRIncDir}/OpenEXR/ 29 | /usr/include 30 | /usr/local/include 31 | ${SOURCE_BASE_DIR}/Deploy/include 32 | ) 33 | 34 | FIND_LIBRARY(OPENEXR_HALF_LIBRARY NAMES Half 35 | PATHS 36 | ${_OPENEXRLinkDir} 37 | ${SYSTEM_LIB_DIRS} 38 | ${SOURCE_BASE_DIR}/Deploy/lib/HuginRelease 39 | ${SOURCE_BASE_DIR}/Deploy/lib/Release 40 | ) 41 | 42 | FIND_LIBRARY(OPENEXR_IEX_LIBRARY 43 | NAMES Iex 44 | PATHS 45 | ${_OPENEXRLinkDir} 46 | ${SYSTEM_LIB_DIRS} 47 | ${SOURCE_BASE_DIR}/Deploy/lib/HuginRelease 48 | ${SOURCE_BASE_DIR}/Deploy/lib/Release 49 | ) 50 | 51 | FIND_LIBRARY(OPENEXR_ILMTHREAD_LIBRARY NAMES IlmThread 52 | PATHS 53 | ${_OPENEXRLinkDir} 54 | ${SYSTEM_LIB_DIRS} 55 | ${SOURCE_BASE_DIR}/Deploy/lib/HuginRelease 56 | ${SOURCE_BASE_DIR}/Deploy/lib/Release 57 | ) 58 | 59 | FIND_LIBRARY(OPENEXR_IMATH_LIBRARY NAMES Imath 60 | PATHS 61 | ${_OPENEXRLinkDir} 62 | ${SYSTEM_LIB_DIRS} 63 | ${SOURCE_BASE_DIR}/Deploy/lib/HuginRelease 64 | ${SOURCE_BASE_DIR}/Deploy/lib/Release 65 | ) 66 | 67 | 68 | FIND_LIBRARY(OPENEXR_ILMIMF_LIBRARY NAMES IlmImf 69 | PATHS 70 | ${_OPENEXRLinkDir} 71 | ${SYSTEM_LIB_DIRS} 72 | ${SOURCE_BASE_DIR}/Deploy/lib/HuginRelease 73 | ${SOURCE_BASE_DIR}/Deploy/lib/Release 74 | ) 75 | 76 | FIND_LIBRARY(OPENEXR_HALF_LIBRARY_DEBUG NAMES Half 77 | PATHS 78 | ${_OPENEXRLinkDir} 79 | ${SYSTEM_LIB_DIRS} 80 | ${SOURCE_BASE_DIR}/Deploy/lib/HuginDebug 81 | ${SOURCE_BASE_DIR}/Deploy/lib/Debug 82 | ) 83 | 84 | FIND_LIBRARY(OPENEXR_IEX_LIBRARY_DEBUG 85 | NAMES Iex 86 | PATHS 87 | ${_OPENEXRLinkDir} 88 | ${SYSTEM_LIB_DIRS} 89 | ${SOURCE_BASE_DIR}/Deploy/lib/HuginDebug 90 | ${SOURCE_BASE_DIR}/Deploy/lib/Debug 91 | ) 92 | 93 | FIND_LIBRARY(OPENEXR_ILMTHREAD_LIBRARY_DEBUG NAMES IlmThread 94 | PATHS 95 | ${_OPENEXRLinkDir} 96 | ${SYSTEM_LIB_DIRS} 97 | ${SOURCE_BASE_DIR}/Deploy/lib/HuginDebug 98 | ${SOURCE_BASE_DIR}/Deploy/lib/Debug 99 | ) 100 | 101 | FIND_LIBRARY(OPENEXR_IMATH_LIBRARY_DEBUG NAMES Imath 102 | PATHS 103 | ${_OPENEXRLinkDir} 104 | ${SYSTEM_LIB_DIRS} 105 | ${SOURCE_BASE_DIR}/Deploy/lib/HuginDebug 106 | ${SOURCE_BASE_DIR}/Deploy/lib/Debug 107 | ) 108 | 109 | FIND_LIBRARY(OPENEXR_ILMIMF_LIBRARY_DEBUG NAMES IlmImf 110 | PATHS 111 | ${_OPENEXRLinkDir} 112 | ${SYSTEM_LIB_DIRS} 113 | ${SOURCE_BASE_DIR}/Deploy/lib/HuginDebug 114 | ${SOURCE_BASE_DIR}/Deploy/lib/Debug 115 | ) 116 | 117 | 118 | if (OPENEXR_INCLUDE_DIR AND OPENEXR_IMATH_LIBRARY AND OPENEXR_ILMIMF_LIBRARY AND OPENEXR_IEX_LIBRARY AND OPENEXR_HALF_LIBRARY) 119 | set(OPENEXR_FOUND TRUE) 120 | if (OPENEXR_ILMTHREAD_LIBRARY) 121 | # set(OPENEXR_LIBRARIES ${OPENEXR_IMATH_LIBRARY} ${OPENEXR_ILMIMF_LIBRARY} ${OPENEXR_IEX_LIBRARY} ${OPENEXR_HALF_LIBRARY} ${OPENEXR_ILMTHREAD_LIBARY} CACHE STRING "The libraries needed to use OpenEXR") 122 | if (MSVC) 123 | set(OPENEXR_LIBRARIES optimized ${OPENEXR_IMATH_LIBRARY} optimized ${OPENEXR_ILMIMF_LIBRARY} optimized ${OPENEXR_IEX_LIBRARY} optimized ${OPENEXR_HALF_LIBRARY} optimized ${OPENEXR_ILMTHREAD_LIBRARY} debug ${OPENEXR_IMATH_LIBRARY_DEBUG} debug ${OPENEXR_ILMIMF_LIBRARY_DEBUG} debug ${OPENEXR_IEX_LIBRARY_DEBUG} debug ${OPENEXR_HALF_LIBRARY_DEBUG} debug ${OPENEXR_ILMTHREAD_LIBRARY_DEBUG} CACHE STRING "Libraries needed for OpenEXR") 124 | else (MSVC) 125 | set(OPENEXR_LIBRARIES ${OPENEXR_IMATH_LIBRARY} ${OPENEXR_ILMIMF_LIBRARY} ${OPENEXR_IEX_LIBRARY} ${OPENEXR_HALF_LIBRARY} ${OPENEXR_ILMTHREAD_LIBRARY}) 126 | endif (MSVC) 127 | else (OPENEXR_ILMTHREAD_LIBRARY) 128 | if (MSVC) 129 | set(OPENEXR_LIBRARIES optimized ${OPENEXR_IMATH_LIBRARY} optimized ${OPENEXR_ILMIMF_LIBRARY} optimized ${OPENEXR_IEX_LIBRARY} optimized ${OPENEXR_HALF_LIBRARY} debug ${OPENEXR_IMATH_LIBRARY_DEBUG} debug ${OPENEXR_ILMIMF_LIBRARY_DEBUG} debug ${OPENEXR_IEX_LIBRARY_DEBUG} debug ${OPENEXR_HALF_LIBRARY_DEBUG} CACHE STRING "The libraries needed to use OpenEXR") 130 | else (MSVC) 131 | set(OPENEXR_LIBRARIES ${OPENEXR_IMATH_LIBRARY} ${OPENEXR_ILMIMF_LIBRARY} ${OPENEXR_IEX_LIBRARY} ${OPENEXR_HALF_LIBRARY} CACHE STRING "The libraries needed to use OpenEXR") 132 | endif (MSVC) 133 | endif (OPENEXR_ILMTHREAD_LIBRARY) 134 | endif (OPENEXR_INCLUDE_DIR AND OPENEXR_IMATH_LIBRARY AND OPENEXR_ILMIMF_LIBRARY AND OPENEXR_IEX_LIBRARY AND OPENEXR_HALF_LIBRARY) 135 | 136 | 137 | 138 | if (OPENEXR_FOUND) 139 | if (NOT OpenEXR_FIND_QUIETLY) 140 | message(STATUS "Found OPENEXR: ${OPENEXR_LIBRARIES}") 141 | endif (NOT OpenEXR_FIND_QUIETLY) 142 | else (OPENEXR_FOUND) 143 | if (OpenEXR_FIND_REQUIRED) 144 | message(FATAL_ERROR "Could NOT find OPENEXR") 145 | endif (OpenEXR_FIND_REQUIRED) 146 | endif (OPENEXR_FOUND) 147 | 148 | MARK_AS_ADVANCED( 149 | OPENEXR_INCLUDE_DIR 150 | OPENEXR_LIBRARIES 151 | OPENEXR_ILMIMF_LIBRARY 152 | OPENEXR_IMATH_LIBRARY 153 | OPENEXR_IEX_LIBRARY 154 | OPENEXR_HALF_LIBRARY 155 | OPENEXR_ILMTHREAD_LIBRARY ) 156 | 157 | endif (OPENEXR_INCLUDE_DIR AND OPENEXR_LIBRARIES) 158 | -------------------------------------------------------------------------------- /src/nldiffusion_functions.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file nldiffusion_functions.h 3 | * @brief Functions for nonlinear diffusion filtering applications 4 | * @date Oct 07, 2014 5 | * @author Pablo F. Alcantarilla, Jesus Nuevo 6 | */ 7 | 8 | #ifndef AKAZE_SRC_NLDIFFUSION_FUCTIONS_H_ 9 | #define AKAZE_SRC_NLDIFFUSION_FUCTIONS_H_ 10 | 11 | /* ************************************************************************* */ 12 | #include 13 | 14 | typedef Eigen::Matrix 15 | RowMatrixXf; 16 | 17 | namespace libAKAZE { 18 | 19 | /* ************************************************************************* */ 20 | /// Convolve an image with a 2D Gaussian kernel 21 | void gaussian_2D_convolution(const RowMatrixXf& src, RowMatrixXf& dst, 22 | size_t ksize_x, size_t ksize_y, float sigma); 23 | 24 | /// This function computes image derivatives with Scharr kernel 25 | /// @param src Input image 26 | /// @param dst Output image 27 | /// @param xorder Derivative order in X-direction (horizontal) 28 | /// @param yorder Derivative order in Y-direction (vertical) 29 | /// @note Scharr operator approximates better rotation invariance than 30 | /// other stencils such as Sobel. See Weickert and Scharr, 31 | /// A Scheme for Coherence-Enhancing Diffusion Filtering with Optimized Rotation 32 | /// Invariance, 33 | /// Journal of Visual Communication and Image Representation 2002 34 | void image_derivatives_scharr(const RowMatrixXf& src, RowMatrixXf& dst, 35 | const size_t xorder, const size_t yorder); 36 | 37 | /// This function computes the Perona and Malik conductivity coefficient g1 38 | /// g1 = exp(-|dL|^2/k^2) 39 | /// @param Lx First order image derivative in X-direction (horizontal) 40 | /// @param Ly First order image derivative in Y-direction (vertical) 41 | /// @param dst Output image 42 | /// @param k Contrast factor parameter 43 | void pm_g1(const RowMatrixXf& Lx, const RowMatrixXf& Ly, RowMatrixXf& dst, 44 | const float k); 45 | 46 | /// This function computes the Perona and Malik conductivity coefficient g2 47 | /// g2 = 1 / (1 + dL^2 / k^2) 48 | /// @param Lx First order image derivative in X-direction (horizontal) 49 | /// @param Ly First order image derivative in Y-direction (vertical) 50 | /// @param dst Output image 51 | /// @param k Contrast factor parameter 52 | void pm_g2(const RowMatrixXf& Lx, const RowMatrixXf& Ly, RowMatrixXf& dst, 53 | const float k); 54 | 55 | /// This function computes Weickert conductivity coefficient gw 56 | /// @param Lx First order image derivative in X-direction (horizontal) 57 | /// @param Ly First order image derivative in Y-direction (vertical) 58 | /// @param dst Output image 59 | /// @param k Contrast factor parameter 60 | /// @note For more information check the following paper: J. Weickert 61 | /// Applications of nonlinear diffusion in image processing and computer vision, 62 | /// Proceedings of Algorithmy 2000 63 | void weickert_diffusivity(const RowMatrixXf& Lx, const RowMatrixXf& Ly, 64 | RowMatrixXf& dst, const float k); 65 | 66 | /// This function computes Charbonnier conductivity coefficient gc 67 | /// gc = 1 / sqrt(1 + dL^2 / k^2) 68 | /// @param Lx First order image derivative in X-direction (horizontal) 69 | /// @param Ly First order image derivative in Y-direction (vertical) 70 | /// @param dst Output image 71 | /// @param k Contrast factor parameter 72 | /// @note For more information check the following paper: J. Weickert 73 | /// Applications of nonlinear diffusion in image processing and computer vision, 74 | /// Proceedings of Algorithmy 2000 75 | void charbonnier_diffusivity(const RowMatrixXf& Lx, const RowMatrixXf& Ly, 76 | RowMatrixXf& dst, const float k); 77 | 78 | /// This function computes a good empirical value for the k contrast factor 79 | /// given an input image, the percentile (0-1), the gradient scale and the 80 | /// number of bins in the histogram 81 | /// @param img Input image 82 | /// @param perc Percentile of the image gradient histogram (0-1) 83 | /// @param gscale Scale for computing the image gradient histogram 84 | /// @param nbins Number of histogram bins 85 | /// @param ksize_x Kernel size in X-direction (horizontal) for the Gaussian 86 | /// smoothing kernel 87 | /// @param ksize_y Kernel size in Y-direction (vertical) for the Gaussian 88 | /// smoothing kernel 89 | /// @return k contrast factor 90 | float compute_k_percentile(const RowMatrixXf& img, float perc, float gscale, 91 | size_t nbins, size_t ksize_x, size_t ksize_y); 92 | 93 | /// This function computes Scharr image derivatives 94 | /// @param src Input image 95 | /// @param dst Output image 96 | /// @param xorder Derivative order in X-direction (horizontal) 97 | /// @param yorder Derivative order in Y-direction (vertical) 98 | /// @param scale Scale factor for the derivative size 99 | void compute_scharr_derivatives(const RowMatrixXf& src, 100 | RowMatrixXf& dst, 101 | const size_t xorder, const size_t yorder, 102 | const size_t scale); 103 | 104 | /// This function performs a scalar non-linear diffusion step 105 | /// @param Ld Output image in the evolution 106 | /// @param c Conductivity image 107 | /// @param Lstep Previous image in the evolution 108 | /// @param stepsize The step size in time units 109 | /// @note Forward Euler Scheme 3x3 stencil 110 | /// The function c is a scalar value that depends on the gradient norm 111 | /// dL_by_ds = d(c dL_by_dx)_by_dx + d(c dL_by_dy)_by_dy 112 | void nld_step_scalar(RowMatrixXf& Ld, const RowMatrixXf& c, RowMatrixXf& Lstep, 113 | const float stepsize); 114 | 115 | /// This function downsamples the input image using OpenCV resize 116 | /// @param img Input image to be downsampled 117 | /// @param dst Output image with half of the resolution of the input image 118 | void halfsample_image(const RowMatrixXf& src, RowMatrixXf& dst); 119 | 120 | bool check_maximum_neighbourhood(const RowMatrixXf& img, int dsize, float value, 121 | int row, int col, bool same_img); 122 | 123 | } // namespace libAKAZE 124 | 125 | #endif // AKAZE_SRC_NLDIFFUSION_FUCTIONS_H_ 126 | -------------------------------------------------------------------------------- /cimg/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # CMakeFiles.txt for CImg 2 | # 3 | # Haz-Edine Assemlal 4 | 5 | CMAKE_MINIMUM_REQUIRED(VERSION 2.8.0) 6 | 7 | set(CIMG_PACKAGE_VERSION_MAJOR 1) 8 | set(CIMG_PACKAGE_VERSION_MINOR 5) 9 | set(CIMG_PACKAGE_VERSION_PATCH 0) 10 | 11 | # register local modules 12 | SET(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}" "${CMAKE_SOURCE_DIR}/cmake-modules") 13 | 14 | PROJECT(cimg) 15 | 16 | # Packaging defines 17 | set(CPACK_GENERATOR TGZ) 18 | set(CPACK_PACKAGE_VERSION_MAJOR ${CIMG_PACKAGE_VERSION_MAJOR}) 19 | set(CPACK_PACKAGE_VERSION_MINOR ${CIMG_PACKAGE_VERSION_MINOR}) 20 | set(CPACK_PACKAGE_VERSION_PATCH ${CIMG_PACKAGE_VERSION_PATCH}) 21 | include(CPack) 22 | 23 | set(PACKAGE "CImg") 24 | set(PACKAGE_BUGREPORT "david.tschumperle@greyc.ensicaen.fr") 25 | set(PACKAGE_NAME "CImg") 26 | set(PACKAGE_VERSION "${CIMG_PACKAGE_VERSION_MAJOR}.${CIMG_PACKAGE_VERSION_MINOR}.${CIMG_PACKAGE_VERSION_PATCH}") 27 | set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") 28 | 29 | 30 | option(BUILD_GIMP "Build GIMP plug-ins" OFF) 31 | option(BUILD_GMIC "Build GMIC" OFF) 32 | option(WITH_VT100 "Enable color output messages " ON) 33 | option(WITH_CIMG_DISPLAY "Use CImg display capabilities" OFF) 34 | option(WITH_OPENMP "Use OpenMP parallel core instructions" ON) 35 | option(WITH_XRANDR "Use XRandR library" OFF) 36 | option(WITH_PNG "Use PNG library" OFF) 37 | option(WITH_JPEG "Use JPEG library" ON) 38 | option(WITH_TIFF "Use TIFF library" OFF) 39 | option(WITH_ZLIB "Use Zlib library" OFF) 40 | option(WITH_MAGICK "Use Magick library" OFF) 41 | option(WITH_LAPACK "Use LAPACK library" OFF) 42 | 43 | if(WITH_VT100) 44 | add_definitions(-Dcimg_use_vt100) 45 | endif(WITH_VT100) 46 | 47 | if( WITH_CIMG_DISPLAY ) 48 | if(UNIX OR APPLE) 49 | if( CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)" ) 50 | list( APPEND DEPENDENCIES_LIBRARIES "-R$(X11PATH)/lib -lrt -lnsl -lsocket" ) 51 | else() 52 | find_package( X11 REQUIRED ) 53 | include_directories( ${X11_INCLUDE_DIR} ) 54 | list( APPEND DEPENDENCIES_LIBRARIES ${X11_LIBRARIES} ) 55 | endif() 56 | elseif(WIN32) 57 | set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mwindows" ) 58 | list( APPEND DEPENDENCIES_LIBRARIES "-lgdi32" ) 59 | endif() 60 | else(WITH_CIMG_DISPLAY) 61 | add_definitions(-Dcimg_display=0) 62 | endif(WITH_CIMG_DISPLAY) 63 | 64 | IF (WITH_OPENMP) 65 | # Clang does not (yet) support OpenMP. 66 | IF (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") 67 | # Retain the help string associated with the OPENMP option 68 | # when updating it to disable use of OPENMP. 69 | GET_PROPERTY(HELP_STRING CACHE OPENMP PROPERTY HELPSTRING) 70 | SET(OPENMP OFF CACHE BOOL "${HELP_STRING}" FORCE) 71 | MESSAGE("-- Compiler is Clang, disabling OpenMP.") 72 | ELSE (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") 73 | # Find quietly s/t as we can continue without OpenMP if it is not found. 74 | FIND_PACKAGE(OpenMP QUIET) 75 | IF (OPENMP_FOUND) 76 | MESSAGE("-- Building with OpenMP.") 77 | ADD_DEFINITIONS(-Dcimg_use_openmp) 78 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") 79 | SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") 80 | IF (UNIX) 81 | # At least on Linux, we need pthreads to be enabled for mutex to 82 | # compile. This may not work on Windows or Android. 83 | FIND_PACKAGE(Threads REQUIRED) 84 | SET(STATIC_LIBRARY_FLAGS 85 | "${STATIC_LIBRARY_FLAGS} ${CMAKE_THREAD_LIBS_INIT}") 86 | SET(CMAKE_SHARED_LINKER_FLAGS 87 | "${CMAKE_SHARED_LINKER_FLAGS} ${CMAKE_THREAD_LIBS_INIT}") 88 | ENDIF (UNIX) 89 | ELSE (OPENMP_FOUND) 90 | MESSAGE("-- Failed to find OpenMP, disabling.") 91 | # Retain the help string associated with the OPENMP option 92 | # when updating it to disable use of OPENMP. 93 | GET_PROPERTY(HELP_STRING CACHE OPENMP PROPERTY HELPSTRING) 94 | SET(OPENMP OFF CACHE BOOL "${HELP_STRING}" FORCE) 95 | ENDIF (OPENMP_FOUND) 96 | ENDIF (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") 97 | ELSE (WITH_OPENMP) 98 | MESSAGE("-- Building without OpenMP.") 99 | ENDIF (WITH_OPENMP) 100 | 101 | if(WITH_XRANDR) 102 | if(NOT X11_Xrandr_INCLUDE_PATH) 103 | message(FATAL_ERROR "Failed to find X11 XrandR which is required") 104 | endif(NOT X11_Xrandr_INCLUDE_PATH) 105 | endif(WITH_XRANDR) 106 | 107 | if(WITH_PNG) 108 | find_package( PNG REQUIRED ) 109 | add_definitions(-Dcimg_use_png ${PNG_DEFINITIONS}) 110 | include_directories( ${PNG_INCLUDE_DIRS} ) 111 | list( APPEND DEPENDENCIES_LIBRARIES ${PNG_LIBRARIES} ) 112 | endif(WITH_PNG) 113 | 114 | if(WITH_JPEG) 115 | find_package( JPEG REQUIRED ) 116 | add_definitions( -Dcimg_use_jpeg ) 117 | include_directories( ${JPEG_INCLUDE_DIR} ) 118 | list( APPEND DEPENDENCIES_LIBRARIES ${JPEG_LIBRARIES} ) 119 | endif(WITH_JPEG) 120 | 121 | if(WITH_TIFF) 122 | find_package( TIFF REQUIRED ) 123 | add_definitions( -Dcimg_use_tiff ) 124 | include_directories( ${TIFF_INCLUDE_DIR} ) 125 | list( APPEND DEPENDENCIES_LIBRARIES ${TIFF_LIBRARIES} ) 126 | endif(WITH_TIFF) 127 | 128 | if(WITH_ZLIB) 129 | find_package( ZLIB REQUIRED ) 130 | add_definitions( -Dcimg_use_zlib ) 131 | include_directories( ${ZLIB_INCLUDE_DIR} ) 132 | list( APPEND DEPENDENCIES_LIBRARIES ${ZLIB_LIBRARIES} ) 133 | endif(WITH_ZLIB) 134 | 135 | if(WITH_MAGICK) 136 | find_package( ImageMagick QUIET COMPONENTS Magick++ convert) 137 | IF (ImageMagick_FOUND) 138 | add_definitions( -Dcimg_use_magick ) 139 | include_directories( ${ImageMagick_INCLUDE_DIRS} ) 140 | list( APPEND DEPENDENCIES_LIBRARIES ${ImageMagick_LIBRARIES} ) 141 | ELSE (ImageMagick_FOUND) 142 | MESSAGE("-- Failed to find ImageMagick, disabling.") 143 | ENDIF(ImageMagick_FOUND) 144 | endif(WITH_MAGICK) 145 | 146 | if(WITH_LAPACK) 147 | find_package( LAPACK QUIET ) 148 | IF (LAPACK_FOUND) 149 | add_definitions( -Dcimg_use_lapack ) 150 | include_directories( ${LAPACK_INCLUDE_DIRS} ) 151 | list( APPEND DEPENDENCIES_LIBRARIES ${LAPACK_LIBRARIES} ) 152 | ELSE (LAPACK_FOUND) 153 | MESSAGE("-- Failed to find Lapack, disabling.") 154 | ENDIF (LAPACK_FOUND) 155 | endif(WITH_LAPACK) 156 | 157 | if(WITH_BOARD) 158 | find_package( BOARD ) 159 | IF (BOARD_FOUND) 160 | add_definitions( -Dcimg_use_board ) 161 | include_directories( ${BOARD_INCLUDE_DIR} ) 162 | list( APPEND DEPENDENCIES_LIBRARIES ${BOARD_LIBRARIES} ) 163 | ELSE (BOARD_FOUND) 164 | MESSAGE("-- Failed to find Board library, disabling.") 165 | ENDIF (BOARD_FOUND) 166 | endif(WITH_BOARD) 167 | 168 | # aliases 169 | set(VERSION "${PACKAGE_VERSION}") 170 | include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ) 171 | set(CIMG_LIBRARIES ${DEPENDENCIES_LIBRARIES}) 172 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## README - A-KAZE Features 2 | 3 | This library is an implementation of the AKAZE feature detector and descriptor 4 | algorithms with the OpenCV dependency removed. This allows for more flexible use 5 | of the AKAZE features without requiring the large dependency of OpenCV. The only 6 | dependency for this library is the Eigen matrix library. We made made an effort 7 | to keep the code relatively in tact to the original implementation so that it 8 | would be easier to follow and compare. 9 | 10 | The major difference are: 11 | - everything is in the namespace libAKAZE 12 | - the keypoints and descriptors are a minimal, custom struct instead of OpenCV's structs 13 | - images are held in a row-major Eigen matrix with floating point pixels 14 | - the number of threads can be set at runtime 15 | 16 | In my experiments, this implementation is less than 1.5x slower than the OpenCV 17 | implementation. This is because OpenCV has many hand-written SIMD optimizations 18 | for image processing. However, this implementation does give the same keypoints 19 | and descriptors (within 0.1% error) as OpenCV. 20 | 21 | **NOTE:** If you have suggestions for how to improve performance (namely the image 22 | convolution and image half-sampling) please email me or make a pull request! 23 | 24 | I would also like to thank Pablo Alcantarilla and Pierre Moulon for help and encouragement in creating this fork of akaze. 25 | 26 | ## Contact Info 27 | 28 | If you have questions about this particular implementation, find a bug, or have an improvement suggested please email Chris Sweeney at cmsweeney@cs.ucsb.edu 29 | 30 | If you have questions about AKAZE, Pablo Alcantarilla (the primary author of the original work) would like to know! If you work in a research institution, university, company or you are a freelance and you are using KAZE or A-KAZE in your work, please send him an email!! Here is his contact information: 31 | 32 | Pablo F. Alcantarilla 33 | email: pablofdezalc@gmail.com 34 | 35 | ## Citation 36 | 37 | If you use this code as part of your work, please cite the following papers: 38 | 39 | 1. **Fast Explicit Diffusion for Accelerated Features in Nonlinear Scale Spaces**. Pablo F. Alcantarilla, J. Nuevo and Adrien Bartoli. _In British Machine Vision Conference (BMVC), Bristol, UK, September 2013_ 40 | 41 | 2. **KAZE Features**. Pablo F. Alcantarilla, Adrien Bartoli and Andrew J. Davison. _In European Conference on Computer Vision (ECCV), Fiorenze, Italy, October 2012_ 42 | 43 | The original AKAZE implementation is housed at: 44 | `https://github.com/pablofdezalc/akaze` 45 | 46 | ## Library Dependencies 47 | 48 | The code only relies on the Eigen matrix library (version 3.2.0 or higher) 49 | 50 | If you want to use OpenMP parallelization you will need to install OpenMP in your system 51 | In Linux you can do this by installing the gomp library 52 | 53 | Tested compilers: 54 | - GCC 4.8 55 | - Apple Clang 3.5 56 | 57 | Tested systems: 58 | - Ubuntu 14.04 59 | - Mac OS X Yosemite 60 | 61 | ## Getting Started 62 | 63 | Compiling: 64 | 65 | 1. `$ mkdir build` 66 | 2. `$ cd build>` 67 | 3. `$ cmake ..` 68 | 4. `$ make` 69 | 70 | If the compilation is successful you should see two executables in the folder bin: 71 | - `akaze_features` 72 | - `akaze_match` 73 | 74 | Additionally, the library `libAKAZE[.a, .lib]` will be created in the folder `lib`. 75 | 76 | If there is any error in the compilation, perhaps some libraries are missing. 77 | Please check the Library dependencies section. 78 | 79 | Examples: 80 | To see how the code works, examine the two examples provided. 81 | 82 | ## Computing A-KAZE Features 83 | 84 | For running the program you need to type in the command line the following arguments: 85 | `./akaze_features img.jpg [options]` 86 | 87 | The `[options]` are not mandatory. In case you do not specify additional options, default arguments will be 88 | used. Here is a description of the additional options: 89 | 90 | - `--verbose`: if verbosity is required 91 | - `--help`: for showing the command line options 92 | - `--num_threads`: number of threads AKAZE will use (default is 1) 93 | - `--soffset`: the base scale offset (sigma units) 94 | - `--omax`: the coarsest nonlinear scale space level (sigma units) 95 | - `--nsublevels`: number of sublevels per octave 96 | - `--diffusivity`: diffusivity function `0` -> Perona-Malik 1, `1` -> Perona-Malik 2, `2` -> Weickert 97 | - `--dthreshold`: Feature detector threshold response for accepting points 98 | - `--descriptor`: Descriptor Type, 0-> SURF_UPRIGHT, 1->SURF 99 | 2-> M-SURF_UPRIGHT, 3->M-SURF 100 | 4-> M-LDB_UPRIGHT, 5->M-LDB 101 | - `--descriptor_channels`: Descriptor Channels for M-LDB. Valid values: 1, 2 (intensity+gradient magnitude), 3(intensity + X and Y gradients) 102 | - `--show_results`: `1` in case we want to show detection results. `0` otherwise 103 | 104 | ## Important Things: 105 | 106 | * Check `AKAZEConfig.h` in case you would like to change the value of some default settings 107 | * The **k** constrast factor is computed as the 70% percentile of the gradient histogram of a 108 | smoothed version of the original image. Normally, this empirical value gives good results, but 109 | depending on the input image the diffusion will not be good enough. Therefore I highly 110 | recommend you to visualize the output images from save_scale_space and test with other k 111 | factors if the results are not satisfactory 112 | 113 | ## Image Matching Example with A-KAZE Features 114 | 115 | The code contains one program to perform image matching between two images. The 116 | ground truth homography files are given in the datasets directory and must be 117 | provided at runtime 118 | 119 | For running the program you need to type in the command line the following arguments: 120 | `./akaze_match img1.jpg img2.pgm homography.txt [options]` 121 | 122 | The `[options]` are not mandatory. In case you do not specify additional 123 | options, default arguments will be used. 124 | 125 | The datasets folder contains the **Iguazu** dataset described in the paper and 126 | additional datasets from Mikolajczyk et al. evaluation. The **Iguazu** dataset 127 | was generated by adding Gaussian noise of increasing standard deviation. 128 | 129 | For example, with the default configuration parameters used in the current code 130 | version you should get the following results: 131 | 132 | ``` 133 | ./akaze_match ../../datasets/iguazu/img1.pgm 134 | ../../datasets/iguazu/img4.pgm 135 | ../../datasets/iguazu/H1to4p 136 | --descriptor 4 137 | ``` 138 | 139 | ``` 140 | Number of Keypoints Image 1: 1823 141 | Number of Keypoints Image 2: 2373 142 | A-KAZE Features Extraction Time (ms): 304.796 143 | Matching Descriptors Time (ms): 54.1619 144 | Number of Matches: 1283 145 | Number of Inliers: 1047 146 | Number of Outliers: 236 147 | Inliers Ratio: 81.6056 148 | ``` 149 | -------------------------------------------------------------------------------- /cimg/README.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- 2 | -------------------------------------------------------------------------------- 3 | ____ _ _ ____ 4 | (_ _)( )_( )( ___) 5 | )( ) _ ( )__) 6 | (__) (_) (_)(____) 7 | ___ ____ __ __ ___ __ ____ ____ ____ __ ____ _ _ 8 | / __)(_ _)( \/ )/ __) ( ) (_ _)( _ \( _ \ /__\ ( _ \( \/ ) 9 | ( (__ _)(_ ) (( (_-. )(__ _)(_ ) _ < ) / /(__)\ ) / \ / 10 | \___)(____)(_/\/\_)\___/ (____)(____)(____/(_)\_)(__)(__)(_)\_) (__) 11 | 12 | 13 | C++ Template Image Processing Toolkit 14 | 15 | ( http://cimg.sourceforge.net ) 16 | 17 | 1.5.9 18 | 19 | -------------------------------------------------------------------------------- 20 | 21 | # Summary 22 | #--------- 23 | 24 | The CImg Library is an open-source C++ toolkit for image processing. 25 | It consists in a single header file 'CImg.h' providing a minimal set of C++ 26 | classes and methods that can be used in your own sources, to load/save, 27 | process and display images. Very portable (Unix/X11,Windows, MacOS X, FreeBSD, .. ), 28 | efficient, easy to use, it's a pleasant library for developping image processing 29 | algorithms in C++. 30 | 31 | # Authors and contributors : 32 | #---------------------------- 33 | 34 | - David Tschumperle (project leader) ( http://tschumperle.users.greyc.fr/ ) 35 | 36 | - Maksim Aizenshtein 37 | - Antonio Albiol 38 | - Haz-Edine Assemlal 39 | - Vincent Barra 40 | - Wolf Blecher 41 | - Romain Blei 42 | - Yohan Bentolila 43 | - Jerome Boulanger 44 | - Pierre Buyssens 45 | - Sebastien Coudert 46 | - Frederic Devernay 47 | - Olivier D'Hondt 48 | - Francois-Xavier Dupe 49 | - Gerd von Egidy 50 | - Eric Fausett 51 | - Jean-Marie Favreau 52 | - Sebastien Fourey 53 | - Alexandre Fournier 54 | - Hon-Kwok Fung 55 | - Vincent Garcia 56 | - David Grimbichler 57 | - Jinwei Gu 58 | - Jean-Daniel Guyot 59 | - Matt Hanson 60 | - Sebastien Hanel 61 | - Michael Holroyd 62 | - Christoph Hormann 63 | - Werner Jainek 64 | - Daniel Kondermann 65 | - Pierre Kornprobst 66 | - Orges Leka 67 | - Francois Lauze 68 | - Xie Long 69 | - Thomas Martin 70 | - Cesar Martinez 71 | - Jean Martinot 72 | - Arnold Meijster (Center for High Performance Computing and Visualization, University of Groningen/The Netherlands) 73 | - Nikita Melnichenko 74 | - Julien Morat 75 | - Baptiste Mougel 76 | - Jovana Milutinovich 77 | - Guillaume Nee 78 | - Adam Newgas 79 | - Francisco Oliveira 80 | - Andrea Onofri 81 | - Renaud Peteri 82 | - Martin Petricek 83 | - Paolo Prete 84 | - Adrien Reboisson 85 | - Klaus Schneider 86 | - Jakob Schluttig 87 | - Veronique Souchaud 88 | - Konstantin Spirin 89 | - David G. Starkweather 90 | - Rainer Steffens 91 | - Grzegorz Szwoch 92 | - Thierry Thomas 93 | - Yu-En-Yun 94 | - Vo Duc Khanh 95 | - Phillip Wood 96 | - Bug Zhao 97 | - Haibo Zheng 98 | 99 | # Institution 100 | #------------- 101 | 102 | GREYC Image / CNRS UMR 6072 / FRANCE 103 | 104 | The CImg Library project started in 2000, at the INRIA-Sophia 105 | Antipolis/France ( http://www-sop.inria.fr/ ), in the ROBOTVIS / ODYSSEE Team. 106 | Since October 2004, it is maintained and developed in the Image team of 107 | the GREYC Lab (CNRS, UMR 6072), in Caen/France. 108 | Team web page : http://www.greyc.ensicaen.fr/EquipeImage/ 109 | 110 | # Licenses 111 | #---------- 112 | 113 | The source code of the CImg Library is distributed under 114 | two distinct licenses : 115 | 116 | - The main library file 'CImg.h' is *dual-licensed* : 117 | It can be either distributed under the CeCILL-C or CeCILL license. 118 | (see files 'Licence_CeCILL-C_V1-en.txt' and 'Licence_CeCILL_V2-en.txt'). 119 | Both are Free-Software licenses : 120 | 121 | * CeCILL-C is adapted to the distribution of 122 | library components, and is close in its terms to the well known GNU LGPL license 123 | (the 'CImg.h' file can thus be used in closed-source products under certain 124 | conditions, please read carefully the license file). 125 | 126 | * CeCILL is close to (and even compatible with) the GNU GPL license. 127 | 128 | - Most of the other files are distributed under the CeCiLL license 129 | (file 'Licence_CeCILL_V2-en.txt'). See each file header to see what license applies. 130 | 131 | These two CeCiLL licenses ( http://www.cecill.info/index.en.html ) have been 132 | created under the supervision of the three biggest research institutions on 133 | computer sciences in France : 134 | 135 | - CNRS ( http://www.cnrs.fr/ ) 136 | - CEA ( http://www.cea.fr/ ) 137 | - INRIA ( http://www.inria.fr/ ) 138 | 139 | You have to RESPECT these licenses. More particularly, please carefully read 140 | the license terms before using the CImg library in commercial products. 141 | 142 | # Package structure : 143 | #-------------------- 144 | 145 | The main package directory CImg/ is organized as follows : 146 | 147 | - README.txt : This file. 148 | - Licence_CeCILL-C_V1-en.txt : A copy of the CeCiLL-C license file. 149 | - Licence_CeCILL_V2-en.txt : A copy of the CeCiLL license. 150 | - CImg.h : The single header file that constitutes the library itself. 151 | - examples/ : A directory containing a lot of example programs performing 152 | various things, using the CImg library. 153 | - html/ : A directory containing a copy of the CImg web page in html 154 | format. The reference documentation is generated 155 | automatically with the tool 'doxygen' (http://www.doxygen.org). 156 | - resources/ : A directory containing some resources files for compiling 157 | CImg examples or packages with various C++ compilers and OS. 158 | - plugins/ : A directory containing CImg plug-ins files that can be used to 159 | add specific extra functionalities to the CImg library. 160 | 161 | # Getting started 162 | #----------------- 163 | 164 | If you are new to CImg, you should first try to compile the different examples 165 | provided in the 'examples/' directory, to see what CImg is capable of 166 | (as CImg is a template-based library, no prior compilation of the library is mandatory). 167 | Look at the 'resources/' directory to ease this compilation on different plateforms. 168 | 169 | Then, you can look at the documentation 'html/reference/' to learn more about CImg 170 | functions and classes. Finally, you can participate to the 'Forum' section 171 | of the CImg web page and ask for help if needed. 172 | 173 | # End of file 174 | #------------ 175 | -------------------------------------------------------------------------------- /cimg/cmake-modules/FindOpenCV.cmake: -------------------------------------------------------------------------------- 1 | ########################################################### 2 | # Find OpenCV Library 3 | # See http://sourceforge.net/projects/opencvlibrary/ 4 | #---------------------------------------------------------- 5 | # 6 | ## 1: Setup: 7 | # The following variables are optionally searched for defaults 8 | # OpenCV_DIR: Base directory of OpenCv tree to use. 9 | # 10 | ## 2: Variable 11 | # The following are set after configuration is done: 12 | # 13 | # OpenCV_FOUND 14 | # OpenCV_LIBS 15 | # OpenCV_INCLUDE_DIR 16 | # OpenCV_VERSION (OpenCV_VERSION_MAJOR, OpenCV_VERSION_MINOR, OpenCV_VERSION_PATCH) 17 | # 18 | # 19 | # Deprecated variable are used to maintain backward compatibility with 20 | # the script of Jan Woetzel (2006/09): www.mip.informatik.uni-kiel.de/~jw 21 | # OpenCV_INCLUDE_DIRS 22 | # OpenCV_LIBRARIES 23 | # OpenCV_LINK_DIRECTORIES 24 | # 25 | ## 3: Version 26 | # 27 | # 2010/04/07 Benoit Rat, Correct a bug when OpenCVConfig.cmake is not found. 28 | # 2010/03/24 Benoit Rat, Add compatibility for when OpenCVConfig.cmake is not found. 29 | # 2010/03/22 Benoit Rat, Creation of the script. 30 | # 31 | # 32 | # tested with: 33 | # - OpenCV 2.1: MinGW, MSVC2008 34 | # - OpenCV 2.0: MinGW, MSVC2008, GCC4 35 | # 36 | # 37 | ## 4: Licence: 38 | # 39 | # LGPL 2.1 : GNU Lesser General Public License Usage 40 | # Alternatively, this file may be used under the terms of the GNU Lesser 41 | 42 | # General Public License version 2.1 as published by the Free Software 43 | # Foundation and appearing in the file LICENSE.LGPL included in the 44 | # packaging of this file. Please review the following information to 45 | # ensure the GNU Lesser General Public License version 2.1 requirements 46 | # will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 47 | # 48 | #---------------------------------------------------------- 49 | 50 | 51 | find_path(OpenCV_DIR "OpenCVConfig.cmake" DOC "Root directory of OpenCV") 52 | 53 | if(NOT "${OpenCV_DIR}") 54 | set(OpenCV_DIR "/usr") 55 | endif(NOT "${OpenCV_DIR}") 56 | 57 | ##==================================================== 58 | ## Find OpenCV libraries 59 | ##---------------------------------------------------- 60 | if(EXISTS "${OpenCV_DIR}") 61 | 62 | #When its possible to use the Config script use it. 63 | if(EXISTS "${OpenCV_DIR}/OpenCVConfig.cmake") 64 | 65 | ## Include the standard CMake script 66 | include("${OpenCV_DIR}/OpenCVConfig.cmake") 67 | 68 | ## Search for a specific version 69 | set(CVLIB_SUFFIX "${OpenCV_VERSION_MAJOR}${OpenCV_VERSION_MINOR}${OpenCV_VERSION_PATCH}") 70 | 71 | #Otherwise it try to guess it. 72 | else(EXISTS "${OpenCV_DIR}/OpenCVConfig.cmake") 73 | 74 | set(OPENCV_LIB_COMPONENTS cxcore cv ml highgui cvaux) 75 | find_path(OpenCV_INCLUDE_DIR "cv.h" PATHS "${OpenCV_DIR}" PATH_SUFFIXES "include" "include/opencv" DOC "") 76 | if(EXISTS ${OpenCV_INCLUDE_DIR}) 77 | include_directories(${OpenCV_INCLUDE_DIR}) 78 | endif(EXISTS ${OpenCV_INCLUDE_DIR}) 79 | 80 | #Find OpenCV version by looking at cvver.h 81 | file(STRINGS ${OpenCV_INCLUDE_DIR}/cvver.h OpenCV_VERSIONS_TMP REGEX "^#define CV_[A-Z]+_VERSION[ \t]+[0-9]+$") 82 | string(REGEX REPLACE ".*#define CV_MAJOR_VERSION[ \t]+([0-9]+).*" "\\1" OpenCV_VERSION_MAJOR ${OpenCV_VERSIONS_TMP}) 83 | string(REGEX REPLACE ".*#define CV_MINOR_VERSION[ \t]+([0-9]+).*" "\\1" OpenCV_VERSION_MINOR ${OpenCV_VERSIONS_TMP}) 84 | string(REGEX REPLACE ".*#define CV_SUBMINOR_VERSION[ \t]+([0-9]+).*" "\\1" OpenCV_VERSION_PATCH ${OpenCV_VERSIONS_TMP}) 85 | set(OpenCV_VERSION ${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.${OpenCV_VERSION_PATCH} CACHE STRING "" FORCE) 86 | #set(CVLIB_SUFFIX "${OpenCV_VERSION_MAJOR}${OpenCV_VERSION_MINOR}${OpenCV_VERSION_PATCH}") 87 | set(CVLIB_SUFFIX "") 88 | 89 | endif(EXISTS "${OpenCV_DIR}/OpenCVConfig.cmake") 90 | 91 | 92 | 93 | 94 | ## Initiate the variable before the loop 95 | set(GLOBAL OpenCV_LIBS "") 96 | set(OpenCV_FOUND_TMP true) 97 | 98 | ## Loop over each components 99 | foreach(__CVLIB ${OPENCV_LIB_COMPONENTS}) 100 | 101 | find_library(OpenCV_${__CVLIB}_LIBRARY_DEBUG NAMES "${__CVLIB}${CVLIB_SUFFIX}d" "lib${__CVLIB}${CVLIB_SUFFIX}d" PATHS "${OpenCV_DIR}/lib" ) 102 | find_library(OpenCV_${__CVLIB}_LIBRARY_RELEASE NAMES "${__CVLIB}${CVLIB_SUFFIX}" "lib${__CVLIB}${CVLIB_SUFFIX}" PATHS "${OpenCV_DIR}/lib" ) 103 | 104 | #Remove the cache value 105 | set(OpenCV_${__CVLIB}_LIBRARY "" CACHE STRING "" FORCE) 106 | 107 | #both debug/release 108 | if(OpenCV_${__CVLIB}_LIBRARY_DEBUG AND OpenCV_${__CVLIB}_LIBRARY_RELEASE) 109 | set(OpenCV_${__CVLIB}_LIBRARY debug ${OpenCV_${__CVLIB}_LIBRARY_DEBUG} optimized ${OpenCV_${__CVLIB}_LIBRARY_RELEASE} CACHE STRING "" FORCE) 110 | #only debug 111 | elseif(OpenCV_${__CVLIB}_LIBRARY_DEBUG) 112 | set(OpenCV_${__CVLIB}_LIBRARY ${OpenCV_${__CVLIB}_LIBRARY_DEBUG} CACHE STRING "" FORCE) 113 | #only release 114 | elseif(OpenCV_${__CVLIB}_LIBRARY_RELEASE) 115 | set(OpenCV_${__CVLIB}_LIBRARY ${OpenCV_${__CVLIB}_LIBRARY_RELEASE} CACHE STRING "" FORCE) 116 | #no library found 117 | else() 118 | set(OpenCV_FOUND_TMP false) 119 | endif() 120 | 121 | #Add to the general list 122 | if(OpenCV_${__CVLIB}_LIBRARY) 123 | set(OpenCV_LIBS ${OpenCV_LIBS} ${OpenCV_${__CVLIB}_LIBRARY}) 124 | endif(OpenCV_${__CVLIB}_LIBRARY) 125 | 126 | endforeach(__CVLIB) 127 | 128 | 129 | set(OpenCV_FOUND ${OpenCV_FOUND_TMP} CACHE BOOL "" FORCE) 130 | 131 | 132 | else(EXISTS "${OpenCV_DIR}") 133 | set(ERR_MSG "Please specify OpenCV directory using OpenCV_DIR env. variable") 134 | endif(EXISTS "${OpenCV_DIR}") 135 | ##==================================================== 136 | 137 | 138 | ##==================================================== 139 | ## Print message 140 | ##---------------------------------------------------- 141 | if(NOT OpenCV_FOUND) 142 | # make FIND_PACKAGE friendly 143 | if(NOT OpenCV_FIND_QUIETLY) 144 | if(OpenCV_FIND_REQUIRED) 145 | message(FATAL_ERROR "OpenCV required but some headers or libs not found. ${ERR_MSG}") 146 | else(OpenCV_FIND_REQUIRED) 147 | message(STATUS "WARNING: OpenCV was not found. ${ERR_MSG}") 148 | endif(OpenCV_FIND_REQUIRED) 149 | endif(NOT OpenCV_FIND_QUIETLY) 150 | endif(NOT OpenCV_FOUND) 151 | ##==================================================== 152 | 153 | 154 | ##==================================================== 155 | ## Backward compatibility 156 | ##---------------------------------------------------- 157 | if(OpenCV_FOUND) 158 | option(OpenCV_BACKWARD_COMPA "Add some variable to make this script compatible with the other version of FindOpenCV.cmake" false) 159 | if(OpenCV_BACKWARD_COMPA) 160 | find_path(OpenCV_INCLUDE_DIRS "cv.h" PATHS "${OpenCV_DIR}" PATH_SUFFIXES "include" "include/opencv" DOC "Include directory") 161 | find_path(OpenCV_INCLUDE_DIR "cv.h" PATHS "${OpenCV_DIR}" PATH_SUFFIXES "include" "include/opencv" DOC "Include directory") 162 | set(OpenCV_LIBRARIES "${OpenCV_LIBS}" CACHE STRING "" FORCE) 163 | endif(OpenCV_BACKWARD_COMPA) 164 | endif(OpenCV_FOUND) 165 | ##==================================================== -------------------------------------------------------------------------------- /src/AKAZEConfig.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file AKAZEConfig.h 3 | * @brief AKAZE configuration file 4 | * @date Oct 07, 2014 5 | * @author Pablo F. Alcantarilla, Jesus Nuevo 6 | */ 7 | 8 | #ifndef AKAZE_SRC_AKAZECONFIG_H_ 9 | #define AKAZE_SRC_AKAZECONFIG_H_ 10 | 11 | /* ************************************************************************* */ 12 | #include 13 | 14 | // OpenMP 15 | #ifdef AKAZE_USE_OPENMP 16 | #include 17 | #endif 18 | 19 | // System 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | typedef Eigen::Matrix 27 | RowMatrixXf; 28 | 29 | namespace libAKAZE { 30 | 31 | /* ************************************************************************* */ 32 | // Lookup table for 2d gaussian (sigma = 2.5) where (0,0) is top left and (6,6) 33 | // is bottom right 34 | const float gauss25[7][7] = { 35 | { 0.02546481f, 0.02350698f, 0.01849125f, 0.01239505f, 0.00708017f, 36 | 0.00344629f, 0.00142946f }, 37 | { 0.02350698f, 0.02169968f, 0.01706957f, 0.01144208f, 0.00653582f, 38 | 0.00318132f, 0.00131956f }, 39 | { 0.01849125f, 0.01706957f, 0.01342740f, 0.00900066f, 0.00514126f, 40 | 0.00250252f, 0.00103800f }, 41 | { 0.01239505f, 0.01144208f, 0.00900066f, 0.00603332f, 0.00344629f, 42 | 0.00167749f, 0.00069579f }, 43 | { 0.00708017f, 0.00653582f, 0.00514126f, 0.00344629f, 0.00196855f, 44 | 0.00095820f, 0.00039744f }, 45 | { 0.00344629f, 0.00318132f, 0.00250252f, 0.00167749f, 0.00095820f, 46 | 0.00046640f, 0.00019346f }, 47 | { 0.00142946f, 0.00131956f, 0.00103800f, 0.00069579f, 0.00039744f, 48 | 0.00019346f, 0.00008024f } 49 | }; 50 | 51 | /* ************************************************************************* */ 52 | // AKAZE Descriptor Type 53 | enum DESCRIPTOR_TYPE { 54 | SURF_UPRIGHT = 0, // Upright descriptors, not invariant to rotation 55 | SURF = 1, 56 | MSURF_UPRIGHT = 2, // Upright descriptors, not invariant to rotation 57 | MSURF = 3, 58 | MLDB_UPRIGHT = 4, // Upright descriptors, not invariant to rotation 59 | MLDB = 5 60 | }; 61 | 62 | /* ************************************************************************* */ 63 | // AKAZE Diffusivities 64 | enum DIFFUSIVITY_TYPE { 65 | PM_G1 = 0, 66 | PM_G2 = 1, 67 | WEICKERT = 2, 68 | CHARBONNIER = 3 69 | }; 70 | 71 | /* ************************************************************************* */ 72 | // AKAZE Timing structure 73 | struct AKAZETiming { 74 | 75 | AKAZETiming() { 76 | kcontrast = 0.0; 77 | scale = 0.0; 78 | derivatives = 0.0; 79 | detector = 0.0; 80 | extrema = 0.0; 81 | subpixel = 0.0; 82 | descriptor = 0.0; 83 | } 84 | 85 | double kcontrast; // Contrast factor computation time in ms 86 | double scale; // Nonlinear scale space computation time in ms 87 | double derivatives; // Multiscale derivatives computation time in ms 88 | double detector; // Feature detector computation time in ms 89 | double extrema; // Scale space extrema computation time in ms 90 | double subpixel; // Subpixel refinement computation time in ms 91 | double descriptor; // Descriptors computation time in ms 92 | }; 93 | 94 | /* ************************************************************************* */ 95 | // AKAZE configuration options structure 96 | struct AKAZEOptions { 97 | 98 | AKAZEOptions() { 99 | num_threads = 1; 100 | soffset = 1.6f; 101 | derivative_factor = 1.5f; 102 | omax = 4; 103 | nsublevels = 4; 104 | dthreshold = 0.001f; 105 | min_dthreshold = 0.00001f; 106 | 107 | diffusivity = PM_G2; 108 | descriptor = MLDB; 109 | descriptor_size = 0; 110 | descriptor_channels = 3; 111 | descriptor_pattern_size = 10; 112 | sderivatives = 1.0; 113 | 114 | kcontrast = 0.001f; 115 | kcontrast_percentile = 0.7f; 116 | kcontrast_nbins = 300; 117 | 118 | verbosity = false; 119 | } 120 | 121 | // The number of threads to use with OpenMP. 122 | int num_threads; 123 | 124 | // Initial octave level (-1 means that the size of the input image is 125 | //duplicated) 126 | int omin; 127 | // Maximum octave evolution of the image 2^sigma (coarsest scale sigma 128 | //units) 129 | int omax; 130 | // Default number of sublevels per scale level 131 | int nsublevels; 132 | // Width of the input image 133 | int img_width; 134 | // Height of the input image 135 | int img_height; 136 | // Base scale offset (sigma units) 137 | float soffset; 138 | // Factor for the multiscale derivatives 139 | float derivative_factor; 140 | // Smoothing factor for the derivatives 141 | float sderivatives; 142 | // Diffusivity type 143 | DIFFUSIVITY_TYPE diffusivity; 144 | 145 | // Detector response threshold to accept point 146 | float dthreshold; 147 | // Minimum detector threshold to accept a point 148 | float min_dthreshold; 149 | 150 | // Type of descriptor 151 | DESCRIPTOR_TYPE descriptor; 152 | int descriptor_size; 153 | // Number of channels in the descriptor (1, 2, 3). These correspond to 154 | // intensity and x, y dervitives. 155 | int descriptor_channels; 156 | // Actual patch size is 2*pattern_size*point.scale 157 | int descriptor_pattern_size; 158 | 159 | 160 | // The contrast factor parameter 161 | float kcontrast; 162 | // Percentile level for the contrast factor 163 | float kcontrast_percentile; 164 | // Number of bins for the contrast factor histogram 165 | size_t kcontrast_nbins; 166 | 167 | // Set to true for saving the scale space images 168 | bool save_scale_space; 169 | // Set to true for saving the detected keypoints and descriptors 170 | bool save_keypoints; 171 | // Set to true for displaying verbosity information 172 | bool verbosity; 173 | 174 | friend std::ostream& operator<<(std::ostream& os, 175 | const AKAZEOptions& akaze_options) { 176 | 177 | os << std::left; 178 | #define CHECK_AKAZE_OPTION(option) \ 179 | os << std::setw(33) << #option << " = " << option << std::endl 180 | 181 | // Scale-space parameters. 182 | CHECK_AKAZE_OPTION(akaze_options.omax); 183 | CHECK_AKAZE_OPTION(akaze_options.nsublevels); 184 | CHECK_AKAZE_OPTION(akaze_options.soffset); 185 | CHECK_AKAZE_OPTION(akaze_options.sderivatives); 186 | CHECK_AKAZE_OPTION(akaze_options.diffusivity); 187 | // Detection parameters. 188 | CHECK_AKAZE_OPTION(akaze_options.dthreshold); 189 | // Descriptor parameters. 190 | CHECK_AKAZE_OPTION(akaze_options.descriptor); 191 | CHECK_AKAZE_OPTION(akaze_options.descriptor_channels); 192 | // Save scale-space 193 | CHECK_AKAZE_OPTION(akaze_options.save_scale_space); 194 | // Verbose option for debug. 195 | CHECK_AKAZE_OPTION(akaze_options.verbosity); 196 | #undef CHECK_AKAZE_OPTIONS 197 | 198 | return os; 199 | } 200 | }; 201 | 202 | /* ************************************************************************* */ 203 | // AKAZE nonlinear diffusion filtering evolution 204 | struct TEvolution { 205 | 206 | TEvolution() { 207 | etime = 0.0f; 208 | esigma = 0.0f; 209 | octave = 0; 210 | sublevel = 0; 211 | sigma_size = 0; 212 | } 213 | 214 | // First order spatial derivatives 215 | RowMatrixXf Lx, Ly; 216 | // Second order spatial derivatives 217 | RowMatrixXf Lxx, Lxy, Lyy; 218 | // Diffusivity image 219 | RowMatrixXf Lflow; 220 | // Evolution image 221 | RowMatrixXf Lt; 222 | // Smoothed image 223 | RowMatrixXf Lsmooth; 224 | // Evolution step update 225 | RowMatrixXf Lstep; 226 | // Detector response 227 | RowMatrixXf Ldet; 228 | // Evolution time 229 | float etime; 230 | // Evolution sigma. For linear diffusion t = sigma^2 / 2 231 | float esigma; 232 | // Image octave 233 | size_t octave; 234 | // Image sublevel in each octave 235 | size_t sublevel; 236 | // Integer sigma. For computing the feature detector responses 237 | size_t sigma_size; 238 | }; 239 | 240 | } // namespace libAKAZE 241 | 242 | #endif // AKAZE_SRC_AKAZECONFIG_H_ 243 | -------------------------------------------------------------------------------- /cmake/FindEigen.cmake: -------------------------------------------------------------------------------- 1 | # This CMake module was taken from Ceres. Ceres Solver license is included. 2 | # 3 | # 4 | # Ceres Solver - A fast non-linear least squares minimizer 5 | # Copyright 2013 Google Inc. All rights reserved. 6 | # http://code.google.com/p/ceres-solver/ 7 | # 8 | # Redistribution and use in source and binary forms, with or without 9 | # modification, are permitted provided that the following conditions are met: 10 | # 11 | # * Redistributions of source code must retain the above copyright notice, 12 | # this list of conditions and the following disclaimer. 13 | # * Redistributions in binary form must reproduce the above copyright notice, 14 | # this list of conditions and the following disclaimer in the documentation 15 | # and/or other materials provided with the distribution. 16 | # * Neither the name of Google Inc. nor the names of its contributors may be 17 | # used to endorse or promote products derived from this software without 18 | # specific prior written permission. 19 | # 20 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 24 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 | # POSSIBILITY OF SUCH DAMAGE. 31 | # 32 | # Author: alexs.mac@gmail.com (Alex Stewart) 33 | # 34 | 35 | # FindEigen.cmake - Find Eigen library, version >= 3. 36 | # 37 | # This module defines the following variables: 38 | # 39 | # EIGEN_FOUND: TRUE iff Eigen is found. 40 | # EIGEN_INCLUDE_DIRS: Include directories for Eigen. 41 | # 42 | # EIGEN_VERSION: Extracted from Eigen/src/Core/util/Macros.h 43 | # EIGEN_WORLD_VERSION: Equal to 3 if EIGEN_VERSION = 3.2.0 44 | # EIGEN_MAJOR_VERSION: Equal to 2 if EIGEN_VERSION = 3.2.0 45 | # EIGEN_MINOR_VERSION: Equal to 0 if EIGEN_VERSION = 3.2.0 46 | # 47 | # The following variables control the behaviour of this module: 48 | # 49 | # EIGEN_INCLUDE_DIR_HINTS: List of additional directories in which to 50 | # search for eigen includes, e.g: /timbuktu/eigen3. 51 | # 52 | # The following variables are also defined by this module, but in line with 53 | # CMake recommended FindPackage() module style should NOT be referenced directly 54 | # by callers (use the plural variables detailed above instead). These variables 55 | # do however affect the behaviour of the module via FIND_[PATH/LIBRARY]() which 56 | # are NOT re-called (i.e. search for library is not repeated) if these variables 57 | # are set with valid values _in the CMake cache_. This means that if these 58 | # variables are set directly in the cache, either by the user in the CMake GUI, 59 | # or by the user passing -DVAR=VALUE directives to CMake when called (which 60 | # explicitly defines a cache variable), then they will be used verbatim, 61 | # bypassing the HINTS variables and other hard-coded search locations. 62 | # 63 | # EIGEN_INCLUDE_DIR: Include directory for CXSparse, not including the 64 | # include directory of any dependencies. 65 | 66 | # Called if we failed to find Eigen or any of it's required dependencies, 67 | # unsets all public (designed to be used externally) variables and reports 68 | # error message at priority depending upon [REQUIRED/QUIET/] argument. 69 | MACRO(EIGEN_REPORT_NOT_FOUND REASON_MSG) 70 | UNSET(EIGEN_FOUND) 71 | UNSET(EIGEN_INCLUDE_DIRS) 72 | # Make results of search visible in the CMake GUI if Eigen has not 73 | # been found so that user does not have to toggle to advanced view. 74 | MARK_AS_ADVANCED(CLEAR EIGEN_INCLUDE_DIR) 75 | # Note _FIND_[REQUIRED/QUIETLY] variables defined by FindPackage() 76 | # use the camelcase library name, not uppercase. 77 | IF (Eigen_FIND_QUIETLY) 78 | MESSAGE(STATUS "Failed to find Eigen - " ${REASON_MSG} ${ARGN}) 79 | ELSEIF (Eigen_FIND_REQUIRED) 80 | MESSAGE(FATAL_ERROR "Failed to find Eigen - " ${REASON_MSG} ${ARGN}) 81 | ELSE() 82 | # Neither QUIETLY nor REQUIRED, use no priority which emits a message 83 | # but continues configuration and allows generation. 84 | MESSAGE("-- Failed to find Eigen - " ${REASON_MSG} ${ARGN}) 85 | ENDIF () 86 | ENDMACRO(EIGEN_REPORT_NOT_FOUND) 87 | 88 | # Search user-installed locations first, so that we prefer user installs 89 | # to system installs where both exist. 90 | # 91 | # TODO: Add standard Windows search locations for Eigen. 92 | LIST(APPEND EIGEN_CHECK_INCLUDE_DIRS 93 | /usr/local/include/eigen3 94 | /usr/local/homebrew/include/eigen3 # Mac OS X 95 | /opt/local/var/macports/software/eigen3 # Mac OS X. 96 | /opt/local/include/eigen3 97 | /usr/include/eigen3) 98 | 99 | # Search supplied hint directories first if supplied. 100 | FIND_PATH(EIGEN_INCLUDE_DIR 101 | NAMES Eigen/Core 102 | PATHS ${EIGEN_INCLUDE_DIR_HINTS} 103 | ${EIGEN_CHECK_INCLUDE_DIRS}) 104 | IF (NOT EIGEN_INCLUDE_DIR OR 105 | NOT EXISTS ${EIGEN_INCLUDE_DIR}) 106 | EIGEN_REPORT_NOT_FOUND( 107 | "Could not find eigen3 include directory, set EIGEN_INCLUDE_DIR to " 108 | "path to eigen3 include directory, e.g. /usr/local/include/eigen3.") 109 | ENDIF (NOT EIGEN_INCLUDE_DIR OR 110 | NOT EXISTS ${EIGEN_INCLUDE_DIR}) 111 | 112 | # Mark internally as found, then verify. EIGEN_REPORT_NOT_FOUND() unsets 113 | # if called. 114 | SET(EIGEN_FOUND TRUE) 115 | 116 | # Extract Eigen version from Eigen/src/Core/util/Macros.h 117 | IF (EIGEN_INCLUDE_DIR) 118 | SET(EIGEN_VERSION_FILE ${EIGEN_INCLUDE_DIR}/Eigen/src/Core/util/Macros.h) 119 | IF (NOT EXISTS ${EIGEN_VERSION_FILE}) 120 | EIGEN_REPORT_NOT_FOUND( 121 | "Could not find file: ${EIGEN_VERSION_FILE} " 122 | "containing version information in Eigen install located at: " 123 | "${EIGEN_INCLUDE_DIR}.") 124 | ELSE (NOT EXISTS ${EIGEN_VERSION_FILE}) 125 | FILE(READ ${EIGEN_VERSION_FILE} EIGEN_VERSION_FILE_CONTENTS) 126 | 127 | STRING(REGEX MATCH "#define EIGEN_WORLD_VERSION [0-9]+" 128 | EIGEN_WORLD_VERSION "${EIGEN_VERSION_FILE_CONTENTS}") 129 | STRING(REGEX REPLACE "#define EIGEN_WORLD_VERSION ([0-9]+)" "\\1" 130 | EIGEN_WORLD_VERSION "${EIGEN_WORLD_VERSION}") 131 | 132 | STRING(REGEX MATCH "#define EIGEN_MAJOR_VERSION [0-9]+" 133 | EIGEN_MAJOR_VERSION "${EIGEN_VERSION_FILE_CONTENTS}") 134 | STRING(REGEX REPLACE "#define EIGEN_MAJOR_VERSION ([0-9]+)" "\\1" 135 | EIGEN_MAJOR_VERSION "${EIGEN_MAJOR_VERSION}") 136 | 137 | STRING(REGEX MATCH "#define EIGEN_MINOR_VERSION [0-9]+" 138 | EIGEN_MINOR_VERSION "${EIGEN_VERSION_FILE_CONTENTS}") 139 | STRING(REGEX REPLACE "#define EIGEN_MINOR_VERSION ([0-9]+)" "\\1" 140 | EIGEN_MINOR_VERSION "${EIGEN_MINOR_VERSION}") 141 | 142 | # This is on a single line s/t CMake does not interpret it as a list of 143 | # elements and insert ';' separators which would result in 3.;2.;0 nonsense. 144 | SET(EIGEN_VERSION "${EIGEN_WORLD_VERSION}.${EIGEN_MAJOR_VERSION}.${EIGEN_MINOR_VERSION}") 145 | ENDIF (NOT EXISTS ${EIGEN_VERSION_FILE}) 146 | ENDIF (EIGEN_INCLUDE_DIR) 147 | 148 | # Set standard CMake FindPackage variables if found. 149 | IF (EIGEN_FOUND) 150 | SET(EIGEN_INCLUDE_DIRS ${EIGEN_INCLUDE_DIR}) 151 | ENDIF (EIGEN_FOUND) 152 | 153 | # Handle REQUIRED / QUIET optional arguments and version. 154 | INCLUDE(FindPackageHandleStandardArgs) 155 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(Eigen 156 | REQUIRED_VARS EIGEN_INCLUDE_DIRS 157 | VERSION_VAR EIGEN_VERSION) 158 | 159 | # Only mark internal variables as advanced if we found Eigen, otherwise 160 | # leave it visible in the standard GUI for the user to set manually. 161 | IF (EIGEN_FOUND) 162 | MARK_AS_ADVANCED(FORCE EIGEN_INCLUDE_DIR) 163 | ENDIF (EIGEN_FOUND) 164 | -------------------------------------------------------------------------------- /cimg/cmake-modules/FindImageMagick.cmake: -------------------------------------------------------------------------------- 1 | # - Find the ImageMagick binary suite. 2 | # This module will search for a set of ImageMagick tools specified 3 | # as components in the FIND_PACKAGE call. Typical components include, 4 | # but are not limited to (future versions of ImageMagick might have 5 | # additional components not listed here): 6 | # 7 | # animate 8 | # compare 9 | # composite 10 | # conjure 11 | # convert 12 | # display 13 | # identify 14 | # import 15 | # mogrify 16 | # montage 17 | # stream 18 | # 19 | # If no component is specified in the FIND_PACKAGE call, then it only 20 | # searches for the ImageMagick executable directory. This code defines 21 | # the following variables: 22 | # 23 | # ImageMagick_FOUND - TRUE if all components are found. 24 | # ImageMagick_EXECUTABLE_DIR - Full path to executables directory. 25 | # ImageMagick__FOUND - TRUE if is found. 26 | # ImageMagick__EXECUTABLE - Full path to executable. 27 | # 28 | # There are also components for the following ImageMagick APIs: 29 | # 30 | # Magick++ 31 | # MagickWand 32 | # MagickCore 33 | # 34 | # For these components the following variables are set: 35 | # 36 | # ImageMagick_FOUND - TRUE if all components are found. 37 | # ImageMagick_INCLUDE_DIRS - Full paths to all include dirs. 38 | # ImageMagick_LIBRARIES - Full paths to all libraries. 39 | # ImageMagick__FOUND - TRUE if is found. 40 | # ImageMagick__INCLUDE_DIRS - Full path to include dirs. 41 | # ImageMagick__LIBRARIES - Full path to libraries. 42 | # 43 | # Example Usages: 44 | # FIND_PACKAGE(ImageMagick) 45 | # FIND_PACKAGE(ImageMagick COMPONENTS convert) 46 | # FIND_PACKAGE(ImageMagick COMPONENTS convert mogrify display) 47 | # FIND_PACKAGE(ImageMagick COMPONENTS Magick++) 48 | # FIND_PACKAGE(ImageMagick COMPONENTS Magick++ convert) 49 | # 50 | # Note that the standard FIND_PACKAGE features are supported 51 | # (i.e., QUIET, REQUIRED, etc.). 52 | 53 | #============================================================================= 54 | # Copyright 2007-2009 Kitware, Inc. 55 | # Copyright 2007-2008 Miguel A. Figueroa-Villanueva 56 | # 57 | # Distributed under the OSI-approved BSD License (the "License"); 58 | # see accompanying file Copyright.txt for details. 59 | # 60 | # This software is distributed WITHOUT ANY WARRANTY; without even the 61 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 62 | # See the License for more information. 63 | #============================================================================= 64 | # (To distributed this file outside of CMake, substitute the full 65 | # License text for the above reference.) 66 | 67 | #--------------------------------------------------------------------- 68 | # Helper functions 69 | #--------------------------------------------------------------------- 70 | FUNCTION(FIND_IMAGEMAGICK_API component header) 71 | SET(ImageMagick_${component}_FOUND FALSE PARENT_SCOPE) 72 | 73 | FIND_PATH(ImageMagick_${component}_INCLUDE_DIR 74 | NAMES ${header} 75 | PATHS 76 | ${ImageMagick_INCLUDE_DIRS} 77 | "[HKEY_LOCAL_MACHINE\\SOFTWARE\\ImageMagick\\Current;BinPath]/include" 78 | PATH_SUFFIXES 79 | ImageMagick 80 | DOC "Path to the ImageMagick include dir." 81 | ) 82 | FIND_LIBRARY(ImageMagick_${component}_LIBRARY 83 | NAMES ${ARGN} 84 | PATHS 85 | "[HKEY_LOCAL_MACHINE\\SOFTWARE\\ImageMagick\\Current;BinPath]/lib" 86 | DOC "Path to the ImageMagick Magick++ library." 87 | ) 88 | 89 | IF(ImageMagick_${component}_INCLUDE_DIR AND ImageMagick_${component}_LIBRARY) 90 | SET(ImageMagick_${component}_FOUND TRUE PARENT_SCOPE) 91 | 92 | LIST(APPEND ImageMagick_INCLUDE_DIRS 93 | ${ImageMagick_${component}_INCLUDE_DIR} 94 | ) 95 | LIST(REMOVE_DUPLICATES ImageMagick_INCLUDE_DIRS) 96 | SET(ImageMagick_INCLUDE_DIRS ${ImageMagick_INCLUDE_DIRS} PARENT_SCOPE) 97 | 98 | LIST(APPEND ImageMagick_LIBRARIES 99 | ${ImageMagick_${component}_LIBRARY} 100 | ) 101 | SET(ImageMagick_LIBRARIES ${ImageMagick_LIBRARIES} PARENT_SCOPE) 102 | ENDIF(ImageMagick_${component}_INCLUDE_DIR AND ImageMagick_${component}_LIBRARY) 103 | ENDFUNCTION(FIND_IMAGEMAGICK_API) 104 | 105 | FUNCTION(FIND_IMAGEMAGICK_EXE component) 106 | SET(_IMAGEMAGICK_EXECUTABLE 107 | ${ImageMagick_EXECUTABLE_DIR}/${component}${CMAKE_EXECUTABLE_SUFFIX}) 108 | IF(EXISTS ${_IMAGEMAGICK_EXECUTABLE}) 109 | SET(ImageMagick_${component}_EXECUTABLE 110 | ${_IMAGEMAGICK_EXECUTABLE} 111 | PARENT_SCOPE 112 | ) 113 | SET(ImageMagick_${component}_FOUND TRUE PARENT_SCOPE) 114 | ELSE(EXISTS ${_IMAGEMAGICK_EXECUTABLE}) 115 | SET(ImageMagick_${component}_FOUND FALSE PARENT_SCOPE) 116 | ENDIF(EXISTS ${_IMAGEMAGICK_EXECUTABLE}) 117 | ENDFUNCTION(FIND_IMAGEMAGICK_EXE) 118 | 119 | #--------------------------------------------------------------------- 120 | # Start Actual Work 121 | #--------------------------------------------------------------------- 122 | # Try to find a ImageMagick installation binary path. 123 | FIND_PATH(ImageMagick_EXECUTABLE_DIR 124 | NAMES mogrify${CMAKE_EXECUTABLE_SUFFIX} 125 | PATHS 126 | "[HKEY_LOCAL_MACHINE\\SOFTWARE\\ImageMagick\\Current;BinPath]" 127 | DOC "Path to the ImageMagick binary directory." 128 | NO_DEFAULT_PATH 129 | ) 130 | FIND_PATH(ImageMagick_EXECUTABLE_DIR 131 | NAMES mogrify${CMAKE_EXECUTABLE_SUFFIX} 132 | ) 133 | 134 | # Find each component. Search for all tools in same dir 135 | # ; otherwise they should be found 136 | # independently and not in a cohesive module such as this one. 137 | SET(ImageMagick_FOUND TRUE) 138 | FOREACH(component ${ImageMagick_FIND_COMPONENTS} 139 | # DEPRECATED: forced components for backward compatibility 140 | convert mogrify import montage composite 141 | ) 142 | IF(component STREQUAL "Magick++") 143 | FIND_IMAGEMAGICK_API(Magick++ Magick++.h 144 | Magick++ CORE_RL_Magick++_ 145 | ) 146 | ELSEIF(component STREQUAL "MagickWand") 147 | FIND_IMAGEMAGICK_API(MagickWand wand/MagickWand.h 148 | Wand MagickWand CORE_RL_wand_ 149 | ) 150 | ELSEIF(component STREQUAL "MagickCore") 151 | FIND_IMAGEMAGICK_API(MagickCore magick/MagickCore.h 152 | Magick MagickCore CORE_RL_magick_ 153 | ) 154 | ELSE(component STREQUAL "Magick++") 155 | IF(ImageMagick_EXECUTABLE_DIR) 156 | FIND_IMAGEMAGICK_EXE(${component}) 157 | ENDIF(ImageMagick_EXECUTABLE_DIR) 158 | ENDIF(component STREQUAL "Magick++") 159 | 160 | IF(NOT ImageMagick_${component}_FOUND) 161 | LIST(FIND ImageMagick_FIND_COMPONENTS ${component} is_requested) 162 | IF(is_requested GREATER -1) 163 | SET(ImageMagick_FOUND FALSE) 164 | ENDIF(is_requested GREATER -1) 165 | ENDIF(NOT ImageMagick_${component}_FOUND) 166 | ENDFOREACH(component) 167 | 168 | SET(ImageMagick_INCLUDE_DIRS ${ImageMagick_INCLUDE_DIRS}) 169 | SET(ImageMagick_LIBRARIES ${ImageMagick_LIBRARIES}) 170 | 171 | #--------------------------------------------------------------------- 172 | # Standard Package Output 173 | #--------------------------------------------------------------------- 174 | INCLUDE(FindPackageHandleStandardArgs) 175 | FIND_PACKAGE_HANDLE_STANDARD_ARGS( 176 | ImageMagick DEFAULT_MSG ImageMagick_FOUND 177 | ) 178 | # Maintain consistency with all other variables. 179 | SET(ImageMagick_FOUND ${IMAGEMAGICK_FOUND}) 180 | 181 | #--------------------------------------------------------------------- 182 | # DEPRECATED: Setting variables for backward compatibility. 183 | #--------------------------------------------------------------------- 184 | SET(IMAGEMAGICK_BINARY_PATH ${ImageMagick_EXECUTABLE_DIR} 185 | CACHE PATH "Path to the ImageMagick binary directory.") 186 | SET(IMAGEMAGICK_CONVERT_EXECUTABLE ${ImageMagick_convert_EXECUTABLE} 187 | CACHE FILEPATH "Path to ImageMagick's convert executable.") 188 | SET(IMAGEMAGICK_MOGRIFY_EXECUTABLE ${ImageMagick_mogrify_EXECUTABLE} 189 | CACHE FILEPATH "Path to ImageMagick's mogrify executable.") 190 | SET(IMAGEMAGICK_IMPORT_EXECUTABLE ${ImageMagick_import_EXECUTABLE} 191 | CACHE FILEPATH "Path to ImageMagick's import executable.") 192 | SET(IMAGEMAGICK_MONTAGE_EXECUTABLE ${ImageMagick_montage_EXECUTABLE} 193 | CACHE FILEPATH "Path to ImageMagick's montage executable.") 194 | SET(IMAGEMAGICK_COMPOSITE_EXECUTABLE ${ImageMagick_composite_EXECUTABLE} 195 | CACHE FILEPATH "Path to ImageMagick's composite executable.") 196 | MARK_AS_ADVANCED( 197 | IMAGEMAGICK_BINARY_PATH 198 | IMAGEMAGICK_CONVERT_EXECUTABLE 199 | IMAGEMAGICK_MOGRIFY_EXECUTABLE 200 | IMAGEMAGICK_IMPORT_EXECUTABLE 201 | IMAGEMAGICK_MONTAGE_EXECUTABLE 202 | IMAGEMAGICK_COMPOSITE_EXECUTABLE 203 | ) 204 | -------------------------------------------------------------------------------- /akaze_features.cpp: -------------------------------------------------------------------------------- 1 | //============================================================================= 2 | // 3 | // akaze_features.cpp 4 | // Authors: Pablo F. Alcantarilla (1), Jesus Nuevo (2) 5 | // Institutions: Toshiba Research Europe Ltd (1) 6 | // TrueVision Solutions (2) 7 | // Date: 07/10/2014 8 | // Email: pablofdezalc@gmail.com 9 | // 10 | // AKAZE Features Copyright 2014, Pablo F. Alcantarilla, Jesus Nuevo 11 | // All Rights Reserved 12 | // See LICENSE for the license information 13 | //============================================================================= 14 | 15 | /** 16 | * @file akaze_features.cpp 17 | * @brief Main program for detecting and computing binary descriptors in an 18 | * accelerated nonlinear scale space 19 | * @date Oct 07, 2014 20 | * @author Pablo F. Alcantarilla, Jesus Nuevo 21 | */ 22 | 23 | #include 24 | 25 | #include "cimg/CImg.h" 26 | #include "src/AKAZE.h" 27 | #include "src/AKAZEConfig.h" 28 | #include "src/utils.h" 29 | #include "timer/timer.hpp" 30 | 31 | /* ************************************************************************* */ 32 | /** 33 | * @brief This function parses the command line arguments for setting A-KAZE 34 | * parameters 35 | * @param options Structure that contains A-KAZE settings 36 | * @param img_path Path for the input image 37 | * @param kpts_path Path for the file where the keypoints where be stored 38 | */ 39 | int parse_input_options(libAKAZE::AKAZEOptions& options, std::string& img_path, 40 | std::string& kpts_path, int argc, char* argv[]); 41 | 42 | /* ************************************************************************* */ 43 | int main(int argc, char* argv[]) { 44 | // Variables 45 | libAKAZE::AKAZEOptions options; 46 | std::string img_path, kpts_path; 47 | 48 | // Variable for computation times. 49 | double tdet = 0.0, tdesc = 0.0; 50 | 51 | // Parse the input command line options 52 | if (parse_input_options(options, img_path, kpts_path, argc, argv)) { 53 | return -1; 54 | } 55 | 56 | if (options.verbosity) { 57 | std::cout << "Check AKAZE options:" << std::endl; 58 | std::cout << options << std::endl; 59 | } 60 | 61 | // Try to read the image and if necessary convert to grayscale. CImg will 62 | // throw an error and crash if the image could not be read. 63 | cimg_library::CImg img(img_path.c_str()); 64 | RowMatrixXf img_32; 65 | ConvertCImgToEigen(img, img_32); 66 | img_32 /= 255.0; 67 | 68 | // Don't forget to specify image dimensions in AKAZE's options. 69 | options.img_width = img_32.cols(); 70 | options.img_height = img_32.rows(); 71 | 72 | // Extract features. 73 | std::vector kpts; 74 | timer::Timer timer; 75 | libAKAZE::AKAZE evolution(options); 76 | evolution.Create_Nonlinear_Scale_Space(img_32); 77 | evolution.Feature_Detection(kpts); 78 | tdet = timer.elapsedMs(); 79 | 80 | // Compute descriptors. 81 | libAKAZE::AKAZEDescriptors desc; 82 | timer.reset(); 83 | evolution.Compute_Descriptors(kpts, desc); 84 | tdesc = timer.elapsedMs(); 85 | 86 | // Summarize the computation times. 87 | evolution.Show_Computation_Times(); 88 | evolution.Save_Scale_Space(); 89 | std::cout << "Number of points: " << kpts.size() << std::endl; 90 | std::cout << "Time Detector: " << tdet << " ms" << std::endl; 91 | std::cout << "Time Descriptor: " << tdesc << " ms" << std::endl; 92 | 93 | // Save keypoints in ASCII format. 94 | if (!kpts_path.empty()) { 95 | if (options.descriptor < libAKAZE::MLDB_UPRIGHT) { 96 | save_keypoints(kpts_path, kpts, desc.float_descriptor, true); 97 | } else { 98 | save_keypoints(kpts_path, kpts, desc.binary_descriptor, true); 99 | } 100 | } 101 | 102 | // Convert the input image to RGB. 103 | cimg_library::CImg rgb_image = 104 | img.get_resize(img.width(), img.height(), img.depth(), 3); 105 | draw_keypoints(rgb_image, kpts); 106 | rgb_image.save("../output/detected_features.jpg"); 107 | } 108 | 109 | /* ************************************************************************* */ 110 | int parse_input_options(libAKAZE::AKAZEOptions& options, std::string& img_path, 111 | std::string& kpts_path, int argc, char* argv[]) { 112 | 113 | // If there is only one argument return 114 | if (argc < 2) { 115 | show_input_options_help(0); 116 | return -1; 117 | } 118 | // Set the options from the command line 119 | else if (argc >= 3) { 120 | options = libAKAZE::AKAZEOptions(); 121 | kpts_path = "./keypoints.txt"; 122 | 123 | if (!strcmp(argv[1], "--help")) { 124 | show_input_options_help(0); 125 | return -1; 126 | } 127 | 128 | img_path = argv[1]; 129 | 130 | for (int i = 3; i < argc; i++) { 131 | if (!strcmp(argv[i], "--num_threads")) { 132 | i = i + 1; 133 | options.num_threads = atoi(argv[i]); 134 | } else if (!strcmp(argv[i], "--soffset")) { 135 | i = i + 1; 136 | if (i >= argc) { 137 | std::cerr << "Error introducing input options!!" << std::endl; 138 | return -1; 139 | } else { 140 | options.soffset = atof(argv[i]); 141 | } 142 | } else if (!strcmp(argv[i], "--omax")) { 143 | i = i + 1; 144 | if (i >= argc) { 145 | std::cerr << "Error introducing input options!!" << std::endl; 146 | return -1; 147 | } else { 148 | options.omax = atof(argv[i]); 149 | } 150 | } else if (!strcmp(argv[i], "--dthreshold")) { 151 | i = i + 1; 152 | if (i >= argc) { 153 | std::cerr << "Error introducing input options!!" << std::endl; 154 | return -1; 155 | } else { 156 | options.dthreshold = atof(argv[i]); 157 | } 158 | } else if (!strcmp(argv[i], "--sderivatives")) { 159 | i = i + 1; 160 | if (i >= argc) { 161 | std::cerr << "Error introducing input options!!" << std::endl; 162 | return -1; 163 | } else { 164 | options.sderivatives = atof(argv[i]); 165 | } 166 | } else if (!strcmp(argv[i], "--nsublevels")) { 167 | i = i + 1; 168 | if (i >= argc) { 169 | std::cerr << "Error introducing input options!!" << std::endl; 170 | return -1; 171 | } else 172 | options.nsublevels = atoi(argv[i]); 173 | } else if (!strcmp(argv[i], "--diffusivity")) { 174 | i = i + 1; 175 | if (i >= argc) { 176 | std::cerr << "Error introducing input options!!" << std::endl; 177 | return -1; 178 | } else 179 | options.diffusivity = libAKAZE::DIFFUSIVITY_TYPE(atoi(argv[i])); 180 | } else if (!strcmp(argv[i], "--descriptor")) { 181 | i = i + 1; 182 | if (i >= argc) { 183 | std::cerr << "Error introducing input options!!" << std::endl; 184 | return -1; 185 | } else { 186 | options.descriptor = libAKAZE::DESCRIPTOR_TYPE(atoi(argv[i])); 187 | 188 | if (options.descriptor < 0 || options.descriptor > libAKAZE::MLDB) { 189 | options.descriptor = libAKAZE::MLDB; 190 | } 191 | } 192 | } else if (!strcmp(argv[i], "--descriptor_channels")) { 193 | i = i + 1; 194 | if (i >= argc) { 195 | std::cerr << "Error introducing input options!!" << std::endl; 196 | return -1; 197 | } else { 198 | options.descriptor_channels = atoi(argv[i]); 199 | 200 | if (options.descriptor_channels <= 0 || 201 | options.descriptor_channels > 3) { 202 | options.descriptor_channels = 3; 203 | } 204 | } 205 | } else if (!strcmp(argv[i],"--descriptor_size")) { 206 | i = i+1; 207 | if (i >= argc) { 208 | std::cerr << "Error introducing input options!!" << std::endl; 209 | return -1; 210 | } 211 | else { 212 | options.descriptor_size = atoi(argv[i]); 213 | 214 | if (options.descriptor_size < 0) { 215 | options.descriptor_size = 0; 216 | } 217 | } 218 | } else if (!strcmp(argv[i], "--save_scale_space")) { 219 | i = i + 1; 220 | if (i >= argc) { 221 | std::cerr << "Error introducing input options!!" << std::endl; 222 | return -1; 223 | } else { 224 | options.save_scale_space = (bool)atoi(argv[i]); 225 | } 226 | } else if (!strcmp(argv[i], "--verbose")) { 227 | options.verbosity = true; 228 | } else if (!strcmp(argv[i], "--output")) { 229 | options.save_keypoints = true; 230 | i = i + 1; 231 | if (i >= argc) { 232 | std::cerr << "Error introducing input options!!" << std::endl; 233 | return -1; 234 | } else 235 | kpts_path = argv[i]; 236 | } 237 | } 238 | } 239 | 240 | return 0; 241 | } 242 | -------------------------------------------------------------------------------- /src/convolution.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2014 The Regents of the University of California (Regents). 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following 13 | // disclaimer in the documentation and/or other materials provided 14 | // with the distribution. 15 | // 16 | // * Neither the name of The Regents or University of California nor the 17 | // names of its contributors may be used to endorse or promote products 18 | // derived from this software without specific prior written permission. 19 | // 20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE 24 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 | // POSSIBILITY OF SUCH DAMAGE. 31 | // 32 | // Please contact the author of this library if you have any questions. 33 | // Author: Chris Sweeney (cmsweeney@cs.ucsb.edu) 34 | 35 | #include "convolution.h" 36 | 37 | #include 38 | #include 39 | 40 | #ifdef AKAZE_USE_OPENMP 41 | #include 42 | #endif // AKAZE_USE_OPENMP 43 | 44 | namespace { 45 | 46 | using Eigen::Matrix; 47 | using Eigen::RowVectorXf; 48 | 49 | inline double Gaussian(double x, double mu, double sigma) { 50 | return std::exp(-(x - mu) * (x - mu) / (2.0 * sigma * sigma)); 51 | } 52 | 53 | } // namespace 54 | 55 | void SeparableConvolution2d(const RowMatrixXf& image, 56 | const Eigen::RowVectorXf& kernel_x, 57 | const Eigen::RowVectorXf& kernel_y, 58 | const BorderType& border_type, 59 | RowMatrixXf* out) { 60 | const int full_size = kernel_x.size(); 61 | const int half_size = full_size / 2; 62 | out->resize(image.rows(), image.cols()); 63 | 64 | // Convolving a vertical filter across rows is the same thing as transpose 65 | // multiply i.e. kernel_y^t * rows. This will give us the convoled value for 66 | // each row. However, care must be taken at the top and bottom borders. 67 | const RowVectorXf reverse_kernel_y = kernel_y.reverse(); 68 | 69 | if (border_type == REFLECT) { 70 | for (int i = 0; i < half_size; i++) { 71 | const int forward_size = i + half_size + 1; 72 | const int reverse_size = full_size - forward_size; 73 | out->row(i) = kernel_y.tail(forward_size) * 74 | image.block(0, 0, forward_size, image.cols()) + 75 | reverse_kernel_y.tail(reverse_size) * 76 | image.block(1, 0, reverse_size, image.cols()); 77 | 78 | // Apply the same technique for the end rows. 79 | // TODO(csweeney): Move this to its own loop for cache exposure? 80 | out->row(image.rows() - i - 1) = 81 | kernel_y.head(forward_size) * image.block(image.rows() - forward_size, 82 | 0, forward_size, 83 | image.cols()) + 84 | reverse_kernel_y.head(reverse_size) * 85 | image.block(image.rows() - reverse_size - 1, 0, reverse_size, 86 | image.cols()); 87 | } 88 | } else { 89 | // Perform border with REPLICATE as the option. 90 | for (int i = 0; i < half_size; i++) { 91 | const int forward_size = i + half_size + 1; 92 | const int reverse_size = full_size - forward_size; 93 | out->row(i) = kernel_y.tail(forward_size) * 94 | image.block(0, 0, forward_size, image.cols()) + 95 | reverse_kernel_y.tail(reverse_size) * 96 | image.row(0).replicate(reverse_size, 1); 97 | 98 | // Apply the same technique for the end rows. 99 | out->row(image.rows() - i - 1) = 100 | kernel_y.head(forward_size) * image.block(image.rows() - forward_size, 101 | 0, forward_size, 102 | image.cols()) + 103 | reverse_kernel_y.head(reverse_size) * 104 | image.row(image.rows() - 1).replicate(reverse_size, 1); 105 | } 106 | } 107 | 108 | // Applying the rest of the y filter. 109 | #ifdef AKAZE_USE_OPENMP 110 | #pragma omp parallel for 111 | #endif 112 | for (int row = half_size; row < image.rows() - half_size; row++) { 113 | out->row(row) = 114 | kernel_y * image.block(row - half_size, 0, full_size, out->cols()); 115 | } 116 | 117 | // Convolving with the horizontal filter is easy. Rather than using the kernel 118 | // as a sliding indow, we use the row pixels as a sliding window around the 119 | // filter. We prepend and append the proper border values so that we are sure 120 | // to end up with the correct convolved values. 121 | if (border_type == REFLECT) { 122 | RowVectorXf temp_row(image.cols() + full_size - 1); 123 | #ifdef AKAZE_USE_OPENMP 124 | #pragma omp parallel for firstprivate(temp_row) 125 | #endif 126 | for (int row = 0; row < out->rows(); row++) { 127 | temp_row.head(half_size) = 128 | out->row(row).segment(1, half_size).reverse(); 129 | temp_row.segment(half_size, image.cols()) = out->row(row); 130 | temp_row.tail(half_size) = 131 | out->row(row) 132 | .segment(image.cols() - 1 - half_size, half_size) 133 | .reverse(); 134 | 135 | // Convolve the row. We perform the first step here explicitly so that we 136 | // avoid setting the row equal to zero. 137 | out->row(row) = kernel_x(0) * temp_row.head(image.cols()); 138 | for (int i = 1; i < full_size; i++) { 139 | out->row(row) += kernel_x(i) * temp_row.segment(i, image.cols()); 140 | } 141 | } 142 | } else { 143 | RowVectorXf temp_row(image.cols() + full_size - 1); 144 | #ifdef AKAZE_USE_OPENMP 145 | #pragma omp parallel for firstprivate(temp_row) 146 | #endif 147 | for (int row = 0; row < out->rows(); row++) { 148 | temp_row.head(half_size).setConstant((*out)(row, 0)); 149 | temp_row.segment(half_size, image.cols()) = out->row(row); 150 | temp_row.tail(half_size).setConstant((*out)(row, out->cols() - 1)); 151 | 152 | // Convolve the row. We perform the first step here explicitly so that we 153 | // avoid setting the row equal to zero. 154 | out->row(row) = kernel_x(0) * temp_row.head(image.cols()); 155 | for (int i = 1; i < full_size; i++) { 156 | out->row(row) += kernel_x(i) * temp_row.segment(i, image.cols()); 157 | } 158 | } 159 | } 160 | } 161 | 162 | void ScharrDerivative(const RowMatrixXf& image, 163 | const int x_deg, 164 | const int y_deg, 165 | const int size, 166 | const bool normalize, 167 | RowMatrixXf* out) { 168 | const int sigma = size * 2 + 1; 169 | Eigen::RowVectorXf kernel1(sigma); 170 | kernel1.setZero(); 171 | kernel1(0) = -1.0; 172 | kernel1(sigma - 1) = 1.0; 173 | 174 | Eigen::RowVectorXf kernel2(sigma); 175 | kernel2.setZero(); 176 | if (!normalize) { 177 | kernel2(0) = 3; 178 | kernel2(sigma / 2) = 10; 179 | kernel2(sigma - 1) = 3; 180 | } else { 181 | float w = 10.0 / 3.0; 182 | float norm = 1.0 / (2.0 * size * (w + 2.0)); 183 | kernel2(0) = norm; 184 | kernel2(sigma / 2) = w * norm; 185 | kernel2(sigma - 1) = norm; 186 | } 187 | 188 | if (x_deg == 1) { 189 | SeparableConvolution2d(image, kernel1, kernel2, REFLECT, out); 190 | } else { 191 | SeparableConvolution2d(image, kernel2, kernel1, REFLECT, out); 192 | } 193 | return; 194 | } 195 | 196 | void GaussianBlur(const RowMatrixXf& image, 197 | const double sigma, 198 | RowMatrixXf* out) { 199 | int kernel_size = std::ceil(((sigma - 0.8) / 0.3 + 1.0) * 2.0); 200 | if (kernel_size % 2 == 0) { 201 | kernel_size += 1; 202 | } 203 | 204 | RowVectorXf gauss_kernel(kernel_size); 205 | double norm_factor = 0; 206 | for (int i = 0; i < gauss_kernel.size(); i++) { 207 | gauss_kernel(i) = Gaussian(i, (kernel_size - 1.0) / 2.0, sigma); 208 | norm_factor += gauss_kernel(i); 209 | } 210 | gauss_kernel /= norm_factor; 211 | 212 | SeparableConvolution2d(image, 213 | gauss_kernel, 214 | gauss_kernel, 215 | REPLICATE, 216 | out); 217 | } 218 | -------------------------------------------------------------------------------- /cmake/OptimizeCompilerFlags.cmake: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2013 The Regents of the University of California (Regents). 2 | # All rights reserved. 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are 6 | # met: 7 | # 8 | # * Redistributions of source code must retain the above copyright 9 | # notice, this list of conditions and the following disclaimer. 10 | # 11 | # * Redistributions in binary form must reproduce the above 12 | # copyright notice, this list of conditions and the following 13 | # disclaimer in the documentation and/or other materials provided 14 | # with the distribution. 15 | # 16 | # * Neither the name of The Regents or University of California nor the 17 | # names of its contributors may be used to endorse or promote products 18 | # derived from this software without specific prior written permission. 19 | # 20 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE 24 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 | # POSSIBILITY OF SUCH DAMAGE. 31 | # 32 | # Please contact the author of this library if you have any questions. 33 | # Author: Chris Sweeney (cmsweeney@cs.ucsb.edu) 34 | # 35 | # These two methods are macros so that they can modify global parameters 36 | # (functions cannot do that easily with CMake). Much of the compilation 37 | # parameter setup was borrowed and possibly modified from Ceres Solver. 38 | macro(OptimizeCompilerFlags) 39 | # Change the default build type from Debug to Release, while still 40 | # supporting overriding the build type. 41 | # 42 | # The CACHE STRING logic here and elsewhere is needed to force CMake 43 | # to pay attention to the value of these variables. 44 | IF (NOT CMAKE_BUILD_TYPE) 45 | MESSAGE("-- No build type specified; defaulting to CMAKE_BUILD_TYPE=Release.") 46 | SET(CMAKE_BUILD_TYPE Release CACHE STRING 47 | "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel." 48 | FORCE) 49 | ELSE (NOT CMAKE_BUILD_TYPE) 50 | IF (CMAKE_BUILD_TYPE STREQUAL "Debug") 51 | MESSAGE("\n=================================================================================") 52 | MESSAGE("\n-- Build type: Debug. Performance will be terrible!") 53 | MESSAGE("-- Add -DCMAKE_BUILD_TYPE=Release to the CMake command line to get an optimized build.") 54 | MESSAGE("\n=================================================================================") 55 | ENDIF (CMAKE_BUILD_TYPE STREQUAL "Debug") 56 | ENDIF (NOT CMAKE_BUILD_TYPE) 57 | 58 | # Set the default Theia flags to an empty string. 59 | SET (THEIA_CXX_FLAGS) 60 | 61 | IF (CMAKE_BUILD_TYPE STREQUAL "Release") 62 | IF (CMAKE_COMPILER_IS_GNUCXX) 63 | # Linux 64 | IF (CMAKE_SYSTEM_NAME MATCHES "Linux") 65 | IF (NOT GCC_VERSION VERSION_LESS 4.2) 66 | SET (THEIA_CXX_FLAGS "${THEIA_CXX_FLAGS} -march=native -mtune=native") 67 | ENDIF (NOT GCC_VERSION VERSION_LESS 4.2) 68 | ENDIF (CMAKE_SYSTEM_NAME MATCHES "Linux") 69 | # Mac OS X 70 | IF (CMAKE_SYSTEM_NAME MATCHES "Darwin") 71 | SET (THEIA_CXX_FLAGS "${THEIA_CXX_FLAGS} -msse3") 72 | # Use of -fast only applicable for Apple's GCC 73 | # Assume this is being used if GCC version < 4.3 on OSX 74 | EXECUTE_PROCESS(COMMAND ${CMAKE_C_COMPILER} 75 | ARGS ${CMAKE_CXX_COMPILER_ARG1} -dumpversion 76 | OUTPUT_VARIABLE GCC_VERSION 77 | OUTPUT_STRIP_TRAILING_WHITESPACE) 78 | IF (GCC_VERSION VERSION_LESS 4.3) 79 | SET (THEIA_CXX_FLAGS "${THEIA_CXX_FLAGS} -fast") 80 | ENDIF (GCC_VERSION VERSION_LESS 4.3) 81 | ENDIF (CMAKE_SYSTEM_NAME MATCHES "Darwin") 82 | ENDIF (CMAKE_COMPILER_IS_GNUCXX) 83 | IF (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") 84 | # Use of -O3 requires use of gold linker & LLVM-gold plugin, which might 85 | # well not be present / in use and without which files will compile, but 86 | # not link ('file not recognized') so explicitly check for support 87 | INCLUDE(CheckCXXCompilerFlag) 88 | CHECK_CXX_COMPILER_FLAG("-O3" HAVE_LTO_SUPPORT) 89 | IF (HAVE_LTO_SUPPORT) 90 | MESSAGE(STATUS "Enabling link-time optimization (-O3)") 91 | SET(THEIA_CXX_FLAGS "${THEIA_CXX_FLAGS} -O3") 92 | ELSE () 93 | MESSAGE(STATUS "Compiler/linker does not support link-time optimization (-O3), disabling.") 94 | ENDIF (HAVE_LTO_SUPPORT) 95 | ENDIF () 96 | ENDIF (CMAKE_BUILD_TYPE STREQUAL "Release") 97 | 98 | # Set c++ standard to c++11 99 | if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") 100 | SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -stdlib=libc++") 101 | else() 102 | execute_process(COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION) 103 | if (GCC_VERSION VERSION_GREATER 4.7 OR GCC_VERSION VERSION_EQUAL 4.7) 104 | SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") 105 | elseif(GCC_VERSION VERSION_GREATER 4.3 OR GCC_VERSION VERSION_EQUAL 4.3) 106 | message(WARNING "C++0x activated. If you get any errors update to a compiler which fully supports C++11") 107 | add_definitions("-std=gnu++0x") 108 | SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++0x") 109 | elseif(NOT MSVC) 110 | message(FATAL_ERROR "C++11 needed. Therefore a gcc compiler with a version higher than 4.3 is needed.") 111 | endif() 112 | endif() 113 | 114 | SET (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${THEIA_CXX_FLAGS}") 115 | 116 | # After the tweaks for the compile settings, disable some warnings on MSVC. 117 | IF (MSVC) 118 | # Disable signed/unsigned int conversion warnings. 119 | ADD_DEFINITIONS("/wd4018") 120 | # Disable warning about using struct/class for the same symobl. 121 | ADD_DEFINITIONS("/wd4099") 122 | # Disable warning about the insecurity of using "std::copy". 123 | ADD_DEFINITIONS("/wd4996") 124 | # Disable performance warning about int-to-bool conversion. 125 | ADD_DEFINITIONS("/wd4800") 126 | # Disable performance warning about fopen insecurity. 127 | ADD_DEFINITIONS("/wd4996") 128 | # Disable warning about int64 to int32 conversion. Disabling 129 | # this warning may not be correct; needs investigation. 130 | # TODO(keir): Investigate these warnings in more detail. 131 | ADD_DEFINITIONS("/wd4244") 132 | # It's not possible to use STL types in DLL interfaces in a portable and 133 | # reliable way. However, that's what happens with Google Log and Google Flags 134 | # on Windows. MSVC gets upset about this and throws warnings that we can't do 135 | # much about. The real solution is to link static versions of Google Log and 136 | # Google Test, but that seems tricky on Windows. So, disable the warning. 137 | ADD_DEFINITIONS("/wd4251") 138 | 139 | # Google Flags doesn't have their DLL import/export stuff set up correctly, 140 | # which results in linker warnings. This is irrelevant for Theia, so ignore 141 | # the warnings. 142 | SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /ignore:4049") 143 | 144 | # Update the C/CXX flags for MSVC to use either the static or shared 145 | # C-Run Time (CRT) library based on the user option: MSVC_USE_STATIC_CRT. 146 | LIST(APPEND C_CXX_FLAGS 147 | CMAKE_CXX_FLAGS 148 | CMAKE_CXX_FLAGS_DEBUG 149 | CMAKE_CXX_FLAGS_RELEASE 150 | CMAKE_CXX_FLAGS_MINSIZEREL 151 | CMAKE_CXX_FLAGS_RELWITHDEBINFO) 152 | 153 | FOREACH(FLAG_VAR ${C_CXX_FLAGS}) 154 | IF (MSVC_USE_STATIC_CRT) 155 | # Use static CRT. 156 | IF (${FLAG_VAR} MATCHES "/MD") 157 | STRING(REGEX REPLACE "/MD" "/MT" ${FLAG_VAR} "${${FLAG_VAR}}") 158 | ENDIF (${FLAG_VAR} MATCHES "/MD") 159 | ELSE (MSVC_USE_STATIC_CRT) 160 | # Use shared, not static, CRT. 161 | IF (${FLAG_VAR} MATCHES "/MT") 162 | STRING(REGEX REPLACE "/MT" "/MD" ${FLAG_VAR} "${${FLAG_VAR}}") 163 | ENDIF (${FLAG_VAR} MATCHES "/MT") 164 | ENDIF (MSVC_USE_STATIC_CRT) 165 | ENDFOREACH() 166 | 167 | # Tuple sizes of 10 are used by Gtest. 168 | ADD_DEFINITIONS("-D_VARIADIC_MAX=10") 169 | ENDIF (MSVC) 170 | IF (UNIX) 171 | # GCC is not strict enough by default, so enable most of the warnings. 172 | SET(CMAKE_CXX_FLAGS 173 | "${CMAKE_CXX_FLAGS} -Werror=all -Werror=extra -Wno-unknown-pragmas -Wno-sign-compare -Wno-unused-parameter -Wno-missing-field-initializers") 174 | 175 | # Newer versions of GCC are sometimes too strict! 176 | IF (CMAKE_COMPILER_IS_GNUCXX) 177 | # Linux 178 | IF (NOT GCC_VERSION VERSION_LESS 4.8) 179 | SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-comment -Wno-unused-variable -Wno-unused-result -Wno-unused-but-set-variable -Wno-unused-local-typedefs -Wno-maybe-uninitialized") 180 | ENDIF (NOT GCC_VERSION VERSION_LESS 4.8) 181 | ENDIF (CMAKE_COMPILER_IS_GNUCXX) 182 | ENDIF (UNIX) 183 | 184 | endmacro(OptimizeCompilerFlags) 185 | -------------------------------------------------------------------------------- /cmake/CheckSSEFeatures.cmake: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Check for the presence of SSE and figure out the flags to use for it. 3 | macro(PCL_CHECK_FOR_SSE) 4 | set(SSE_FLAGS) 5 | 6 | # Test CLANG 7 | #if(CMAKE_COMPILER_IS_CLANG) 8 | # if(APPLE) 9 | # SET(SSE_FLAGS "${SSE_FLAGS} -march=native") 10 | # endif(APPLE) 11 | #endif(CMAKE_COMPILER_IS_CLANG) 12 | 13 | # Test GCC/G++ 14 | if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX) 15 | execute_process(COMMAND ${CMAKE_CXX_COMPILER} "-dumpversion" 16 | OUTPUT_VARIABLE GCC_VERSION_STRING) 17 | if(GCC_VERSION_STRING VERSION_GREATER 4.2 AND NOT APPLE AND NOT CMAKE_CROSSCOMPILING) 18 | SET(SSE_FLAGS "${SSE_FLAGS} -march=native") 19 | message(STATUS "Using CPU native flags for SSE optimization: ${SSE_FLAGS}") 20 | endif() 21 | endif() 22 | 23 | # Unfortunately we need to check for SSE to enable "-mfpmath=sse" alongside 24 | # "-march=native". The reason for this is that by default, 32bit architectures 25 | # tend to use the x87 FPU (which has 80 bit internal precision), thus leading 26 | # to different results than 64bit architectures which are using SSE2 (64 bit internal 27 | # precision). One solution would be to use "-ffloat-store" on 32bit (see 28 | # http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html), but that slows code down, 29 | # so the preferred solution is to try "-mpfmath=sse" first. 30 | include(CheckCXXSourceRuns) 31 | set(CMAKE_REQUIRED_FLAGS) 32 | 33 | check_cxx_source_runs(" 34 | #include 35 | int main() 36 | { 37 | void* mem = _mm_malloc (100, 16); 38 | return 0; 39 | }" 40 | HAVE_MM_MALLOC) 41 | 42 | check_cxx_source_runs(" 43 | #include 44 | int main() 45 | { 46 | void* mem; 47 | return posix_memalign (&mem, 16, 100); 48 | }" 49 | HAVE_POSIX_MEMALIGN) 50 | 51 | if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANG) 52 | set(CMAKE_REQUIRED_FLAGS "-msse4.2") 53 | endif(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANG) 54 | 55 | check_cxx_source_runs(" 56 | #include 57 | #include 58 | int main () 59 | { 60 | long long a[2] = { 1, 2 }; 61 | long long b[2] = { -1, 3 }; 62 | long long c[2]; 63 | __m128i va = _mm_loadu_si128 ((__m128i*)a); 64 | __m128i vb = _mm_loadu_si128 ((__m128i*)b); 65 | __m128i vc = _mm_cmpgt_epi64 (va, vb); 66 | 67 | _mm_storeu_si128 ((__m128i*)c, vc); 68 | if (c[0] == -1LL && c[1] == 0LL) 69 | return (0); 70 | else 71 | return (1); 72 | }" 73 | HAVE_SSE4_2_EXTENSIONS) 74 | 75 | if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANG) 76 | set(CMAKE_REQUIRED_FLAGS "-msse4.1") 77 | endif(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANG) 78 | 79 | check_cxx_source_runs(" 80 | #include 81 | int main () 82 | { 83 | __m128 a, b; 84 | float vals[4] = {1, 2, 3, 4}; 85 | const int mask = 123; 86 | a = _mm_loadu_ps (vals); 87 | b = a; 88 | b = _mm_dp_ps (a, a, mask); 89 | _mm_storeu_ps (vals,b); 90 | return (0); 91 | }" 92 | HAVE_SSE4_1_EXTENSIONS) 93 | 94 | if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANG) 95 | set(CMAKE_REQUIRED_FLAGS "-msse3") 96 | endif(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANG) 97 | 98 | check_cxx_source_runs(" 99 | #include 100 | int main () 101 | { 102 | __m128d a, b; 103 | double vals[2] = {0}; 104 | a = _mm_loadu_pd (vals); 105 | b = _mm_hadd_pd (a,a); 106 | _mm_storeu_pd (vals, b); 107 | return (0); 108 | }" 109 | HAVE_SSE3_EXTENSIONS) 110 | 111 | if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANG) 112 | set(CMAKE_REQUIRED_FLAGS "-msse2") 113 | elseif(MSVC AND NOT CMAKE_CL_64) 114 | set(CMAKE_REQUIRED_FLAGS "/arch:SSE2") 115 | endif(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANG) 116 | 117 | check_cxx_source_runs(" 118 | #include 119 | int main () 120 | { 121 | __m128d a, b; 122 | double vals[2] = {0}; 123 | a = _mm_loadu_pd (vals); 124 | b = _mm_add_pd (a,a); 125 | _mm_storeu_pd (vals,b); 126 | return (0); 127 | }" 128 | HAVE_SSE2_EXTENSIONS) 129 | 130 | if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANG) 131 | set(CMAKE_REQUIRED_FLAGS "-msse") 132 | elseif(MSVC AND NOT CMAKE_CL_64) 133 | set(CMAKE_REQUIRED_FLAGS "/arch:SSE") 134 | endif(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANG) 135 | 136 | check_cxx_source_runs(" 137 | #include 138 | int main () 139 | { 140 | __m128 a, b; 141 | float vals[4] = {0}; 142 | a = _mm_loadu_ps (vals); 143 | b = a; 144 | b = _mm_add_ps (a,b); 145 | _mm_storeu_ps (vals,b); 146 | return (0); 147 | }" 148 | HAVE_SSE_EXTENSIONS) 149 | 150 | set(CMAKE_REQUIRED_FLAGS) 151 | 152 | if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANG) 153 | if(HAVE_SSE4_2_EXTENSIONS) 154 | SET(SSE_FLAGS "${SSE_FLAGS} -msse4.2 -mfpmath=sse") 155 | message(STATUS "Found SSE4.2 extensions, using flags: ${SSE_FLAGS}") 156 | elseif(HAVE_SSE4_1_EXTENSIONS) 157 | SET(SSE_FLAGS "${SSE_FLAGS} -msse4.1 -mfpmath=sse") 158 | message(STATUS "Found SSE4.1 extensions, using flags: ${SSE_FLAGS}") 159 | elseif(HAVE_SSE3_EXTENSIONS) 160 | SET(SSE_FLAGS "${SSE_FLAGS} -msse3 -mfpmath=sse") 161 | message(STATUS "Found SSE3 extensions, using flags: ${SSE_FLAGS}") 162 | elseif(HAVE_SSE2_EXTENSIONS) 163 | SET(SSE_FLAGS "${SSE_FLAGS} -msse2 -mfpmath=sse") 164 | message(STATUS "Found SSE2 extensions, using flags: ${SSE_FLAGS}") 165 | elseif(HAVE_SSE_EXTENSIONS) 166 | SET(SSE_FLAGS "${SSE_FLAGS} -msse -mfpmath=sse") 167 | message(STATUS "Found SSE extensions, using flags: ${SSE_FLAGS}") 168 | else() 169 | # Setting -ffloat-store to alleviate 32bit vs 64bit discrepancies on non-SSE 170 | # platforms. 171 | set(SSE_FLAGS "-ffloat-store") 172 | message(STATUS "No SSE extensions found") 173 | endif() 174 | elseif(MSVC AND NOT CMAKE_CL_64) 175 | if(HAVE_SSE2_EXTENSIONS) 176 | SET(SSE_FLAGS "${SSE_FLAGS} /arch:SSE2") 177 | message(STATUS "Found SSE2 extensions, using flags: ${SSE_FLAGS}") 178 | elseif(HAVE_SSE_EXTENSIONS) 179 | SET(SSE_FLAGS "${SSE_FLAGS} /arch:SSE") 180 | message(STATUS "Found SSE extensions, using flags: ${SSE_FLAGS}") 181 | endif(HAVE_SSE2_EXTENSIONS) 182 | endif() 183 | 184 | set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${SSE_FLAGS}") 185 | set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${SSE_FLAGS}") 186 | set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${SSE_FLAGS}") 187 | 188 | endmacro(PCL_CHECK_FOR_SSE) 189 | 190 | ############################################################################### 191 | # Check for the presence of SSE 4.1 192 | macro(PCL_CHECK_FOR_SSE4_1) 193 | include(CheckCXXSourceRuns) 194 | set(CMAKE_REQUIRED_FLAGS) 195 | 196 | if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANG) 197 | set(CMAKE_REQUIRED_FLAGS "-msse4.1") 198 | endif(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANG) 199 | 200 | check_cxx_source_runs(" 201 | #include 202 | int main() 203 | { 204 | __m128 a, b; 205 | float vals[4] = {1, 2, 3, 4}; 206 | const int mask = 123; 207 | a = _mm_loadu_ps(vals); 208 | b = a; 209 | b = _mm_dp_ps (a, a, mask); 210 | _mm_storeu_ps(vals,b); 211 | return 0; 212 | }" 213 | HAVE_SSE4_1_EXTENSIONS) 214 | endmacro(PCL_CHECK_FOR_SSE4_1) 215 | 216 | ############################################################################### 217 | # Check for the presence of SSE 3 218 | macro(PCL_CHECK_FOR_SSE3) 219 | include(CheckCXXSourceRuns) 220 | set(CMAKE_REQUIRED_FLAGS) 221 | 222 | if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANG) 223 | set(CMAKE_REQUIRED_FLAGS "-msse3") 224 | endif(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANG) 225 | 226 | check_cxx_source_runs(" 227 | #include 228 | int main () 229 | { 230 | __m128d a, b; 231 | double vals[2] = {0}; 232 | a = _mm_loadu_pd (vals); 233 | b = _mm_hadd_pd (a,a); 234 | _mm_storeu_pd (vals, b); 235 | return (0); 236 | }" 237 | HAVE_SSE3_EXTENSIONS) 238 | endmacro(PCL_CHECK_FOR_SSE3) 239 | 240 | PCL_CHECK_FOR_SSE() 241 | PCL_CHECK_FOR_SSE3() 242 | PCL_CHECK_FOR_SSE4_1() -------------------------------------------------------------------------------- /src/AKAZE.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file AKAZE.h 3 | * @brief Main class for detecting and computing binary descriptors in an 4 | * accelerated nonlinear scale space 5 | * @date Oct 07, 2014 6 | * @author Pablo F. Alcantarilla, Jesus Nuevo 7 | */ 8 | 9 | #ifndef AKAZE_SRC_AKAZE_H_ 10 | #define AKAZE_SRC_AKAZE_H_ 11 | 12 | /* ************************************************************************* */ 13 | #include 14 | 15 | #include "AKAZEConfig.h" 16 | #include "fed.h" 17 | #include "nldiffusion_functions.h" 18 | #include 19 | /* ************************************************************************* */ 20 | namespace libAKAZE { 21 | 22 | // Keypoint struct intended to mimic OpenCV. 23 | struct AKAZEKeypoint { 24 | Eigen::Vector2f pt; 25 | float size; 26 | float angle; 27 | float response; 28 | int octave; 29 | int class_id; 30 | }; 31 | 32 | // Descriptor type used for the float descriptors. 33 | typedef Eigen::Matrix Vector64f; 34 | 35 | // This convenience typdef is used to hold binary descriptors such that each bit 36 | // is a value in the descriptor. 37 | typedef Eigen::Matrix BinaryVectorX; 38 | 39 | struct AKAZEDescriptors { 40 | std::vector float_descriptor; 41 | std::vector binary_descriptor; 42 | }; 43 | 44 | class AKAZE { 45 | private: 46 | // Configuration options for AKAZE 47 | AKAZEOptions options_; 48 | // Vector of nonlinear diffusion evolution 49 | std::vector evolution_; 50 | 51 | // FED parameters 52 | // Number of cycles 53 | int ncycles_; 54 | // Flag for reordering time steps 55 | bool reordering_; 56 | // Vector of FED dynamic time steps 57 | std::vector > tsteps_; 58 | // Vector of number of steps per cycle 59 | std::vector nsteps_; 60 | 61 | // Matrices for the M-LDB descriptor computation 62 | Eigen::MatrixXi descriptorSamples_; 63 | Eigen::MatrixXi descriptorBits_; 64 | 65 | // Computation times variables in ms 66 | AKAZETiming timing_; 67 | 68 | public: 69 | // AKAZE constructor with input options 70 | // @param options AKAZE configuration options 71 | // @note This constructor allocates memory for the nonlinear scale space 72 | AKAZE(const AKAZEOptions& options); 73 | 74 | // Destructor 75 | ~AKAZE(); 76 | 77 | // Allocate the memory for the nonlinear scale space 78 | void Allocate_Memory_Evolution(); 79 | 80 | // This method creates the nonlinear scale space for a given image 81 | // @param img Input image for which the nonlinear scale space needs to be 82 | // created 83 | // @return 0 if the nonlinear scale space was created successfully, -1 84 | // otherwise 85 | int Create_Nonlinear_Scale_Space(const RowMatrixXf& img); 86 | 87 | // @brief This method selects interesting keypoints through the nonlinear 88 | // scale space 89 | // @param kpts Vector of detected keypoints 90 | void Feature_Detection(std::vector& kpts); 91 | 92 | // This method computes the feature detector response for the nonlinear scale 93 | // space 94 | // @note We use the Hessian determinant as the feature detector response 95 | void Compute_Determinant_Hessian_Response(); 96 | 97 | // This method computes the multiscale derivatives for the nonlinear scale 98 | // space 99 | void Compute_Multiscale_Derivatives(); 100 | 101 | // This method finds extrema in the nonlinear scale space 102 | void Find_Scale_Space_Extrema(std::vector& kpts); 103 | 104 | // This method performs subpixel refinement of the detected keypoints fitting 105 | // a quadratic 106 | void Do_Subpixel_Refinement(std::vector& kpts); 107 | 108 | // Feature description methods. 109 | void Compute_Descriptors(std::vector& kpts, 110 | AKAZEDescriptors& desc); 111 | 112 | // This method computes the main orientation for a given keypoint 113 | // @param kpt Input keypoint 114 | // @note The orientation is computed using a similar approach as described in 115 | // the original SURF method. 116 | // See Bay et al., Speeded Up Robust Features, ECCV 2006. 117 | // A-KAZE uses first order derivatives computed from the nonlinear scale 118 | // space in contrast to Haar wavelets 119 | void Compute_Main_Orientation(AKAZEKeypoint& kpt) const; 120 | 121 | // Compute the upright descriptor (not rotation invariant) for the provided 122 | // keypoint using a 123 | // rectangular grid similar as the one used in SURF 124 | // @param kpt Input keypoint 125 | // @param desc Floating-based descriptor 126 | // @note Rectangular grid of 20 s x 20 s. Descriptor Length 64. No additional 127 | // Gaussian weighting is performed. The descriptor is inspired from Bay et 128 | // al., 129 | // Speeded Up Robust Features, ECCV, 2006 130 | void Get_SURF_Descriptor_Upright_64(const AKAZEKeypoint& kpt, 131 | Vector64f& desc) const; 132 | 133 | // Compute the rotation invariant descriptor for the provided keypoint using 134 | // a 135 | // rectangular grid similar as the one used in SURF 136 | // @param kpt Input keypoint 137 | // @param desc Floating-based descriptor 138 | // @note Rectangular grid of 20 s x 20 s. Descriptor Length 64. No additional 139 | // Gaussian weighting is performed. The descriptor is inspired from Bay et 140 | // al., 141 | // Speeded Up Robust Features, ECCV, 2006 142 | void Get_SURF_Descriptor_64(const AKAZEKeypoint& kpt, Vector64f& desc) const; 143 | 144 | // Compute the upright descriptor (not rotation invariant) for the provided 145 | // keypoint using a 146 | // rectangular grid similar as the one used in M-SURF 147 | // @param kpt Input keypoint 148 | // @param desc Floating-based descriptor 149 | // @note Rectangular grid of 24 s x 24 s. Descriptor Length 64. The 150 | // descriptor is inspired 151 | // from Agrawal et al., CenSurE: Center Surround Extremas for Realtime 152 | // Feature Detection and Matching, 153 | // ECCV 2008 154 | void Get_MSURF_Upright_Descriptor_64(const AKAZEKeypoint& kpt, 155 | Vector64f& desc) const; 156 | 157 | // Compute the rotation invariant descriptor for the provided keypoint using 158 | // a rectangular grid similar as the one used in M-SURF 159 | // @param kpt Input keypoint 160 | // @param desc Floating-based descriptor 161 | // @note Rectangular grid of 24 s x 24 s. Descriptor Length 64. The 162 | // descriptor is inspired 163 | // from Agrawal et al., CenSurE: Center Surround Extremas for Realtime 164 | // Feature Detection and Matching, 165 | // ECCV 2008 166 | void Get_MSURF_Descriptor_64(const AKAZEKeypoint& kpt, Vector64f& desc) const; 167 | 168 | // Compute the upright (not rotation invariant) M-LDB binary descriptor 169 | // (maximum descriptor length) 170 | // @param kpt Input keypoint 171 | // @param desc Binary-based descriptor 172 | void Get_Upright_MLDB_Full_Descriptor(const AKAZEKeypoint& kpt, 173 | unsigned char* desc) const; 174 | 175 | // Computes the rotation invariant M-LDB binary descriptor (maximum 176 | // descriptor length) 177 | // @param kpt Input keypoint 178 | // @param desc Binary-based descriptor 179 | void Get_MLDB_Full_Descriptor(const AKAZEKeypoint& kpt, 180 | unsigned char* desc) const; 181 | /// Compute the upright (not rotation invariant) M-LDB binary descriptor 182 | /// (specified descriptor length) 183 | /// @param kpt Input keypoint 184 | /// @param desc Binary-based descriptor 185 | void Get_Upright_MLDB_Descriptor_Subset(const AKAZEKeypoint& kpt, 186 | unsigned char* desc); 187 | 188 | /// Computes the rotation invariant M-LDB binary descriptor (specified 189 | /// descriptor length) 190 | /// @param kpt Input keypoint 191 | /// @param desc Binary-based descriptor 192 | void Get_MLDB_Descriptor_Subset(const AKAZEKeypoint& kpt, 193 | unsigned char* desc); 194 | 195 | // Fill the comparison values for the MLDB rotation invariant descriptor 196 | void MLDB_Fill_Values(float* values, int sample_step, int level, float xf, 197 | float yf, float co, float si, float scale) const; 198 | 199 | // Fill the comparison values for the MLDB upright descriptor 200 | void MLDB_Fill_Upright_Values(float* values, int sample_step, int level, 201 | float xf, float yf, float scale) const; 202 | 203 | // Do the binary comparisons to obtain the descriptor 204 | void MLDB_Binary_Comparisons(float* values, unsigned char* desc, int count, 205 | int& dpos) const; 206 | 207 | // This method saves the scale space into jpg images 208 | void Save_Scale_Space(); 209 | 210 | // This method saves the feature detector responses of the nonlinear scale 211 | // space into jpg images 212 | void Save_Detector_Responses(); 213 | 214 | // Display timing information 215 | void Show_Computation_Times() const; 216 | 217 | // Return the computation times 218 | AKAZETiming Get_Computation_Times() const { return timing_; } 219 | }; 220 | 221 | /* ************************************************************************* */ 222 | 223 | // This function sets default parameters for the A-KAZE detector 224 | void setDefaultAKAZEOptions(AKAZEOptions& options); 225 | 226 | /// This function computes a (quasi-random) list of bits to be taken 227 | /// from the full descriptor. To speed the extraction, the function creates 228 | /// a list of the samples that are involved in generating at least a bit 229 | /// (sampleList) 230 | /// and a list of the comparisons between those samples (comparisons) 231 | /// @param sampleList 232 | /// @param comparisons The matrix with the binary comparisons 233 | /// @param nbits The number of bits of the descriptor 234 | /// @param pattern_size The pattern size for the binary descriptor 235 | /// @param nchannels Number of channels to consider in the descriptor (1-3) 236 | /// @note The function keeps the 18 bits (3-channels by 6 comparisons) of the 237 | /// coarser grid, since it provides the most robust estimations 238 | void generateDescriptorSubsample(Eigen::MatrixXi& sampleList, 239 | Eigen::MatrixXi& comparisons, int nbits, 240 | int pattern_size, int nchannels); 241 | 242 | // This function checks descriptor limits for a given keypoint 243 | inline void check_descriptor_limits(int& x, int& y, int width, int height); 244 | 245 | // This function computes the value of a 2D Gaussian function 246 | inline float gaussian(float x, float y, float sigma) { 247 | return expf(-(x * x + y * y) / (2.0f * sigma * sigma)); 248 | } 249 | 250 | // This funtion rounds float to nearest integer 251 | inline int fRound(float flt) { return (int)(flt + 0.5f); } 252 | 253 | } // namespace libAKAZE 254 | 255 | #endif // AKAZE_SRC_AKAZE_H_ 256 | -------------------------------------------------------------------------------- /akaze_match.cpp: -------------------------------------------------------------------------------- 1 | //============================================================================= 2 | // 3 | // akaze_match.cpp 4 | // Authors: Pablo F. Alcantarilla (1), Jesus Nuevo (2) 5 | // Institutions: Toshiba Research Europe Ltd (1) 6 | // TrueVision Solutions (2) 7 | // Date: 07/10/2014 8 | // Email: pablofdezalc@gmail.com 9 | // 10 | // AKAZE Features Copyright 2014, Pablo F. Alcantarilla, Jesus Nuevo 11 | // All Rights Reserved 12 | // See LICENSE for the license information 13 | //============================================================================= 14 | 15 | /** 16 | * @file akaze_match.cpp 17 | * @brief Main program for matching two images with AKAZE features 18 | * @date Oct 07, 2014 19 | * @author Pablo F. Alcantarilla 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | #include "cimg/CImg.h" 27 | #include "src/AKAZE.h" 28 | #include "src/AKAZEConfig.h" 29 | #include "src/utils.h" 30 | #include "timer/timer.hpp" 31 | 32 | /* ************************************************************************* */ 33 | // Image matching options 34 | const float MIN_H_ERROR = 35 | 2.50f; ///< Maximum error in pixels to accept an inlier 36 | const float DRATIO = 0.80f; ///< NNDR Matching value 37 | 38 | /* ************************************************************************* */ 39 | /** 40 | * @brief This function parses the command line arguments for setting A-KAZE 41 | * parameters 42 | * and image matching between two input images 43 | * @param options Structure that contains A-KAZE settings 44 | * @param img_path1 Path for the first input image 45 | * @param img_path2 Path for the second input image 46 | * @param homography_path Path for the file that contains the ground truth 47 | * homography 48 | */ 49 | int parse_input_options(libAKAZE::AKAZEOptions& options, std::string& img_path1, 50 | std::string& img_path2, std::string& homography_path, 51 | int argc, char* argv[]); 52 | 53 | /* ************************************************************************* */ 54 | int main(int argc, char* argv[]) { 55 | // Variables 56 | libAKAZE::AKAZEOptions options; 57 | std::string img_path1, img_path2, homography_path; 58 | float ratio = 0.0; 59 | int nkpts1 = 0, nkpts2 = 0, nmatches = 0, ninliers = 0, noutliers = 0; 60 | 61 | std::vector kpts1, kpts2; 62 | std::vector > dmatches; 63 | libAKAZE::AKAZEDescriptors desc1, desc2; 64 | Eigen::Matrix3f HG; 65 | 66 | // Variables for measuring computation times 67 | double takaze = 0.0, tmatch = 0.0; 68 | 69 | // Parse the input command line options 70 | if (parse_input_options(options, img_path1, img_path2, homography_path, argc, 71 | argv)) { 72 | return -1; 73 | } 74 | 75 | // Read image 1 and if necessary convert to grayscale. 76 | cimg_library::CImg img1(img_path1.c_str()); 77 | cimg_library::CImg img2(img_path2.c_str()); 78 | 79 | // Read ground truth homography file 80 | if (read_homography(homography_path, HG) == false) { 81 | std::cout << "Invalid homography file!" << std::endl; 82 | return -1; 83 | } 84 | 85 | // Convert the images to float 86 | RowMatrixXf img1_32, img2_32; 87 | ConvertCImgToEigen(img1, img1_32); 88 | img1_32 /= 255.0; 89 | ConvertCImgToEigen(img2, img2_32); 90 | img2_32 /= 255.0; 91 | 92 | // Create the first AKAZE object 93 | options.img_width = img1.width(); 94 | options.img_height = img1.height(); 95 | libAKAZE::AKAZE evolution1(options); 96 | 97 | // Create the second HKAZE object 98 | options.img_width = img2.width(); 99 | options.img_height = img2.height(); 100 | libAKAZE::AKAZE evolution2(options); 101 | 102 | timer::Timer timer; 103 | 104 | // Create the nonlinear scale space 105 | // and perform feature detection and description for image 1 106 | evolution1.Create_Nonlinear_Scale_Space(img1_32); 107 | evolution1.Feature_Detection(kpts1); 108 | evolution1.Compute_Descriptors(kpts1, desc1); 109 | evolution2.Create_Nonlinear_Scale_Space(img2_32); 110 | evolution2.Feature_Detection(kpts2); 111 | evolution2.Compute_Descriptors(kpts2, desc2); 112 | 113 | takaze = timer.elapsedMs(); 114 | 115 | nkpts1 = kpts1.size(); 116 | nkpts2 = kpts2.size(); 117 | 118 | // Matching Descriptors!! 119 | std::vector > matches, inliers; 120 | timer.reset(); 121 | if (options.descriptor < libAKAZE::MLDB_UPRIGHT) { 122 | match_features(desc1.float_descriptor, desc2.float_descriptor, DRATIO, 123 | matches); 124 | } 125 | // Binary descriptor, use Hamming distance 126 | else { 127 | match_features(desc1.binary_descriptor, desc2.binary_descriptor, DRATIO, 128 | matches); 129 | } 130 | 131 | tmatch = timer.elapsedMs(); 132 | 133 | // Compute Inliers!! 134 | compute_inliers_homography(kpts1, kpts2, matches, inliers, HG, MIN_H_ERROR); 135 | 136 | // Compute the inliers statistics 137 | nmatches = matches.size(); 138 | ninliers = inliers.size(); 139 | noutliers = nmatches - ninliers; 140 | ratio = 100.0 * ((float)ninliers / (float)nmatches); 141 | 142 | // Show matching statistics 143 | std::cout << "Number of Keypoints Image 1: " << nkpts1 << std::endl; 144 | std::cout << "Number of Keypoints Image 2: " << nkpts2 << std::endl; 145 | std::cout << "A-KAZE Features Extraction Time (ms): " << takaze << std::endl; 146 | std::cout << "Matching Descriptors Time (ms): " << tmatch << std::endl; 147 | std::cout << "Number of Matches: " << nmatches << std::endl; 148 | std::cout << "Number of Inliers: " << ninliers << std::endl; 149 | std::cout << "Number of Outliers: " << noutliers << std::endl; 150 | std::cout << "Inliers Ratio: " << ratio << std::endl << std::endl; 151 | 152 | cimg_library::CImg img1_rgb = 153 | img1.get_resize(img1.width(), img1.height(), img1.depth(), 3); 154 | cimg_library::CImg img2_rgb = 155 | img2.get_resize(img2.width(), img2.height(), img2.depth(), 3); 156 | draw_keypoints(img1_rgb, kpts1); 157 | draw_keypoints(img2_rgb, kpts2); 158 | cimg_library::CImg matched_image; 159 | draw_matches(img1_rgb, img2_rgb, kpts1, kpts2, inliers, matched_image); 160 | matched_image.save("../output/matched_images.jpg"); 161 | } 162 | 163 | /* ************************************************************************* */ 164 | int parse_input_options(libAKAZE::AKAZEOptions& options, std::string& img_path1, 165 | std::string& img_path2, std::string& homography_path, 166 | int argc, char* argv[]) { 167 | 168 | // If there is only one argument return 169 | if (argc == 1) { 170 | show_input_options_help(1); 171 | return -1; 172 | } 173 | // Set the options from the command line 174 | else if (argc >= 2) { 175 | 176 | // Load the default options 177 | options = libAKAZE::AKAZEOptions(); 178 | 179 | if (!strcmp(argv[1], "--help")) { 180 | show_input_options_help(1); 181 | return -1; 182 | } 183 | 184 | img_path1 = argv[1]; 185 | img_path2 = argv[2]; 186 | 187 | if (argc >= 4) homography_path = argv[3]; 188 | 189 | for (int i = 3; i < argc; i++) { 190 | if (!strcmp(argv[i], "--num_threads")) { 191 | i = i + 1; 192 | options.num_threads = atoi(argv[i]); 193 | } else if (!strcmp(argv[i], "--soffset")) { 194 | i = i + 1; 195 | if (i >= argc) { 196 | std::cerr << "Error introducing input options!!" << std::endl; 197 | return -1; 198 | } else { 199 | options.soffset = atof(argv[i]); 200 | } 201 | } else if (!strcmp(argv[i], "--omax")) { 202 | i = i + 1; 203 | if (i >= argc) { 204 | std::cerr << "Error introducing input options!!" << std::endl; 205 | return -1; 206 | } else { 207 | options.omax = atof(argv[i]); 208 | } 209 | } else if (!strcmp(argv[i], "--dthreshold")) { 210 | i = i + 1; 211 | if (i >= argc) { 212 | std::cerr << "Error introducing input options!!" << std::endl; 213 | return -1; 214 | } else { 215 | options.dthreshold = atof(argv[i]); 216 | } 217 | } else if (!strcmp(argv[i], "--sderivatives")) { 218 | i = i + 1; 219 | if (i >= argc) { 220 | std::cerr << "Error introducing input options!!" << std::endl; 221 | return -1; 222 | } else { 223 | options.sderivatives = atof(argv[i]); 224 | } 225 | } else if (!strcmp(argv[i], "--nsublevels")) { 226 | i = i + 1; 227 | if (i >= argc) { 228 | std::cerr << "Error introducing input options!!" << std::endl; 229 | return -1; 230 | } else { 231 | options.nsublevels = atoi(argv[i]); 232 | } 233 | } else if (!strcmp(argv[i], "--diffusivity")) { 234 | i = i + 1; 235 | if (i >= argc) { 236 | std::cerr << "Error introducing input options!!" << std::endl; 237 | return -1; 238 | } else { 239 | options.diffusivity = libAKAZE::DIFFUSIVITY_TYPE(atoi(argv[i])); 240 | } 241 | } else if (!strcmp(argv[i], "--descriptor")) { 242 | i = i + 1; 243 | if (i >= argc) { 244 | std::cerr << "Error introducing input options!!" << std::endl; 245 | return -1; 246 | } else { 247 | options.descriptor = libAKAZE::DESCRIPTOR_TYPE(atoi(argv[i])); 248 | 249 | if (options.descriptor < 0 || options.descriptor > libAKAZE::MLDB) { 250 | options.descriptor = libAKAZE::MLDB; 251 | } 252 | } 253 | } else if (!strcmp(argv[i], "--descriptor_channels")) { 254 | i = i + 1; 255 | if (i >= argc) { 256 | std::cerr << "Error introducing input options!!" << std::endl; 257 | return -1; 258 | } else { 259 | options.descriptor_channels = atoi(argv[i]); 260 | 261 | if (options.descriptor_channels <= 0 || 262 | options.descriptor_channels > 3) { 263 | options.descriptor_channels = 3; 264 | } 265 | } 266 | } else if (!strcmp(argv[i], "--descriptor_size")) { 267 | i = i+1; 268 | if (i >= argc) { 269 | std::cerr << "Error introducing input options!!" << std::endl; 270 | return -1; 271 | } 272 | else { 273 | options.descriptor_size = atoi(argv[i]); 274 | 275 | if (options.descriptor_size < 0) { 276 | options.descriptor_size = 0; 277 | } 278 | } 279 | } else if (!strcmp(argv[i], "--verbose")) { 280 | options.verbosity = true; 281 | } else if (!strncmp(argv[i], "--", 2)) 282 | std::cerr << "Unknown command " << argv[i] << std::endl; 283 | } 284 | } else { 285 | std::cerr << "Error introducing input options!!" << std::endl; 286 | show_input_options_help(1); 287 | return -1; 288 | } 289 | 290 | return 0; 291 | } 292 | -------------------------------------------------------------------------------- /cimg/cmake-modules/FindNetCDF.cmake: -------------------------------------------------------------------------------- 1 | # -*- mode: cmake -*- 2 | 3 | # 4 | # MSTK NetCDF Find Module 5 | # Shamelessly stolen from Amanzi open source code https://software.lanl.gov/ascem/trac 6 | # 7 | # Usage: 8 | # Control the search through NetCDF_DIR or setting environment variable 9 | # NetCDF_ROOT to the NetCDF installation prefix. 10 | # 11 | # This module does not search default paths! 12 | # 13 | # Following variables are set: 14 | # NetCDF_FOUND (BOOL) Flag indicating if NetCDF was found 15 | # NetCDF_INCLUDE_DIR (PATH) Path to the NetCDF include file 16 | # NetCDF_INCLUDE_DIRS (LIST) List of all required include files 17 | # NetCDF_LIBRARY_DIR (PATH) Path to the NetCDF library 18 | # NetCDF_LIBRARY (FILE) NetCDF library 19 | # NetCDF_LIBRARIES (LIST) List of all required NetCDF libraries 20 | # 21 | # Additional variables set 22 | # NetCDF_C_LIBRARY (FILE) NetCDF C library 23 | # NetCDF_CXX_LIBRARY (FILE) NetCDF C++ library 24 | # NetCDF_LARGE_DIMS (BOOL) Checks the header files for size of 25 | # NC_MAX_DIMS, NC_MAX_VARS and NC_MAX_VARS_DIMS 26 | # Returns TRUE if 27 | # NC_MAX_DIMS >= 655363 28 | # NC_MAX_VARS >= 524288 29 | # NC_MAX_VAR_DIMS >= 8 30 | # 31 | # ############################################################################# 32 | 33 | # Standard CMake modules see CMAKE_ROOT/Modules 34 | include(FindPackageHandleStandardArgs) 35 | 36 | # MSTK CMake functions see /cmake/modules for source 37 | #include(PrintVariable) 38 | #include(AddPackageDependency) 39 | 40 | 41 | set (NetCDF_INCLUDE_DIR /usr/include /usr/local/include /usr/local/bic/include /opt/minc-toolkit/include) 42 | set (NetCDF_LIBRARY_DIR /usr/lib /usr/local/lib /usr/local/bic/lib /opt/minc-toolkit/include) 43 | 44 | if ( NetCDF_LIBRARIES AND NetCDF_INCLUDE_DIRS ) 45 | 46 | # Do nothing. Variables are set. No need to search again 47 | 48 | else(NetCDF_LIBRARIES AND NetCDF_INCLUDE_DIRS) 49 | 50 | # Cache variables 51 | if(NetCDF_DIR) 52 | set(NetCDF_DIR "${NetCDF_DIR}" CACHE PATH "Path to search for NetCDF include and library files") 53 | endif() 54 | 55 | if(NetCDF_INCLUDE_DIR) 56 | set(NetCDF_INCLUDE_DIR "${NetCDF_INCLUDE_DIR}" CACHE PATH "Path to search for NetCDF include files") 57 | endif() 58 | 59 | if(NetCDF_LIBRARY_DIR) 60 | set(NetCDF_LIBRARY_DIR "${NetCDF_LIBRARY_DIR}" CACHE PATH "Path to search for NetCDF library files") 61 | endif() 62 | 63 | 64 | # Search for include files 65 | # Search order preference: 66 | # (1) NetCDF_INCLUDE_DIR - check existence of path AND if the include files exist 67 | # (2) NetCDF_DIR/ 68 | # (3) Default CMake paths See cmake --html-help=out.html file for more information. 69 | # 70 | set(netcdf_inc_names "netcdf.h") 71 | if (NetCDF_INCLUDE_DIR) 72 | 73 | # if (EXISTS "${NetCDF_INCLUDE_DIR}") 74 | 75 | find_path(cdf_test_include_path 76 | NAMES ${netcdf_inc_names} 77 | HINTS ${NetCDF_INCLUDE_DIR} 78 | NO_DEFAULT_PATH) 79 | if(NOT cdf_test_include_path) 80 | message(SEND_ERROR "Can not locate ${netcdf_inc_names} in ${NetCDF_INCLUDE_DIR}") 81 | endif() 82 | set(NetCDF_INCLUDE_DIR "${cdf_test_include_path}") 83 | 84 | # else() 85 | # message(SEND_ERROR "NetCDF_INCLUDE_DIR=${NetCDF_INCLUDE_DIR} does not exist") 86 | # set(NetCDF_INCLUDE_DIR "NetCDF_INCLUDE_DIR-NOTFOUND") 87 | # endif() 88 | 89 | else() 90 | 91 | set(netcdf_inc_suffixes "include") 92 | if(NetCDF_DIR) 93 | 94 | # if (EXISTS "${NetCDF_DIR}" ) 95 | 96 | find_path(NetCDF_INCLUDE_DIR 97 | NAMES ${netcdf_inc_names} 98 | HINTS ${NetCDF_DIR} 99 | PATH_SUFFIXES ${netcdf_inc_suffixes} 100 | NO_DEFAULT_PATH) 101 | 102 | # else() 103 | # message(SEND_ERROR "NetCDF_DIR=${NetCDF_DIR} does not exist") 104 | # set(NetCDF_INCLUDE_DIR "NetCDF_INCLUDE_DIR-NOTFOUND") 105 | # endif() 106 | 107 | 108 | else() 109 | 110 | find_path(NetCDF_INCLUDE_DIR 111 | NAMES ${netcdf_inc_names} 112 | PATH_SUFFIXES ${netcdf_inc_suffixes}) 113 | 114 | endif() 115 | 116 | endif() 117 | 118 | 119 | if ( NOT NetCDF_INCLUDE_DIR ) 120 | message(SEND_ERROR "Can not locate NetCDF include directory") 121 | endif() 122 | 123 | # # Large dimension check here 124 | # if ( NetCDF_INCLUDE_DIR ) 125 | 126 | # set(netcdf_h "${NetCDF_INCLUDE_DIR}/netcdf.h" ) 127 | # message(STATUS "NetCDF include file ${netcdf_h} will be searched for define values") 128 | 129 | # file(STRINGS "${netcdf_h}" netcdf_max_dims_string REGEX "^#define NC_MAX_DIMS") 130 | # string(REGEX REPLACE "[^0-9]" "" netcdf_max_dims "${netcdf_max_dims_string}") 131 | 132 | # file(STRINGS "${netcdf_h}" netcdf_max_vars_string REGEX "^#define NC_MAX_VARS") 133 | # string(REGEX REPLACE "[^0-9]" "" netcdf_max_vars "${netcdf_max_vars_string}") 134 | 135 | # file(STRINGS "${netcdf_h}" netcdf_max_var_dims_string REGEX "^#define NC_MAX_VAR_DIMS") 136 | # string(REGEX REPLACE "[^0-9]" "" netcdf_max_var_dims "${netcdf_max_var_dims_string}") 137 | 138 | # #PRINT_VARIABLE(netcdf_max_dims_string) 139 | # #PRINT_VARIABLE(netcdf_max_dims) 140 | # #PRINT_VARIABLE(netcdf_max_vars) 141 | # #PRINT_VARIABLE(netcdf_max_var_dims) 142 | 143 | # if ( 144 | # ( (netcdf_max_dims EQUAL 65536) OR (netcdf_max_dims GREATER 65536) ) AND 145 | # ( (netcdf_max_vars EQUAL 524288) OR (netcdf_max_vars GREATER 524288) ) AND 146 | # ( (netcdf_max_var_dims EQUAL 8) OR (netcdf_max_var_dims GREATER 8) ) 147 | 148 | # ) 149 | # set(NetCDF_LARGE_DIMS TRUE) 150 | # else() 151 | # message(WARNING "The NetCDF found in ${NetCDF_DIR} does not have the correct NC_MAX_DIMS, NC_MAX_VARS and NC_MAX_VAR_DIMS\n" 152 | # "It may not be compatible with other TPL libraries such MOAB and ExodusII\n" ) 153 | # set(NetCDF_LARGE_DIMS FALSE) 154 | # endif() 155 | 156 | # endif() 157 | 158 | # Search for libraries 159 | # Search order preference: 160 | # (1) NetCDF_LIBRARY_DIR - check existence of path AND if the include files exist 161 | # (2) NetCDF_DIR/ 162 | # (3) Default CMake paths See cmake --html-help=out.html file for more information. 163 | # 164 | if (NetCDF_LIBRARY_DIR) 165 | 166 | # if (EXISTS "${NetCDF_LIBRARY_DIR}") 167 | 168 | find_library(NetCDF_C_LIBRARY 169 | NAMES netcdf 170 | HINTS ${NetCDF_LIBRARY_DIR} 171 | NO_DEFAULT_PATH) 172 | 173 | find_library(NetCDF_CXX_LIBRARY 174 | NAMES netcdf_c++ 175 | HINTS ${NetCDF_LIBRARY_DIR} 176 | NO_DEFAULT_PATH) 177 | 178 | # else() 179 | # message(SEND_ERROR "NetCDF_LIBRARY_DIR=${NetCDF_LIBRARY_DIR} does not exist") 180 | # set(NetCDF_LIBRARY "NetCDF_C_LIBRARY-NOTFOUND") 181 | # set(NetCDF_LIBRARY "NetCDF_CXX_LIBRARY-NOTFOUND") 182 | # endif() 183 | 184 | else() 185 | 186 | if(NetCDF_DIR) 187 | 188 | # if (EXISTS "${NetCDF_DIR}" ) 189 | 190 | find_library(NetCDF_C_LIBRARY 191 | NAMES netcdf 192 | HINTS ${NetCDF_DIR} 193 | PATH_SUFFIXES "lib" "Lib" 194 | NO_DEFAULT_PATH) 195 | 196 | find_library(NetCDF_CXX_LIBRARY 197 | NAMES netcdf_c++ 198 | HINTS ${NetCDF_DIR} 199 | PATH_SUFFIXES "lib" "Lib" 200 | NO_DEFAULT_PATH) 201 | 202 | # else() 203 | # message(SEND_ERROR "NetCDF_DIR=${NetCDF_DIR} does not exist") 204 | # set(NetCDF_LIBRARY "NetCDF_C_LIBRARY-NOTFOUND") 205 | # set(NetCDF_LIBRARY "NetCDF_CXX_LIBRARY-NOTFOUND") 206 | # endif() 207 | 208 | 209 | else() 210 | 211 | find_library(NetCDF_C_LIBRARY 212 | NAMES netcdf 213 | PATH_SUFFIXES ${netcdf_lib_suffixes}) 214 | 215 | find_library(NetCDF_CXX_LIBRARY 216 | NAMES netcdf_c++ 217 | PATH_SUFFIXES ${netcdf_lib_suffixes}) 218 | 219 | 220 | endif() 221 | 222 | endif() 223 | 224 | if ( NOT NetCDF_C_LIBRARY ) 225 | message(SEND_ERROR "Can not locate NetCDF C library") 226 | endif() 227 | 228 | # if ( NOT NetCDF_CXX_LIBRARY ) 229 | # message(SEND_ERROR "Can not locate NetCDF CXX library") 230 | # endif() 231 | 232 | 233 | 234 | # Define the LIBRARIES and INCLUDE_DORS 235 | set(NetCDF_INCLUDE_DIRS ${NetCDF_INCLUDE_DIR}) 236 | set(NetCDF_LIBRARIES ${NetCDF_CXX_LIBRARY} ${NetCDF_C_LIBRARY}) 237 | 238 | # Need to find the NetCDF config script to check for HDF5 239 | if ( NetCDF_DIR OR NetCDF_BIN_DIR ) 240 | find_program(netcdf_config nc-config 241 | HINTS ${NetCDF_DIR} ${NetCDF_BIN_DIR} 242 | PATH_SUFFIXES bin Bin 243 | DOC "NetCDF configuration script") 244 | 245 | if (netcdf_config) 246 | message(STATUS "Found NetCDF configuration script: ${netcdf_config}") 247 | execute_process(COMMAND "${netcdf_config}" "--has-hdf5" 248 | RESULT_VARIABLE _ret_code 249 | OUTPUT_VARIABLE _stdout 250 | ERROR_VARIABLE _stderr 251 | ) 252 | string(REGEX REPLACE "[\n\r ]" "" _hdf5_answer ${_stdout}) 253 | message(STATUS "${netcdf_config} --has-hdf5 returned '${_hdf5_answer}'") 254 | string(COMPARE EQUAL "${_hdf5_answer}" "yes" _has_hdf5) 255 | if (${_has_hdf5} ) 256 | set(NetCDF_NEEDS_HDF5 True) 257 | else() 258 | message(STATUS "NetCDF does not require HDF5") 259 | endif() 260 | 261 | endif() 262 | endif() 263 | 264 | if(NetCDF_NEEDS_HDF5) 265 | message(STATUS "NetCDF requires HDF5") 266 | add_package_dependency(NetCDF DEPENDS_ON HDF5) 267 | endif() 268 | 269 | endif(NetCDF_LIBRARIES AND NetCDF_INCLUDE_DIRS ) 270 | 271 | # Send useful message if everything is found 272 | find_package_handle_standard_args(NetCDF DEFAULT_MSG 273 | NetCDF_LIBRARIES 274 | NetCDF_INCLUDE_DIRS) 275 | 276 | # find_package)handle)standard_args should set NetCDF_FOUND but it does not! 277 | if ( NetCDF_LIBRARIES AND NetCDF_INCLUDE_DIRS) 278 | set(NetCDF_FOUND TRUE) 279 | else() 280 | set(NetCDF_FOUND FALSE) 281 | endif() 282 | 283 | mark_as_advanced( 284 | NetCDF_INCLUDE_DIR 285 | NetCDF_INCLUDE_DIRS 286 | NetCDF_C_LIBRARY 287 | NetCDF_CXX_LIBRARY 288 | NetCDF_LIBRARIES 289 | NetCDF_LIBRARY_DIR 290 | ) 291 | -------------------------------------------------------------------------------- /src/nldiffusion_functions.cpp: -------------------------------------------------------------------------------- 1 | //============================================================================= 2 | // 3 | // nldiffusion_functions.cpp 4 | // Authors: Pablo F. Alcantarilla (1), Jesus Nuevo (2) 5 | // Institutions: Toshiba Research Europe Ltd (1) 6 | // TrueVision Solutions (2) 7 | // Date: 07/10/2014 8 | // Email: pablofdezalc@gmail.com 9 | // 10 | // AKAZE Features Copyright 2014, Pablo F. Alcantarilla, Jesus Nuevo 11 | // All Rights Reserved 12 | // See LICENSE for the license information 13 | //============================================================================= 14 | 15 | /** 16 | * @file nldiffusion_functions.cpp 17 | * @brief Functions for nonlinear diffusion filtering applications 18 | * @date Oct 07, 2014 19 | * @author Pablo F. Alcantarilla, Jesus Nuevo 20 | */ 21 | 22 | #include 23 | #ifdef AKAZE_USE_OPENMP 24 | #include 25 | #endif // AKAZE_USE_OPENMP 26 | #include 27 | 28 | #include "convolution.h" 29 | #include "nldiffusion_functions.h" 30 | 31 | namespace libAKAZE { 32 | 33 | /* ************************************************************************* */ 34 | void gaussian_2D_convolution(const RowMatrixXf& src, RowMatrixXf& dst, 35 | size_t ksize_x, size_t ksize_y, float sigma) { 36 | GaussianBlur(src, sigma, &dst); 37 | } 38 | 39 | /* ************************************************************************* */ 40 | void image_derivatives_scharr(const RowMatrixXf& src, RowMatrixXf& dst, 41 | const size_t xorder, const size_t yorder) { 42 | ScharrDerivative(src, xorder, yorder, 1.0, false, &dst); 43 | } 44 | 45 | /* ************************************************************************* */ 46 | void pm_g1(const RowMatrixXf& Lx, const RowMatrixXf& Ly, RowMatrixXf& dst, 47 | const float k) { 48 | const float inv_k = 1.0 / (k * k); 49 | dst = (-inv_k * (Lx.array().square() + Ly.array().square())).exp(); 50 | } 51 | 52 | /* ************************************************************************* */ 53 | void pm_g2(const RowMatrixXf& Lx, const RowMatrixXf& Ly, RowMatrixXf& dst, 54 | const float k) { 55 | const float inv_k = 1.0 / (k * k); 56 | dst = (1.0 + inv_k * (Lx.array().square() + Ly.array().square())).inverse(); 57 | } 58 | 59 | /* ************************************************************************* */ 60 | void weickert_diffusivity(const RowMatrixXf& Lx, const RowMatrixXf& Ly, 61 | RowMatrixXf& dst, const float k) { 62 | dst.resize(Lx.rows(), Lx.cols()); 63 | const float inv_k = 1.0 / (k * k); 64 | for (int y = 0; y < Lx.rows(); y++) { 65 | for (int x = 0; x < Lx.cols(); x++) { 66 | const float dL = inv_k * (Lx(y, x) * Lx(y, x) + Ly(y, x) * Ly(y, x)); 67 | dst(y, x) = -3.315 / (dL * dL * dL * dL); 68 | } 69 | } 70 | dst = dst.array().exp(); 71 | dst = 1.0 - dst.array(); 72 | } 73 | 74 | /* ************************************************************************* */ 75 | void charbonnier_diffusivity(const RowMatrixXf& Lx, const RowMatrixXf& Ly, 76 | RowMatrixXf& dst, const float k) { 77 | const float inv_k = 1.0 / (k * k); 78 | dst = 1.0 / 79 | ((1.0 + inv_k * (Lx.array().square() + Ly.array().square())).sqrt()); 80 | } 81 | 82 | /* ************************************************************************* */ 83 | float compute_k_percentile(const RowMatrixXf& img, float perc, float gscale, 84 | size_t nbins, size_t ksize_x, size_t ksize_y) { 85 | size_t nbin = 0, nelements = 0, nthreshold = 0, k = 0; 86 | float kperc = 0.0, modg = 0.0, npoints = 0.0, hmax = 0.0; 87 | 88 | // Create the array for the histogram 89 | Eigen::VectorXf hist(nbins); 90 | hist.setZero(); 91 | 92 | // Create the matrices 93 | RowMatrixXf gaussian(img.rows(), img.cols()); 94 | RowMatrixXf Lx(img.rows(), img.cols()); 95 | RowMatrixXf Ly(img.rows(), img.cols()); 96 | 97 | // Perform the Gaussian convolution 98 | gaussian_2D_convolution(img, gaussian, ksize_x, ksize_y, gscale); 99 | 100 | // Compute the Gaussian derivatives Lx and Ly 101 | image_derivatives_scharr(gaussian, Lx, 1, 0); 102 | image_derivatives_scharr(gaussian, Ly, 0, 1); 103 | 104 | // Skip the borders for computing the histogram 105 | for (int y = 1; y < gaussian.rows() - 1; y++) { 106 | for (int x = 1; x < gaussian.cols() - 1; x++) { 107 | modg = Lx(y, x) * Lx(y, x) + Ly(y, x) * Ly(y, x); 108 | // Get the maximum 109 | if (modg > hmax) hmax = modg; 110 | } 111 | } 112 | 113 | hmax = sqrt(hmax); 114 | 115 | // Skip the borders for computing the histogram 116 | for (int y = 1; y < gaussian.rows() - 1; y++) { 117 | for (int x = 1; x < gaussian.cols() - 1; x++) { 118 | modg = sqrt(Lx(y, x) * Lx(y, x) + Ly(y, x) * Ly(y, x)); 119 | 120 | // Find the correspondent bin 121 | if (modg != 0.0) { 122 | nbin = floor(nbins * (modg / hmax)); 123 | 124 | if (nbin == nbins) { 125 | nbin--; 126 | } 127 | 128 | hist[nbin]++; 129 | npoints++; 130 | } 131 | } 132 | } 133 | 134 | // Now find the perc of the histogram percentile 135 | nthreshold = (size_t)(npoints * perc); 136 | 137 | for (k = 0; nelements < nthreshold && k < nbins; k++) 138 | nelements = nelements + hist[k]; 139 | 140 | if (nelements < nthreshold) 141 | kperc = 0.03; 142 | else 143 | kperc = hmax * ((float)(k) / (float) nbins); 144 | 145 | return kperc; 146 | } 147 | 148 | /* ************************************************************************* */ 149 | void compute_scharr_derivatives(const RowMatrixXf& src, 150 | RowMatrixXf& dst, 151 | const size_t xorder, const size_t yorder, 152 | const size_t scale) { 153 | ScharrDerivative(src, xorder, yorder, scale, true, &dst); 154 | } 155 | 156 | /* ************************************************************************* */ 157 | void nld_step_scalar(RowMatrixXf& Ld, const RowMatrixXf& c, RowMatrixXf& Lstep, 158 | const float stepsize) { 159 | Lstep.resize(Ld.rows(), Ld.cols()); 160 | #ifdef AKAZE_USE_OPENMP 161 | #pragma omp parallel for schedule(dynamic) 162 | #endif 163 | for (int y = 1; y < Lstep.rows() - 1; y++) { 164 | for (int x = 1; x < Lstep.cols() - 1; x++) { 165 | const float xpos = (c(y, x) + c(y, x + 1)) * (Ld(y, x + 1) - Ld(y, x)); 166 | const float xneg = (c(y, x - 1) + c(y, x)) * (Ld(y, x) - Ld(y, x - 1)); 167 | const float ypos = (c(y, x) + c(y + 1, x)) * (Ld(y + 1, x) - Ld(y, x)); 168 | const float yneg = (c(y - 1, x) + c(y, x)) * (Ld(y, x) - Ld(y - 1, x)); 169 | Lstep(y, x) = 0.5 * stepsize * (xpos - xneg + ypos - yneg); 170 | } 171 | } 172 | 173 | for (int x = 1; x < Lstep.cols() - 1; x++) { 174 | const float xpos = (c(0, x) + c(0, x + 1)) * (Ld(0, x + 1) - Ld(0, x)); 175 | const float xneg = (c(0, x - 1) + c(0, x)) * (Ld(0, x) - Ld(0, x - 1)); 176 | const float ypos = (c(0, x) + c(1, x)) * (Ld(1, x) - Ld(0, x)); 177 | Lstep(0, x) = 0.5 * stepsize * (xpos - xneg + ypos); 178 | } 179 | 180 | const int end_row = Lstep.rows() - 1; 181 | for (int x = 1; x < Lstep.cols() - 1; x++) { 182 | const float xpos = (c(end_row, x) + c(end_row, x + 1)) * 183 | (Ld(end_row, x + 1) - Ld(end_row, x)); 184 | const float xneg = (c(end_row, x - 1) + c(end_row, x)) * 185 | (Ld(end_row, x) - Ld(end_row, x - 1)); 186 | const float ypos = (c(end_row, x) + c(end_row - 1, x)) * 187 | (Ld(end_row - 1, x) - Ld(end_row, x)); 188 | Lstep(end_row, x) = 0.5 * stepsize * (xpos - xneg + ypos); 189 | } 190 | 191 | const int c_min_1 = Lstep.cols() - 1; 192 | const int c_min_2 = Lstep.cols() - 2; 193 | for (int i = 1; i < Lstep.rows() - 1; i++) { 194 | float xpos = (c(i, 0) + c(i, 1)) * (Ld(i, 1) - Ld(i, 0)); 195 | float ypos = (c(i, 0) + c(i + 1, 0)) * (Ld(i + 1, 0) - Ld(i, 0)); 196 | float yneg = (c(i - 1, 0) + c(i, 0)) * (Ld(i, 0) - Ld(i - 1, 0)); 197 | Lstep(i, 0) = 0.5 * stepsize * (xpos + ypos - yneg); 198 | 199 | const float xneg = 200 | (c(i, c_min_2) + c(i, c_min_1)) * (Ld(i, c_min_1) - Ld(i, c_min_2)); 201 | ypos = (c(i, c_min_1) + c(i + 1, c_min_1)) * 202 | (Ld(i + 1, c_min_1) - Ld(i, c_min_1)); 203 | yneg = (c(i - 1, c_min_1) + c(i, c_min_1)) * 204 | (Ld(i, c_min_1) - Ld(i - 1, c_min_1)); 205 | Lstep(i, c_min_1) = 0.5 * stepsize * (-xneg + ypos - yneg); 206 | } 207 | 208 | // Ld = Ld + Lstep 209 | Ld += Lstep; 210 | } 211 | 212 | /* ************************************************************************* */ 213 | // I think OpenCV's inter area works by setting the size of the interpolation 214 | // kernel to be equal to the scaling factor. 215 | // 216 | // TODO: OpenCV is ~7x faster for this method when dimensions are odd. Maybe the 217 | // difference is only in using OpenMP (I tested it on a Mac). Should try to 218 | // improve the performance here. 219 | void halfsample_image(const RowMatrixXf& src, RowMatrixXf& dst) { 220 | assert(src.rows() / 2 == dst.cols()); 221 | assert(src.cols() / 2 == dst.rows()); 222 | 223 | // Do the whole resampling in one pass by using neighboring values. First, we 224 | // compute the borders. 225 | const double x_kernel_size = static_cast(src.cols()) / dst.cols(); 226 | const double y_kernel_size = static_cast(src.rows()) / dst.rows(); 227 | 228 | // Do simple linear interpolation. 229 | if (x_kernel_size == 2 && y_kernel_size == 2) { 230 | for (int i = 0; i < dst.rows(); i++) { 231 | for (int j = 0; j < dst.cols(); j++) { 232 | dst(i, j) = src(2 * i, 2 * j) + src(2 * i + 1, 2 * j) + 233 | src(2 * i, 2 * j + 1) + src(2 * i + 1, 2 * j + 1); 234 | } 235 | } 236 | dst /= 4.0; 237 | return; 238 | } 239 | 240 | const double x_kernel_clamped_size = static_cast(ceil(x_kernel_size)); 241 | const double y_kernel_clamped_size = static_cast(ceil(y_kernel_size)); 242 | 243 | // Set up precomputed factor matrices. 244 | Eigen::RowVectorXf x_kernel_mul(x_kernel_clamped_size), 245 | y_kernel_mul(y_kernel_clamped_size); 246 | y_kernel_mul.setConstant(1.0); 247 | 248 | Eigen::RowVectorXf temp_row(src.cols()); 249 | #ifdef AKAZE_USE_OPENMP 250 | #pragma omp parallel for firstprivate(temp_row, x_kernel_mul, y_kernel_mul) 251 | #endif 252 | for (int i = 0; i < dst.rows(); i++) { 253 | // Compute the row resize first. 254 | const int y = static_cast(y_kernel_size * i); 255 | y_kernel_mul(0) = 1 - (y_kernel_size * i - y); 256 | y_kernel_mul(y_kernel_clamped_size - 1) -= 257 | y_kernel_mul.sum() - y_kernel_size; 258 | 259 | temp_row = 260 | y_kernel_mul * src.block(y, 0, y_kernel_clamped_size, src.cols()); 261 | 262 | // For this row, compute the column-wise resize. 263 | x_kernel_mul.setConstant(1.0); 264 | for (int j = 0; j < dst.cols(); j++) { 265 | const int x = static_cast(x_kernel_size * j); 266 | x_kernel_mul(0) = 1 - (x_kernel_size * j - x); 267 | x_kernel_mul(x_kernel_clamped_size - 1) -= 268 | x_kernel_mul.sum() - x_kernel_size; 269 | dst(i, j) = 270 | x_kernel_mul.dot(temp_row.segment(x, x_kernel_clamped_size)); 271 | } 272 | } 273 | 274 | dst /= x_kernel_size * y_kernel_size; 275 | } 276 | 277 | /* ************************************************************************* */ 278 | bool check_maximum_neighbourhood(const RowMatrixXf& img, int dsize, float value, 279 | int row, int col, bool same_img) { 280 | bool response = true; 281 | 282 | for (int i = row - dsize; i <= row + dsize; i++) { 283 | for (int j = col - dsize; j <= col + dsize; j++) { 284 | if (i >= 0 && i < img.rows() && j >= 0 && j < img.cols()) { 285 | if (same_img == true) { 286 | if (i != row || j != col) { 287 | if (img(i, j) > value) { 288 | response = false; 289 | return response; 290 | } 291 | } 292 | } else { 293 | if (img(i, j) > value) { 294 | response = false; 295 | return response; 296 | } 297 | } 298 | } 299 | } 300 | } 301 | 302 | return response; 303 | } 304 | 305 | } // namespace libAKAZE 306 | -------------------------------------------------------------------------------- /cimg/cmake-modules/FindLAPACK.cmake: -------------------------------------------------------------------------------- 1 | # - Find LAPACK library 2 | # This module finds an installed fortran library that implements the LAPACK 3 | # linear-algebra interface (see http://www.netlib.org/lapack/). 4 | # 5 | # The approach follows that taken for the autoconf macro file, acx_lapack.m4 6 | # (distributed at http://ac-archive.sourceforge.net/ac-archive/acx_lapack.html). 7 | # 8 | # This module sets the following variables: 9 | # LAPACK_FOUND - set to true if a library implementing the LAPACK interface 10 | # is found 11 | # LAPACK_LINKER_FLAGS - uncached list of required linker flags (excluding -l 12 | # and -L). 13 | # LAPACK_LIBRARIES - uncached list of libraries (using full path name) to 14 | # link against to use LAPACK 15 | # LAPACK95_LIBRARIES - uncached list of libraries (using full path name) to 16 | # link against to use LAPACK95 17 | # LAPACK95_FOUND - set to true if a library implementing the LAPACK f95 18 | # interface is found 19 | # BLA_STATIC if set on this determines what kind of linkage we do (static) 20 | # BLA_VENDOR if set checks only the specified vendor, if not set checks 21 | # all the possibilities 22 | # BLA_F95 if set on tries to find the f95 interfaces for BLAS/LAPACK 23 | ### List of vendors (BLA_VENDOR) valid in this module 24 | ## Intel(mkl), ACML,Apple, NAS, Generic 25 | 26 | #============================================================================= 27 | # Copyright 2007-2009 Kitware, Inc. 28 | # 29 | # Distributed under the OSI-approved BSD License (the "License"); 30 | # see accompanying file Copyright.txt for details. 31 | # 32 | # This software is distributed WITHOUT ANY WARRANTY; without even the 33 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 34 | # See the License for more information. 35 | #============================================================================= 36 | # (To distribute this file outside of CMake, substitute the full 37 | # License text for the above reference.) 38 | 39 | set(_lapack_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) 40 | 41 | get_property(_LANGUAGES_ GLOBAL PROPERTY ENABLED_LANGUAGES) 42 | if (NOT _LANGUAGES_ MATCHES Fortran) 43 | include(CheckFunctionExists) 44 | else (NOT _LANGUAGES_ MATCHES Fortran) 45 | include(CheckFortranFunctionExists) 46 | endif (NOT _LANGUAGES_ MATCHES Fortran) 47 | 48 | set(LAPACK_FOUND FALSE) 49 | set(LAPACK95_FOUND FALSE) 50 | 51 | # TODO: move this stuff to separate module 52 | 53 | macro(Check_Lapack_Libraries LIBRARIES _prefix _name _flags _list _blas _threads) 54 | # This macro checks for the existence of the combination of fortran libraries 55 | # given by _list. If the combination is found, this macro checks (using the 56 | # Check_Fortran_Function_Exists macro) whether can link against that library 57 | # combination using the name of a routine given by _name using the linker 58 | # flags given by _flags. If the combination of libraries is found and passes 59 | # the link test, LIBRARIES is set to the list of complete library paths that 60 | # have been found. Otherwise, LIBRARIES is set to FALSE. 61 | 62 | # N.B. _prefix is the prefix applied to the names of all cached variables that 63 | # are generated internally and marked advanced by this macro. 64 | 65 | set(_libraries_work TRUE) 66 | set(${LIBRARIES}) 67 | set(_combined_name) 68 | if (NOT _libdir) 69 | if (WIN32) 70 | set(_libdir ENV LIB) 71 | elseif (APPLE) 72 | set(_libdir /usr/local/lib /usr/lib /usr/local/lib64 /usr/lib64 ENV DYLD_LIBRARY_PATH) 73 | else () 74 | set(_libdir /usr/local/lib /usr/lib /usr/local/lib64 /usr/lib64 ENV LD_LIBRARY_PATH) 75 | endif () 76 | endif () 77 | foreach(_library ${_list}) 78 | set(_combined_name ${_combined_name}_${_library}) 79 | 80 | if(_libraries_work) 81 | if (BLA_STATIC) 82 | if (WIN32) 83 | set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES}) 84 | endif ( WIN32 ) 85 | if (APPLE) 86 | set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES}) 87 | else (APPLE) 88 | set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) 89 | endif (APPLE) 90 | else (BLA_STATIC) 91 | if (CMAKE_SYSTEM_NAME STREQUAL "Linux") 92 | # for ubuntu's libblas3gf and liblapack3gf packages 93 | set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES} .so.3gf) 94 | endif () 95 | endif (BLA_STATIC) 96 | find_library(${_prefix}_${_library}_LIBRARY 97 | NAMES ${_library} 98 | PATHS ${_libdir} 99 | ) 100 | mark_as_advanced(${_prefix}_${_library}_LIBRARY) 101 | set(${LIBRARIES} ${${LIBRARIES}} ${${_prefix}_${_library}_LIBRARY}) 102 | set(_libraries_work ${${_prefix}_${_library}_LIBRARY}) 103 | endif(_libraries_work) 104 | endforeach(_library ${_list}) 105 | 106 | if(_libraries_work) 107 | # Test this combination of libraries. 108 | if(UNIX AND BLA_STATIC) 109 | set(CMAKE_REQUIRED_LIBRARIES ${_flags} "-Wl,--start-group" ${${LIBRARIES}} ${_blas} "-Wl,--end-group" ${_threads}) 110 | else(UNIX AND BLA_STATIC) 111 | set(CMAKE_REQUIRED_LIBRARIES ${_flags} ${${LIBRARIES}} ${_blas} ${_threads}) 112 | endif(UNIX AND BLA_STATIC) 113 | # message("DEBUG: CMAKE_REQUIRED_LIBRARIES = ${CMAKE_REQUIRED_LIBRARIES}") 114 | if (NOT _LANGUAGES_ MATCHES Fortran) 115 | check_function_exists("${_name}_" ${_prefix}${_combined_name}_WORKS) 116 | else (NOT _LANGUAGES_ MATCHES Fortran) 117 | check_fortran_function_exists(${_name} ${_prefix}${_combined_name}_WORKS) 118 | endif (NOT _LANGUAGES_ MATCHES Fortran) 119 | set(CMAKE_REQUIRED_LIBRARIES) 120 | mark_as_advanced(${_prefix}${_combined_name}_WORKS) 121 | set(_libraries_work ${${_prefix}${_combined_name}_WORKS}) 122 | #message("DEBUG: ${LIBRARIES} = ${${LIBRARIES}}") 123 | endif(_libraries_work) 124 | 125 | if(_libraries_work) 126 | set(${LIBRARIES} ${${LIBRARIES}} ${_blas} ${_threads}) 127 | else(_libraries_work) 128 | set(${LIBRARIES} FALSE) 129 | endif(_libraries_work) 130 | 131 | endmacro(Check_Lapack_Libraries) 132 | 133 | 134 | set(LAPACK_LINKER_FLAGS) 135 | set(LAPACK_LIBRARIES) 136 | set(LAPACK95_LIBRARIES) 137 | 138 | 139 | if(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED) 140 | find_package(BLAS) 141 | else(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED) 142 | find_package(BLAS REQUIRED) 143 | endif(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED) 144 | 145 | 146 | if(BLAS_FOUND) 147 | set(LAPACK_LINKER_FLAGS ${BLAS_LINKER_FLAGS}) 148 | if ($ENV{BLA_VENDOR} MATCHES ".+") 149 | set(BLA_VENDOR $ENV{BLA_VENDOR}) 150 | else ($ENV{BLA_VENDOR} MATCHES ".+") 151 | if(NOT BLA_VENDOR) 152 | set(BLA_VENDOR "All") 153 | endif(NOT BLA_VENDOR) 154 | endif ($ENV{BLA_VENDOR} MATCHES ".+") 155 | 156 | if (BLA_VENDOR STREQUAL "Goto" OR BLA_VENDOR STREQUAL "All") 157 | if(NOT LAPACK_LIBRARIES) 158 | check_lapack_libraries( 159 | LAPACK_LIBRARIES 160 | LAPACK 161 | cheev 162 | "" 163 | "goto2" 164 | "${BLAS_LIBRARIES}" 165 | "" 166 | ) 167 | endif(NOT LAPACK_LIBRARIES) 168 | endif (BLA_VENDOR STREQUAL "Goto" OR BLA_VENDOR STREQUAL "All") 169 | 170 | 171 | #acml lapack 172 | if (BLA_VENDOR MATCHES "ACML.*" OR BLA_VENDOR STREQUAL "All") 173 | if (BLAS_LIBRARIES MATCHES ".+acml.+") 174 | set (LAPACK_LIBRARIES ${BLAS_LIBRARIES}) 175 | endif () 176 | endif () 177 | 178 | # Apple LAPACK library? 179 | if (BLA_VENDOR STREQUAL "Apple" OR BLA_VENDOR STREQUAL "All") 180 | if(NOT LAPACK_LIBRARIES) 181 | check_lapack_libraries( 182 | LAPACK_LIBRARIES 183 | LAPACK 184 | cheev 185 | "" 186 | "Accelerate" 187 | "${BLAS_LIBRARIES}" 188 | "" 189 | ) 190 | endif(NOT LAPACK_LIBRARIES) 191 | endif (BLA_VENDOR STREQUAL "Apple" OR BLA_VENDOR STREQUAL "All") 192 | if (BLA_VENDOR STREQUAL "NAS" OR BLA_VENDOR STREQUAL "All") 193 | if ( NOT LAPACK_LIBRARIES ) 194 | check_lapack_libraries( 195 | LAPACK_LIBRARIES 196 | LAPACK 197 | cheev 198 | "" 199 | "vecLib" 200 | "${BLAS_LIBRARIES}" 201 | "" 202 | ) 203 | endif ( NOT LAPACK_LIBRARIES ) 204 | endif (BLA_VENDOR STREQUAL "NAS" OR BLA_VENDOR STREQUAL "All") 205 | # Generic LAPACK library? 206 | if (BLA_VENDOR STREQUAL "Generic" OR 207 | BLA_VENDOR STREQUAL "ATLAS" OR 208 | BLA_VENDOR STREQUAL "All") 209 | if ( NOT LAPACK_LIBRARIES ) 210 | check_lapack_libraries( 211 | LAPACK_LIBRARIES 212 | LAPACK 213 | cheev 214 | "" 215 | "lapack" 216 | "${BLAS_LIBRARIES}" 217 | "" 218 | ) 219 | endif ( NOT LAPACK_LIBRARIES ) 220 | endif () 221 | #intel lapack 222 | if (BLA_VENDOR MATCHES "Intel*" OR BLA_VENDOR STREQUAL "All") 223 | if (NOT WIN32) 224 | set(LM "-lm") 225 | endif () 226 | if (_LANGUAGES_ MATCHES C OR _LANGUAGES_ MATCHES CXX) 227 | if(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED) 228 | find_PACKAGE(Threads) 229 | else(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED) 230 | find_package(Threads REQUIRED) 231 | endif(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED) 232 | if (BLA_F95) 233 | if(NOT LAPACK95_LIBRARIES) 234 | # old 235 | check_lapack_libraries( 236 | LAPACK95_LIBRARIES 237 | LAPACK 238 | cheev 239 | "" 240 | "mkl_lapack95" 241 | "${BLAS95_LIBRARIES}" 242 | "${CMAKE_THREAD_LIBS_INIT};${LM}" 243 | ) 244 | endif(NOT LAPACK95_LIBRARIES) 245 | if(NOT LAPACK95_LIBRARIES) 246 | # new >= 10.3 247 | check_lapack_libraries( 248 | LAPACK95_LIBRARIES 249 | LAPACK 250 | CHEEV 251 | "" 252 | "mkl_intel_lp64" 253 | "${BLAS95_LIBRARIES}" 254 | "${CMAKE_THREAD_LIBS_INIT};${LM}" 255 | ) 256 | endif(NOT LAPACK95_LIBRARIES) 257 | else(BLA_F95) 258 | if(NOT LAPACK_LIBRARIES) 259 | # old 260 | check_lapack_libraries( 261 | LAPACK_LIBRARIES 262 | LAPACK 263 | cheev 264 | "" 265 | "mkl_lapack" 266 | "${BLAS_LIBRARIES}" 267 | "${CMAKE_THREAD_LIBS_INIT};${LM}" 268 | ) 269 | endif(NOT LAPACK_LIBRARIES) 270 | if(NOT LAPACK_LIBRARIES) 271 | # new >= 10.3 272 | check_lapack_libraries( 273 | LAPACK_LIBRARIES 274 | LAPACK 275 | cheev 276 | "" 277 | "mkl_gf_lp64" 278 | "${BLAS_LIBRARIES}" 279 | "${CMAKE_THREAD_LIBS_INIT};${LM}" 280 | ) 281 | endif(NOT LAPACK_LIBRARIES) 282 | endif(BLA_F95) 283 | endif (_LANGUAGES_ MATCHES C OR _LANGUAGES_ MATCHES CXX) 284 | endif(BLA_VENDOR MATCHES "Intel*" OR BLA_VENDOR STREQUAL "All") 285 | else(BLAS_FOUND) 286 | message(STATUS "LAPACK requires BLAS") 287 | endif(BLAS_FOUND) 288 | 289 | if(BLA_F95) 290 | if(LAPACK95_LIBRARIES) 291 | set(LAPACK95_FOUND TRUE) 292 | else(LAPACK95_LIBRARIES) 293 | set(LAPACK95_FOUND FALSE) 294 | endif(LAPACK95_LIBRARIES) 295 | if(NOT LAPACK_FIND_QUIETLY) 296 | if(LAPACK95_FOUND) 297 | message(STATUS "A library with LAPACK95 API found.") 298 | else(LAPACK95_FOUND) 299 | if(LAPACK_FIND_REQUIRED) 300 | message(FATAL_ERROR 301 | "A required library with LAPACK95 API not found. Please specify library location." 302 | ) 303 | else(LAPACK_FIND_REQUIRED) 304 | message(STATUS 305 | "A library with LAPACK95 API not found. Please specify library location." 306 | ) 307 | endif(LAPACK_FIND_REQUIRED) 308 | endif(LAPACK95_FOUND) 309 | endif(NOT LAPACK_FIND_QUIETLY) 310 | set(LAPACK_FOUND "${LAPACK95_FOUND}") 311 | set(LAPACK_LIBRARIES "${LAPACK95_LIBRARIES}") 312 | else(BLA_F95) 313 | if(LAPACK_LIBRARIES) 314 | set(LAPACK_FOUND TRUE) 315 | else(LAPACK_LIBRARIES) 316 | set(LAPACK_FOUND FALSE) 317 | endif(LAPACK_LIBRARIES) 318 | 319 | if(NOT LAPACK_FIND_QUIETLY) 320 | if(LAPACK_FOUND) 321 | message(STATUS "A library with LAPACK API found.") 322 | else(LAPACK_FOUND) 323 | if(LAPACK_FIND_REQUIRED) 324 | message(FATAL_ERROR 325 | "A required library with LAPACK API not found. Please specify library location." 326 | ) 327 | else(LAPACK_FIND_REQUIRED) 328 | message(STATUS 329 | "A library with LAPACK API not found. Please specify library location." 330 | ) 331 | endif(LAPACK_FIND_REQUIRED) 332 | endif(LAPACK_FOUND) 333 | endif(NOT LAPACK_FIND_QUIETLY) 334 | endif(BLA_F95) 335 | 336 | set(CMAKE_FIND_LIBRARY_SUFFIXES ${_lapack_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES}) 337 | --------------------------------------------------------------------------------