diff --git a/.readthedocs.yml b/.readthedocs.yml
new file mode 100644
index 00000000..79484e63
--- /dev/null
+++ b/.readthedocs.yml
@@ -0,0 +1,19 @@
+# .readthedocs.yml
+# Read the Docs configuration file
+# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
+
+# Required
+version: 2
+
+# Build documentation in the docs/ directory with Sphinx
+sphinx:
+ configuration: doc/sphinx/source/conf.py
+
+# Optionally build your docs in additional formats such as PDF and ePub
+formats: all
+
+# Optionally set the version of Python and requirements required to build your docs
+python:
+ version: 3.7
+ install:
+ - requirements: doc/sphinx/requirements.txt
diff --git a/.travis.yml b/.travis.yml
index 4e71f353..dd24a21b 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -92,14 +92,14 @@ before_script:
- mkdir -p ${POPSIFT_BUILD_RELEASE}
- cd ${POPSIFT_BUILD_RELEASE}
- >
- cmake . ${POPSIFT_SOURCE} -DCMAKE_INSTALL_PREFIX=${POPSIFT_INSTALL_RELEASE} -DCMAKE_BUILD_TYPE=Release
+ cmake . ${POPSIFT_SOURCE} -DCMAKE_INSTALL_PREFIX=${POPSIFT_INSTALL_RELEASE} -DCMAKE_BUILD_TYPE=Release -DPopSift_BUILD_DOCS:BOOL=OFF
# Classic debug build
# Create build folder
- mkdir -p ${POPSIFT_BUILD_DEBUG}
- cd ${POPSIFT_BUILD_DEBUG}
- >
- cmake . ${POPSIFT_SOURCE} -DCMAKE_INSTALL_PREFIX=${POPSIFT_INSTALL_DEBUG} -DCMAKE_BUILD_TYPE=Debug
+ cmake . ${POPSIFT_SOURCE} -DCMAKE_INSTALL_PREFIX=${POPSIFT_INSTALL_DEBUG} -DCMAKE_BUILD_TYPE=Debug -DPopSift_BUILD_DOCS:BOOL=OFF
script:
- cd ${POPSIFT_BUILD_RELEASE}
@@ -111,7 +111,7 @@ script:
- cd ${POPSIFT_APP_SRC}
- mkdir -p ${POPSIFT_APP_BUILD_RELEASE}
- cd ${POPSIFT_APP_BUILD_RELEASE}
- - cmake .. -DPopSift_DIR=${POPSIFT_INSTALL_RELEASE}/lib/cmake/PopSift/ -DCMAKE_INSTALL_PREFIX=${POPSIFT_APP_INSTALL_RELEASE} -DCMAKE_BUILD_TYPE=Release
+ - cmake .. -DPopSift_DIR=${POPSIFT_INSTALL_RELEASE}/lib/cmake/PopSift/ -DCMAKE_INSTALL_PREFIX=${POPSIFT_APP_INSTALL_RELEASE} -DCMAKE_BUILD_TYPE=Release -DPopSift_BUILD_DOCS:BOOL=OFF
- make install -j 2 VERBOSE=1
# same for debug
@@ -124,7 +124,7 @@ script:
- cd ${POPSIFT_APP_SRC}
- mkdir -p ${POPSIFT_APP_BUILD_DEBUG}
- cd ${POPSIFT_APP_BUILD_DEBUG}
- - cmake .. -DPopSift_DIR=${POPSIFT_INSTALL_DEBUG}/lib/cmake/PopSift/ -DCMAKE_INSTALL_PREFIX=${POPSIFT_APP_INSTALL_DEBUG} -DCMAKE_BUILD_TYPE=Debug
+ - cmake .. -DPopSift_DIR=${POPSIFT_INSTALL_DEBUG}/lib/cmake/PopSift/ -DCMAKE_INSTALL_PREFIX=${POPSIFT_APP_INSTALL_DEBUG} -DCMAKE_BUILD_TYPE=Debug -DPopSift_BUILD_DOCS:BOOL=OFF
- make install -j 2 VERBOSE=1
cache:
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 13d49614..9735bc2d 100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -8,6 +8,7 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/${CMAKE_SYSTEM_NAME}-$
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR}")
option(PopSift_BUILD_EXAMPLES "Build PopSift applications." ON)
+option(PopSift_BUILD_DOCS "Build PopSift documentation." OFF)
option(PopSift_USE_NVTX_PROFILING "Use CUDA NVTX for profiling." OFF)
option(PopSift_ERRCHK_AFTER_KERNEL "Synchronize and check CUDA error after every kernel." OFF)
option(PopSift_USE_POSITION_INDEPENDENT_CODE "Generate position independent code." ON)
@@ -200,6 +201,10 @@ endif()
add_subdirectory(src)
+if(PopSift_BUILD_DOCS)
+ add_subdirectory(doc)
+endif()
+
set(PopSift_TESTFILE_PATH "popsift-samples/datasets/sample/big_set/" CACHE STRING "Base directory where your test files are stored")
if(PopSift_USE_TEST_CMD)
if(NOT IS_ABSOLUTE("${PopSift_TESTFILE_PATH}"))
@@ -229,6 +234,7 @@ message(STATUS "PopSift version: " ${PROJECT_VERSION})
message(STATUS "Build type: " ${CMAKE_BUILD_TYPE})
message(STATUS "Build Shared libs: " ${BUILD_SHARED_LIBS})
message(STATUS "Build examples: " ${PopSift_BUILD_EXAMPLES})
+message(STATUS "Build documentation: " ${PopSift_BUILD_DOCS})
message(STATUS "Generate position independent code: " ${CMAKE_POSITION_INDEPENDENT_CODE})
message(STATUS "Use CUDA NVTX for profiling: " ${PopSift_USE_NVTX_PROFILING})
message(STATUS "Synchronize and check CUDA error after every kernel: " ${PopSift_ERRCHK_AFTER_KERNEL})
diff --git a/appveyor.yml b/appveyor.yml
index 3cdf7298..dc822f2b 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -26,7 +26,7 @@ install:
before_build:
- md build
- cd build
- - cmake -G "Visual Studio 14 2015" -A x64 -T v140,host=x64 -DBUILD_SHARED_LIBS=%DBUILD_SHARED_LIBS% -DPopSift_USE_POSITION_INDEPENDENT_CODE:BOOL=%DBUILD_SHARED_LIBS% -DPopSift_BUILD_EXAMPLES:BOOL=ON -DCMAKE_BUILD_TYPE=%configuration% -DCMAKE_TOOLCHAIN_FILE=c:/tools/vcpkg/scripts/buildsystems/vcpkg.cmake ..
+ - cmake -G "Visual Studio 14 2015" -A x64 -T v140,host=x64 -DBUILD_SHARED_LIBS=%DBUILD_SHARED_LIBS% -DPopSift_BUILD_DOCS:BOOL=OFF -DPopSift_USE_POSITION_INDEPENDENT_CODE:BOOL=%DBUILD_SHARED_LIBS% -DPopSift_BUILD_EXAMPLES:BOOL=ON -DCMAKE_BUILD_TYPE=%configuration% -DCMAKE_TOOLCHAIN_FILE=c:/tools/vcpkg/scripts/buildsystems/vcpkg.cmake ..
- ls -l
build:
diff --git a/cmake/FindSphinx.cmake b/cmake/FindSphinx.cmake
new file mode 100644
index 00000000..9b9d2b9e
--- /dev/null
+++ b/cmake/FindSphinx.cmake
@@ -0,0 +1,12 @@
+#Look for an executable called sphinx-build
+find_program(SPHINX_EXECUTABLE
+ NAMES sphinx-build
+ HINTS ${SPHINX_ROOT}
+ DOC "Path to sphinx-build executable")
+
+include(FindPackageHandleStandardArgs)
+
+#Handle standard arguments to find_package like REQUIRED and QUIET
+find_package_handle_standard_args(Sphinx
+ "Failed to find sphinx-build executable"
+ SPHINX_EXECUTABLE)
\ No newline at end of file
diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt
new file mode 100644
index 00000000..5468184f
--- /dev/null
+++ b/doc/CMakeLists.txt
@@ -0,0 +1,39 @@
+find_package(Doxygen REQUIRED)
+
+file(GLOB_RECURSE ALL_PUBLIC_HEADERS ${PROJECT_SOURCE_DIR}/src/popsift/*.h*)
+set(CCTAG_OTHER_DOC_SOURCES ${PROJECT_SOURCE_DIR}/README.md ${PROJECT_SOURCE_DIR}/INSTALL.md)
+set(DOXYGEN_USE_MDFILE_AS_MAINPAGE ${PROJECT_SOURCE_DIR}/README.md)
+set(DOXYGEN_PROJECT_BRIEF "A faithful implementation of the SIFT algorithm in CUDA.")
+set(DOXYGEN_GENERATE_XML YES)
+set(DOXYGEN_GENERATE_TREEVIEW YES)
+set(DOXYGEN_GENERATE_DEPRECATEDLIST YES)
+set(DOXYGEN_SORT_BRIEF_DOCS YES)
+set(DOXYGEN_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doxygen)
+set(DOXYGEN_INDEX_FILE ${DOXYGEN_OUTPUT_DIRECTORY}/xml/index.xml)
+
+doxygen_add_docs(doxygen
+ ${ALL_PUBLIC_HEADERS} ${CCTAG_OTHER_DOC_SOURCES}
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ COMMENT "Generate the doc")
+
+
+
+find_package(Sphinx REQUIRED)
+
+set(SPHINX_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/sphinx/source)
+set(SPHINX_BUILD ${CMAKE_CURRENT_BINARY_DIR}/sphinx)
+
+add_custom_target(sphinx ALL
+ COMMAND
+ ${SPHINX_EXECUTABLE} -b html
+ # Tell Breathe where to find the Doxygen output
+ -Dbreathe_projects.PopSift=${DOXYGEN_OUTPUT_DIRECTORY}/xml
+ ${SPHINX_SOURCE} ${SPHINX_BUILD}
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ DEPENDS
+ doxygen
+ # Other docs files you want to track should go here (or in some variable)
+ ${CMAKE_CURRENT_SOURCE_DIR}/sphinx/source/index.rst
+ ${DOXYGEN_INDEX_FILE}
+ # MAIN_DEPENDENCY ${SPHINX_SOURCE}/conf.py
+ COMMENT "Generating documentation with Sphinx")
\ No newline at end of file
diff --git a/doc/sphinx/Makefile b/doc/sphinx/Makefile
new file mode 100644
index 00000000..d0c3cbf1
--- /dev/null
+++ b/doc/sphinx/Makefile
@@ -0,0 +1,20 @@
+# Minimal makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line, and also
+# from the environment for the first two.
+SPHINXOPTS ?=
+SPHINXBUILD ?= sphinx-build
+SOURCEDIR = source
+BUILDDIR = build
+
+# Put it first so that "make" without argument is like "make help".
+help:
+ @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+
+.PHONY: help Makefile
+
+# Catch-all target: route all unknown targets to Sphinx using the new
+# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
+%: Makefile
+ @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
diff --git a/doc/sphinx/make.bat b/doc/sphinx/make.bat
new file mode 100644
index 00000000..6247f7e2
--- /dev/null
+++ b/doc/sphinx/make.bat
@@ -0,0 +1,35 @@
+@ECHO OFF
+
+pushd %~dp0
+
+REM Command file for Sphinx documentation
+
+if "%SPHINXBUILD%" == "" (
+ set SPHINXBUILD=sphinx-build
+)
+set SOURCEDIR=source
+set BUILDDIR=build
+
+if "%1" == "" goto help
+
+%SPHINXBUILD% >NUL 2>NUL
+if errorlevel 9009 (
+ echo.
+ echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
+ echo.installed, then set the SPHINXBUILD environment variable to point
+ echo.to the full path of the 'sphinx-build' executable. Alternatively you
+ echo.may add the Sphinx directory to PATH.
+ echo.
+ echo.If you don't have Sphinx installed, grab it from
+ echo.http://sphinx-doc.org/
+ exit /b 1
+)
+
+%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
+goto end
+
+:help
+%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
+
+:end
+popd
diff --git a/doc/sphinx/requirements.txt b/doc/sphinx/requirements.txt
new file mode 100644
index 00000000..45a2e179
--- /dev/null
+++ b/doc/sphinx/requirements.txt
@@ -0,0 +1,4 @@
+sphinx>=1.9.0
+sphinx_rtd_theme
+sphinxcontrib-bibtex
+breathe
diff --git a/doc/sphinx/source/Doxyfile b/doc/sphinx/source/Doxyfile
new file mode 100644
index 00000000..3a42393f
--- /dev/null
+++ b/doc/sphinx/source/Doxyfile
@@ -0,0 +1,267 @@
+DOXYFILE_ENCODING = UTF-8
+PROJECT_NAME = PopSift
+PROJECT_NUMBER = 1.0.0
+PROJECT_BRIEF = "A faithful implementation of the SIFT algorithm in CUDA."
+PROJECT_LOGO =
+OUTPUT_DIRECTORY = ../build
+CREATE_SUBDIRS = NO
+ALLOW_UNICODE_NAMES = NO
+OUTPUT_LANGUAGE = English
+BRIEF_MEMBER_DESC = YES
+REPEAT_BRIEF = YES
+ABBREVIATE_BRIEF = "The $name class" "The $name widget" "The $name file" is provides specifies contains represents a an the
+ALWAYS_DETAILED_SEC = NO
+INLINE_INHERITED_MEMB = NO
+FULL_PATH_NAMES = YES
+STRIP_FROM_PATH =
+STRIP_FROM_INC_PATH =
+SHORT_NAMES = NO
+JAVADOC_AUTOBRIEF = NO
+QT_AUTOBRIEF = NO
+MULTILINE_CPP_IS_BRIEF = NO
+INHERIT_DOCS = YES
+SEPARATE_MEMBER_PAGES = NO
+TAB_SIZE = 4
+ALIASES =
+TCL_SUBST =
+OPTIMIZE_OUTPUT_FOR_C = NO
+OPTIMIZE_OUTPUT_JAVA = NO
+OPTIMIZE_FOR_FORTRAN = NO
+OPTIMIZE_OUTPUT_VHDL = NO
+EXTENSION_MAPPING =
+MARKDOWN_SUPPORT = YES
+TOC_INCLUDE_HEADINGS = 0
+AUTOLINK_SUPPORT = YES
+BUILTIN_STL_SUPPORT = NO
+CPP_CLI_SUPPORT = NO
+SIP_SUPPORT = NO
+IDL_PROPERTY_SUPPORT = YES
+DISTRIBUTE_GROUP_DOC = NO
+GROUP_NESTED_COMPOUNDS = NO
+SUBGROUPING = YES
+INLINE_GROUPED_CLASSES = NO
+INLINE_SIMPLE_STRUCTS = NO
+TYPEDEF_HIDES_STRUCT = NO
+LOOKUP_CACHE_SIZE = 0
+EXTRACT_ALL = NO
+EXTRACT_PRIVATE = NO
+EXTRACT_PACKAGE = NO
+EXTRACT_STATIC = NO
+EXTRACT_LOCAL_CLASSES = YES
+EXTRACT_LOCAL_METHODS = NO
+EXTRACT_ANON_NSPACES = NO
+HIDE_UNDOC_MEMBERS = NO
+HIDE_UNDOC_CLASSES = NO
+HIDE_FRIEND_COMPOUNDS = NO
+HIDE_IN_BODY_DOCS = NO
+INTERNAL_DOCS = NO
+CASE_SENSE_NAMES = YES
+HIDE_SCOPE_NAMES = NO
+HIDE_COMPOUND_REFERENCE= NO
+SHOW_INCLUDE_FILES = YES
+SHOW_GROUPED_MEMB_INC = NO
+FORCE_LOCAL_INCLUDES = NO
+INLINE_INFO = YES
+SORT_MEMBER_DOCS = YES
+SORT_BRIEF_DOCS = NO
+SORT_MEMBERS_CTORS_1ST = NO
+SORT_GROUP_NAMES = NO
+SORT_BY_SCOPE_NAME = NO
+STRICT_PROTO_MATCHING = NO
+GENERATE_TODOLIST = YES
+GENERATE_TESTLIST = YES
+GENERATE_BUGLIST = YES
+GENERATE_DEPRECATEDLIST= YES
+ENABLED_SECTIONS =
+MAX_INITIALIZER_LINES = 30
+SHOW_USED_FILES = YES
+SHOW_FILES = YES
+SHOW_NAMESPACES = YES
+FILE_VERSION_FILTER =
+LAYOUT_FILE =
+CITE_BIB_FILES =
+QUIET = NO
+WARNINGS = YES
+WARN_IF_UNDOCUMENTED = YES
+WARN_IF_DOC_ERROR = YES
+WARN_NO_PARAMDOC = NO
+WARN_AS_ERROR = NO
+WARN_FORMAT = "$file:$line: $text"
+WARN_LOGFILE =
+INPUT = ../../../src
+INPUT_ENCODING = UTF-8
+FILE_PATTERNS = *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.idl *.ddl *.odl *.h *.hh *.hxx *.hpp *.h++ *.cs *.d *.php *.php4 *.php5 *.phtml *.inc *.m *.markdown *.md *.mm *.dox *.py *.pyw *.f90 *.f95 *.f03 *.f08 *.f *.for *.tcl *.vhd *.vhdl *.ucf *.qsf
+RECURSIVE = YES
+EXCLUDE =
+EXCLUDE_SYMLINKS = NO
+EXCLUDE_PATTERNS = */.git/* */.svn/* */.hg/* */CMakeFiles/* */_CPack_Packages/* DartConfiguration.tcl CMakeLists.txt CMakeCache.txt
+EXCLUDE_SYMBOLS =
+EXAMPLE_PATH =
+EXAMPLE_PATTERNS = *
+EXAMPLE_RECURSIVE = NO
+IMAGE_PATH =
+INPUT_FILTER =
+FILTER_PATTERNS =
+FILTER_SOURCE_FILES = NO
+FILTER_SOURCE_PATTERNS =
+SOURCE_BROWSER = NO
+INLINE_SOURCES = NO
+STRIP_CODE_COMMENTS = YES
+REFERENCED_BY_RELATION = NO
+REFERENCES_RELATION = NO
+REFERENCES_LINK_SOURCE = YES
+SOURCE_TOOLTIPS = YES
+USE_HTAGS = NO
+VERBATIM_HEADERS = YES
+CLANG_ASSISTED_PARSING = NO
+CLANG_OPTIONS =
+ALPHABETICAL_INDEX = YES
+COLS_IN_ALPHA_INDEX = 5
+IGNORE_PREFIX =
+GENERATE_HTML = NO
+HTML_OUTPUT = html
+HTML_FILE_EXTENSION = .html
+HTML_HEADER =
+HTML_FOOTER =
+HTML_STYLESHEET =
+HTML_EXTRA_STYLESHEET =
+HTML_EXTRA_FILES =
+HTML_COLORSTYLE_HUE = 220
+HTML_COLORSTYLE_SAT = 100
+HTML_COLORSTYLE_GAMMA = 80
+HTML_TIMESTAMP = NO
+HTML_DYNAMIC_SECTIONS = NO
+HTML_INDEX_NUM_ENTRIES = 100
+GENERATE_DOCSET = NO
+DOCSET_FEEDNAME = "Doxygen generated docs"
+DOCSET_BUNDLE_ID = org.doxygen.Project
+DOCSET_PUBLISHER_ID = org.doxygen.Publisher
+DOCSET_PUBLISHER_NAME = Publisher
+GENERATE_HTMLHELP = NO
+CHM_FILE =
+HHC_LOCATION =
+GENERATE_CHI = NO
+CHM_INDEX_ENCODING =
+BINARY_TOC = NO
+TOC_EXPAND = NO
+GENERATE_QHP = NO
+QCH_FILE =
+QHP_NAMESPACE = org.doxygen.Project
+QHP_VIRTUAL_FOLDER = doc
+QHP_CUST_FILTER_NAME =
+QHP_CUST_FILTER_ATTRS =
+QHP_SECT_FILTER_ATTRS =
+QHG_LOCATION =
+GENERATE_ECLIPSEHELP = NO
+ECLIPSE_DOC_ID = org.doxygen.Project
+DISABLE_INDEX = NO
+GENERATE_TREEVIEW = YES
+ENUM_VALUES_PER_LINE = 4
+TREEVIEW_WIDTH = 250
+EXT_LINKS_IN_WINDOW = NO
+FORMULA_FONTSIZE = 10
+FORMULA_TRANSPARENT = YES
+USE_MATHJAX = NO
+MATHJAX_FORMAT = HTML-CSS
+MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
+MATHJAX_EXTENSIONS =
+MATHJAX_CODEFILE =
+SEARCHENGINE = YES
+SERVER_BASED_SEARCH = NO
+EXTERNAL_SEARCH = NO
+SEARCHENGINE_URL =
+SEARCHDATA_FILE = searchdata.xml
+EXTERNAL_SEARCH_ID =
+EXTRA_SEARCH_MAPPINGS =
+GENERATE_LATEX = NO
+LATEX_OUTPUT = latex
+LATEX_CMD_NAME = latex
+MAKEINDEX_CMD_NAME = makeindex
+COMPACT_LATEX = NO
+PAPER_TYPE = a4
+EXTRA_PACKAGES =
+LATEX_HEADER =
+LATEX_FOOTER =
+LATEX_EXTRA_STYLESHEET =
+LATEX_EXTRA_FILES =
+PDF_HYPERLINKS = YES
+USE_PDFLATEX = YES
+LATEX_BATCHMODE = NO
+LATEX_HIDE_INDICES = NO
+LATEX_SOURCE_CODE = NO
+LATEX_BIB_STYLE = plain
+LATEX_TIMESTAMP = NO
+GENERATE_RTF = NO
+RTF_OUTPUT = rtf
+COMPACT_RTF = NO
+RTF_HYPERLINKS = NO
+RTF_STYLESHEET_FILE =
+RTF_EXTENSIONS_FILE =
+RTF_SOURCE_CODE = NO
+GENERATE_MAN = NO
+MAN_OUTPUT = man
+MAN_EXTENSION = .3
+MAN_SUBDIR =
+MAN_LINKS = NO
+GENERATE_XML = YES
+XML_OUTPUT = xml
+XML_PROGRAMLISTING = YES
+GENERATE_DOCBOOK = NO
+DOCBOOK_OUTPUT = docbook
+DOCBOOK_PROGRAMLISTING = NO
+GENERATE_AUTOGEN_DEF = NO
+GENERATE_PERLMOD = NO
+PERLMOD_LATEX = NO
+PERLMOD_PRETTY = YES
+PERLMOD_MAKEVAR_PREFIX =
+ENABLE_PREPROCESSING = YES
+MACRO_EXPANSION = NO
+EXPAND_ONLY_PREDEF = NO
+SEARCH_INCLUDES = YES
+INCLUDE_PATH =
+INCLUDE_FILE_PATTERNS =
+PREDEFINED =
+EXPAND_AS_DEFINED =
+SKIP_FUNCTION_MACROS = YES
+TAGFILES =
+GENERATE_TAGFILE =
+ALLEXTERNALS = NO
+EXTERNAL_GROUPS = YES
+EXTERNAL_PAGES = YES
+PERL_PATH = /usr/bin/perl
+CLASS_DIAGRAMS = YES
+MSCGEN_PATH =
+DIA_PATH =
+HIDE_UNDOC_RELATIONS = YES
+HAVE_DOT = YES
+DOT_NUM_THREADS = 0
+DOT_FONTNAME = Helvetica
+DOT_FONTSIZE = 10
+DOT_FONTPATH =
+CLASS_GRAPH = YES
+COLLABORATION_GRAPH = YES
+GROUP_GRAPHS = YES
+UML_LOOK = NO
+UML_LIMIT_NUM_FIELDS = 10
+TEMPLATE_RELATIONS = NO
+INCLUDE_GRAPH = YES
+INCLUDED_BY_GRAPH = YES
+CALL_GRAPH = NO
+CALLER_GRAPH = NO
+GRAPHICAL_HIERARCHY = YES
+DIRECTORY_GRAPH = YES
+DOT_IMAGE_FORMAT = png
+INTERACTIVE_SVG = NO
+DOT_PATH = /usr/bin
+DOTFILE_DIRS =
+MSCFILE_DIRS =
+DIAFILE_DIRS =
+PLANTUML_JAR_PATH =
+PLANTUML_CFG_FILE =
+PLANTUML_INCLUDE_PATH =
+DOT_GRAPH_MAX_NODES = 50
+MAX_DOT_GRAPH_DEPTH = 0
+DOT_TRANSPARENT = NO
+DOT_MULTI_TARGETS = YES
+GENERATE_LEGEND = YES
+DOT_CLEANUP = YES
diff --git a/doc/sphinx/source/about/about.rst b/doc/sphinx/source/about/about.rst
new file mode 100644
index 00000000..52e76402
--- /dev/null
+++ b/doc/sphinx/source/about/about.rst
@@ -0,0 +1,53 @@
+About
+=====
+
+
+
+License
+~~~~~~~
+
+PopSift is licensed under `MPLv2 license `_.
+
+More info about the license and what you can do with the code can be found at `tldrlegal website `_
+
+SIFT was patented in the United States from 1999-03-08 to 2020-03-28.
+See the `patent link `_ for more information.
+PopSift license only concerns the PopSift source code and does not release users of this code from any requirements that may arise from patents.
+
+Contact us
+~~~~~~~~~~
+
+You can contact us on the public mailing list at
+`alicevision@googlegroups.com `_
+
+You can also contact us privately at
+`alicevision-team@googlegroups.com `_
+
+
+Cite us
+~~~~~~~
+
+If you want to cite this work in your publication, please use the following
+
+.. code:: bibtex
+
+ @inproceedings{Griwodz2018Popsift,
+ author = {Griwodz, Carsten and Calvet, Lilian and Halvorsen, P{\aa}l},
+ title = {Popsift: A Faithful SIFT Implementation for Real-time Applications},
+ booktitle = {Proceedings of the 9th {ACM} Multimedia Systems Conference},
+ series = {MMSys '18},
+ year = {2018},
+ isbn = {978-1-4503-5192-8},
+ location = {Amsterdam, Netherlands},
+ pages = {415--420},
+ numpages = {6},
+ doi = {10.1145/3204949.3208136},
+ acmid = {3208136},
+ publisher = {ACM},
+ address = {New York, NY, USA},
+ }
+
+Acknowledgements
+~~~~~~~~~~~~~~~~
+
+This has been developed in the context of the `European project POPART `_ founded by European Union’s Horizon 2020 research and innovation programme under `grant agreement No 644874 `_.
\ No newline at end of file
diff --git a/doc/sphinx/source/api/api.rst b/doc/sphinx/source/api/api.rst
new file mode 100644
index 00000000..5e9ef3cc
--- /dev/null
+++ b/doc/sphinx/source/api/api.rst
@@ -0,0 +1,25 @@
+API References
+==============
+
+
+Main Classes
+~~~~~~~~~~~~
+
+.. doxygenclass:: SiftJob
+ :members:
+
+.. doxygenclass:: PopSift
+ :members:
+
+.. doxygenstruct:: popsift::Config
+ :members:
+
+
+Functions
+~~~~~~~~~
+
+
+
+
+Utility Classes
+~~~~~~~~~~~~~~~
diff --git a/doc/sphinx/source/api/usage.rst b/doc/sphinx/source/api/usage.rst
new file mode 100644
index 00000000..b226d240
--- /dev/null
+++ b/doc/sphinx/source/api/usage.rst
@@ -0,0 +1,13 @@
+Library usage
+=============
+
+
+
+
+Detection
+~~~~~~~~~
+
+
+
+
+
diff --git a/doc/sphinx/source/biblio.bib b/doc/sphinx/source/biblio.bib
new file mode 100644
index 00000000..f57013dd
--- /dev/null
+++ b/doc/sphinx/source/biblio.bib
@@ -0,0 +1,25 @@
+@inproceedings{Griwodz2018Popsift,
+ author = {Griwodz, Carsten and Calvet, Lilian and Halvorsen, P{\aa}l},
+ title = {Popsift: A Faithful SIFT Implementation for Real-time Applications},
+ booktitle = {Proceedings of the 9th {ACM} Multimedia Systems Conference},
+ series = {MMSys '18},
+ year = {2018},
+ isbn = {978-1-4503-5192-8},
+ location = {Amsterdam, Netherlands},
+ pages = {415--420},
+ numpages = {6},
+ doi = {10.1145/3204949.3208136},
+ acmid = {3208136},
+ publisher = {ACM},
+ address = {New York, NY, USA},
+}
+
+@article{Lowe2003,
+ author = {Lowe, DG},
+ doi = {10.1023/B:VISI.0000029664.99615.94},
+ file = {:home/alcov/.local/share/data/Mendeley Ltd./Mendeley Desktop/Downloaded/Lowe - 2004 - Distinctive image features from scale-invariant keypoints.pdf:pdf},
+ journal = {International journal of computer vision},
+ pages = {1--29},
+ title = {{Distinctive image features from scale-invariant keypoints}},
+ year = {2004}
+}
diff --git a/doc/sphinx/source/bibliography.rst b/doc/sphinx/source/bibliography.rst
new file mode 100644
index 00000000..3e04dc7d
--- /dev/null
+++ b/doc/sphinx/source/bibliography.rst
@@ -0,0 +1,5 @@
+Bibliography
+============
+
+.. bibliography:: biblio.bib
+ :all:
\ No newline at end of file
diff --git a/doc/sphinx/source/conf.py b/doc/sphinx/source/conf.py
new file mode 100644
index 00000000..b85cd593
--- /dev/null
+++ b/doc/sphinx/source/conf.py
@@ -0,0 +1,84 @@
+# Configuration file for the Sphinx documentation builder.
+#
+# This file only contains a selection of the most common options. For a full
+# list see the documentation:
+# https://www.sphinx-doc.org/en/master/usage/configuration.html
+
+# -- Path setup --------------------------------------------------------------
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#
+# import os
+# import sys
+# sys.path.insert(0, os.path.abspath('.'))
+
+import subprocess, os
+
+def configure_doxyfile(input_dir, output_dir):
+ with open('Doxyfile.in', 'r') as file :
+ filedata = file.read()
+
+ filedata = filedata.replace('@DOXYGEN_INPUT_DIR@', input_dir)
+ filedata = filedata.replace('@DOXYGEN_OUTPUT_DIR@', output_dir)
+
+ with open('Doxyfile', 'w') as file:
+ file.write(filedata)
+
+# Check if we're running on Read the Docs' servers
+read_the_docs_build = os.environ.get('READTHEDOCS', None) == 'True'
+
+breathe_projects = {}
+
+if read_the_docs_build:
+ # run doxygen before to generate the xml
+ output_dir = '../build'
+ subprocess.call('doxygen', shell=True)
+ breathe_projects['PopSift'] = output_dir + '/xml'
+
+
+
+
+# -- Project information -----------------------------------------------------
+
+project = u'PopSift'
+copyright = '2020, AliceVision'
+author = 'AliceVision'
+
+
+# -- General configuration ---------------------------------------------------
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
+extensions = ['breathe', 'sphinxcontrib.bibtex']
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+# This pattern also affects html_static_path and html_extra_path.
+exclude_patterns = []
+
+source_suffix = ['.rst', '.md']
+
+# -- Options for HTML output -------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages. See the documentation for
+# a list of builtin themes.
+#
+html_theme = 'sphinx_rtd_theme'
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+# breathe_projects = {
+# "PopSift": "../../doxygen/xml/",
+# }
+
+# Breathe Configuration
+breathe_default_project = 'PopSift'
\ No newline at end of file
diff --git a/doc/sphinx/source/index.rst b/doc/sphinx/source/index.rst
new file mode 100644
index 00000000..457d54ca
--- /dev/null
+++ b/doc/sphinx/source/index.rst
@@ -0,0 +1,36 @@
+PopSift Library
+=============
+
+PopSift is an open-source implementation of the SIFT algorithm in CUDA :cite:`Griwodz2018Popsift`.
+PopSift tries to stick as closely as possible to David Lowe's famous paper :cite:`Lowe2003`, while extracting features from an image in real-time at least on an NVidia GTX 980 Ti GPU.
+
+
+.. toctree::
+ :maxdepth: 2
+ :hidden:
+ :caption: Install
+
+ install/install
+
+.. toctree::
+ :maxdepth: 2
+ :hidden:
+ :caption: API Documentation
+
+ api/usage
+ api/api
+
+
+.. toctree::
+ :maxdepth: 2
+ :hidden:
+ :caption: About
+
+ about/about
+
+.. toctree::
+ :maxdepth: 2
+ :hidden:
+ :caption: References
+
+ bibliography
diff --git a/doc/sphinx/source/install/install.rst b/doc/sphinx/source/install/install.rst
new file mode 100644
index 00000000..fb6eb014
--- /dev/null
+++ b/doc/sphinx/source/install/install.rst
@@ -0,0 +1,250 @@
+Requirements
+============
+
+Hardware
+~~~~~~~~
+
+PopSift is a GPU implementation that requires an NVIDIA GPU card with a CUDA compute capability >= 3.0 (including, e.g. the GT 650M).
+The code is originally developed with the compute capability 5.2 card GTX 980 Ti in mind.
+
+You can check your `NVIDIA GPU card CC support here `_ or on the `NVIDIA dev page `_.
+If you do not have a NVIDIA card you will still able to compile and use the CPU version.
+
+Here are the minimum hardware requirements for PopSift:
+
++--------------------------------------------------------------------------+
+| Minimum requirements |
++===================+======================================================+
+| Operating systems | Windows x64, Linux, macOS |
++-------------------+------------------------------------------------------+
+| CPU | Recent Intel or AMD cpus |
++-------------------+------------------------------------------------------+
+| RAM Memory | 8 GB |
++-------------------+------------------------------------------------------+
+| Hard Drive | No particular requirements |
++-------------------+------------------------------------------------------+
+| GPU | NVIDIA CUDA-enabled GPU (compute capability >= 3.5) |
++-------------------+------------------------------------------------------+
+
+
+
+Software
+~~~~~~~~
+
+The core library depends only on Cuda >= 7.0
+
+The library includes a few sample applications that show how to use the library.
+They require
+
+* Boost >= 1.55 (required components atomic, chrono, date-time, system, thread)
+
+* [optionally] DevIL (libdevil-dev) can be used to load a broader range of image formats, otherwise only pgm is supported.
+
+
+
+------------
+
+
+vcpkg
+=====
+
+`vcpkg `_ is a cross-platform (Windows, Linux and MacOS), open-source package manager created by Microsoft.
+
+We are planning to release a port of the library so that it can be easily built using the package manager on all supported platforms.
+Stay tuned!
+
+
+------------
+
+Building the library
+====================
+
+Building tools
+~~~~~~~~~~~~~~
+
+Required tools:
+
+* CMake >= 3.14 to build the code
+* Git
+* C/C++ compiler supporting the C++11 standard (gcc >= 4.6 or visual studio or clang)
+* CUDA >= 7.0
+
+
+
+Dependencies
+~~~~~~~~~~~~
+
+vcpkg
++++++
+
+vcpkg can be used to install all the dependencies on all the supported platforms.
+This is particularly useful on Windows.
+To install the dependencies:
+
+.. code:: shell
+
+ vcpkg install cuda devil boost-system boost-program-options boost-thread boost-filesystem
+
+You can add the flag :code:`--triplet` to specify the architecture and the version you want to build.
+For example:
+
+* :code:`--triplet x64-windows` will build the dynamic version for Windows 64 bit
+
+* :code:`--triplet x64-windows-static` will build the static version for Windows 64 bit
+
+* :code:`--triplet x64-linux-dynamic` will build the dynamic version for Linux 64 bit
+
+and so on.
+More information can be found `here `_
+
+Linux
++++++
+
+On Linux you can install from the package manager:
+
+For Ubuntu/Debian package system:
+
+.. code:: shell
+
+ sudo apt-get install g++ git-all libboost-all-dev libdevil-dev
+
+
+For CentOS package system:
+
+.. code:: shell
+
+ sudo yum install gcc-c++ git boost-devel devil
+
+
+MacOS
++++++
+
+On MacOs using `Homebrew `_ install the following packages:
+
+.. code:: shell
+
+ brew install git boost devil
+
+
+Getting the sources
+~~~~~~~~~~~~~~~~~~~~
+
+.. code:: shell
+
+ git clone https://github.com/alicevision/PopSift.git
+
+
+CMake configuration
+~~~~~~~~~~~~~~~~~~~
+
+From PopSift root folder you can run cmake:
+
+.. code:: shell
+
+ mkdir build && cd build
+ cmake ..
+ make -j `nproc`
+
+On Windows add :code:`-G "Visual Studio 16 2019" -A x64` to generate the Visual Studio solution according to your VS version (`see CMake documentation `_).
+
+If you are using the dependencies built with VCPKG you need to pass :code:`-DCMAKE_TOOLCHAIN_FILE=path/to/vcpkg/scripts/buildsystems/vcpkg.cmake` at cmake step to let it know where to find the dependencies.
+
+
+CMake options
++++++++++++++
+
+CMake configuration can be controlled by changing the values of the following variables (here with their default value)
+
+
+* :code:`BUILD_SHARED_LIBS:BOOL=ON` to enable/disable the building shared libraries
+
+* :code:`PopSift_BUILD_EXAMPLES:BOOL=ON` to enable/disable the building of applications
+
+* :code:`PopSift_BUILD_DOC:BOOL=OFF` to enable/disable building this documentation and the Doxygen one.
+
+For example, if you do not want to build the applications, you have to pass :code:`-DPopSift_BUILD_EXAMPLES:BOOL=OFF` and so on.
+
+
+------------
+
+
+PopSift as third party
+====================
+
+When you install PopSift a file :code:`PopSiftConfig.cmake` is installed in :code:`/lib/cmake/PopSift/` that allows you to import the library in your CMake project.
+In your :code:`CMakeLists.txt` file you can add the dependency in this way:
+
+.. code-block::
+ :linenos:
+
+ # Find the package from the PopSiftConfig.cmake
+ # in /lib/cmake/PopSift/. Under the namespace PopSift::
+ # it exposes the target PopSift that allows you to compile
+ # and link with the library
+ find_package(PopSift CONFIG REQUIRED)
+ ...
+ # suppose you want to try it out in a executable
+ add_executable(popsiftTest yourfile.cpp)
+ # add link to the library
+ target_link_libraries(popsiftTest PUBLIC PopSift::PopSift)
+
+Then, in order to build just pass the location of :code:`PopSiftConfig.cmake` from the cmake command line:
+
+.. code:: shell
+
+ cmake .. -DPopSift_DIR=/lib/cmake/PopSift/
+
+
+------------
+
+
+
+Docker image
+============
+
+A docker image can be built using the Ubuntu based :code:`Dockerfile`, which is based on nvidia/cuda image (https://hub.docker.com/r/nvidia/cuda/ )
+
+
+Building the dependency image
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+We provide a :code:`Dockerfile_deps` containing a cuda image with all the necessary PopSift dependencies installed.
+
+A parameter :code:`CUDA_TAG` can be passed when building the image to select the cuda version.
+Similarly, :code:`OS_TAG` can be passed to select the Ubuntu version.
+By default, :code:`CUDA_TAG=10.2` and :code:`OS_TAG=18.04`
+
+For example to create the dependency image based on ubuntu 18.04 with cuda 8.0 for development, use
+
+.. code:: shell
+
+ docker build --build-arg CUDA_TAG=8.0 --tag alicevision/popsift-deps:cuda8.0-ubuntu18.04 -f Dockerfile_deps .
+
+The complete list of available tags can be found on the nvidia [dockerhub page](https://hub.docker.com/r/nvidia/cuda/)
+
+
+Building the PopSift image
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Once you built the dependency image, you can build the popsift image in the same manner using :code:`Dockerfile`:
+
+.. code:: shell
+
+ docker build --tag alicevision/popsift:cuda8.0-ubuntu18.04 .
+
+
+Running the PopSift image
+~~~~~~~~~~~~~~~~~~~~~~~
+
+In order to run the image nvidia docker is needed: see the `installation instruction `_.
+Once installed, the docker can be run, e.g., in interactive mode with
+
+.. code:: shell
+
+ docker run -it --runtime=nvidia alicevision/popsift:cuda8.0-ubuntu18.04
+
+
+Official images on DockeHub
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Check the docker hub `PopSift repository `_ for the available images.
\ No newline at end of file
diff --git a/src/popsift/common/device_prop.h b/src/popsift/common/device_prop.h
index 8828fd4a..ed5db2b2 100644
--- a/src/popsift/common/device_prop.h
+++ b/src/popsift/common/device_prop.h
@@ -10,8 +10,12 @@
#include
#include
-namespace popsift { namespace cuda {
+namespace popsift {
+namespace cuda {
+/**
+ * @brief A class to recover, query and print the information about the cuda device.
+ */
class device_prop_t
{
int _num_devices;
@@ -27,36 +31,48 @@ class device_prop_t
device_prop_t( );
~device_prop_t( );
+ /**
+ * @brief Print the information about the device.
+ */
void print( );
+
+ /**
+ * @brief Set the device to use.
+ * @param[in] n The index of the device to use.
+ * @param[in] print_choice Whether to print information about the chosen device.
+ */
void set( int n, bool print_choice = false );
- /** Check if a request exceeds the current CUDA device's limit in
+ /**
+ * @brief Check if a request exceeds the current CUDA device's limit in
* texture2Dlinear dimensions. texture2Dlinear is based on CUDA memory that
* can be accessed directly (i.e. no CudaArray).
* @param[in,out] width Desired width of the texture.
* @param[in,out] height Desired height of the texture.
* @param[in] printWarn if true, print warnings to cerr if desired width
* or height exceeds limits.
- * @return { true if the desired width and height are possible.
- * false if one or both of the desired width and height are impossible.
- * The desired width or height (or both) are replaced by the limit.}
+ * @return \p true if the desired width and height are possible.
+ * \p false if one or both of the desired width and height are impossible.
+ * The desired width or height (or both) are replaced by the limit.
*/
bool checkLimit_2DtexLinear( int& width, int& height, bool printWarn ) const;
- /** Check if a request exceeds the current CUDA device's limit in
+ /**
+ * @brief Check if a request exceeds the current CUDA device's limit in
* texture2D dimensions. texture2D is based on CUDA Arrays, which have
* invisible layout and can only be filled with cudaMemcpy.
* @param[in,out] width Desired width of the texture.
* @param[in,out] height Desired height of the texture.
* @param[in] printWarn if true, print warnings to cerr if desired width
* or height exceeds limits.
- * @return { true if the desired width and height are possible.
- * false if one or both of the desired width and height are impossible.
- * The desired width or height (or both) are replaced by the limit.}
+ * @return \p true if the desired width and height are possible.
+ * \p false if one or both of the desired width and height are impossible.
+ * The desired width or height (or both) are replaced by the limit.
*/
bool checkLimit_2DtexArray( int& width, int& height, bool printWarn ) const;
- /** Check if a request exceeds the current CUDA device's limit in
+ /**
+ * @brief Check if a request exceeds the current CUDA device's limit in
* texture2DLayered dimensions. texture2DLayered refers to a 3D structure, where
* interpolation happens only in 3D, effectively creating layers.
* @param[in,out] width Desired width of the texture.
@@ -64,15 +80,16 @@ class device_prop_t
* @param[in,out] layers Desired depth of the texture.
* @param[in] printWarn if true, print warnings to cerr if desired width
* or height exceeds limits.
- * @return { true if the desired width, height and depth are possible.
- * false if one or both of the desired width and height are impossible.
+ * @return \p true if the desired width, height and depth are possible.
+ * \p false if one or both of the desired width and height are impossible.
* The desired width, height and layers are replaced by the limit
- * if they exceed it.}
+ * if they exceed it.
*/
bool checkLimit_2DtexLayered( int& width, int& height, int& layers,
bool printWarn ) const;
- /** Check if a request exceeds the current CUDA device's limit in
+ /**
+ * @brief Check if a request exceeds the current CUDA device's limit in
* surface2DLayered dimensions. surface2DLayered is the writable equivalent
* to texture2DLayered, but the width must be given in bytes, not elements.
* Since we use float, images cannot be as wide as expected.
@@ -81,10 +98,10 @@ class device_prop_t
* @param[in,out] layers Desired depth of the texture.
* @param[in] printWarn if true, print warnings to cerr if desired width
* or height exceeds limits.
- * @return { true if the desired width, height and depth are possible.
- * false if one or both of the desired width and height are impossible.
+ * @return \p true if the desired width, height and depth are possible.
+ * \p false if one or both of the desired width and height are impossible.
* The desired width, height and layers are replaced by the limit
- * if they exceed it.}
+ * if they exceed it.
*/
bool checkLimit_2DsurfLayered( int& width, int& height, int& layers,
bool printWarn ) const;
diff --git a/src/popsift/features.h b/src/popsift/features.h
index 1e1a31dd..3b16f954 100755
--- a/src/popsift/features.h
+++ b/src/popsift/features.h
@@ -16,7 +16,8 @@ namespace popsift {
struct Descriptor; // float features[128];
-/* This is a data structure that is returned to a calling program.
+/**
+ * @brief This is a data structure that is returned to a calling program.
* The xpos/ypos information in feature is scale-adapted.
*/
struct Feature
@@ -24,9 +25,11 @@ struct Feature
int debug_octave;
float xpos;
float ypos;
- float sigma; // scale;
- int num_ori; // number of this extremum's orientations
- // remaining entries in desc are 0
+ /// scale
+ float sigma;
+ /// number of this extremum's orientations
+ /// remaining entries in desc are 0
+ int num_ori;
float orientation[ORIENTATION_MAX_COUNT];
Descriptor* desc[ORIENTATION_MAX_COUNT];
@@ -52,7 +55,8 @@ class FeaturesBase
inline void setDescriptorCount( int num_ori ) { _num_ori = num_ori; }
};
-/* This is a data structure that is returned to a calling program.
+/**
+ * @brief This is a data structure that is returned to a calling program.
* _ori is a transparent flat memory holding descriptors
* that are referenced by the extrema.
*
@@ -93,7 +97,7 @@ class FeaturesHost : public FeaturesBase
friend class Pyramid;
};
-typedef FeaturesHost Features;
+using Features = FeaturesHost;
std::ostream& operator<<( std::ostream& ostr, const FeaturesHost& feature );
diff --git a/src/popsift/popsift.h b/src/popsift/popsift.h
index 631a7196..446e103a 100755
--- a/src/popsift/popsift.h
+++ b/src/popsift/popsift.h
@@ -52,16 +52,38 @@ class SiftJob
#endif
public:
- /** Constructor for byte images, value range 0..255 */
+
+ /**
+ * @brief Constructor for byte images, value range 0..255
+ * @param[in] w the width in pixel of the image
+ * @param[in] h the height in pixel of the image
+ * @param[in] imageData the image buffer
+ */
SiftJob( int w, int h, const unsigned char* imageData );
- /** Constructor for float images, value range [0..1[ */
+ /**
+ * @brief Constructor for float images, value range [0..1[
+ * @param[in] w the width in pixel of the image
+ * @param[in] h the height in pixel of the image
+ * @param[in] imageData the image buffer
+ */
SiftJob( int w, int h, const float* imageData );
+ /**
+ * @brief Destructor releases all the resources.
+ */
~SiftJob( );
- popsift::FeaturesHost* get(); // should be deprecated, same as getHost()
+ /**
+ * @deprecated
+ * @see getHost()
+ */
+ popsift::FeaturesHost* get();
popsift::FeaturesBase* getBase();
+ /**
+ * @brief
+ * @return
+ */
popsift::FeaturesHost* getHost();
popsift::FeaturesDev* getDev();
@@ -72,6 +94,9 @@ class SiftJob
void setFeatures( popsift::FeaturesBase* f );
};
+/**
+ * @brief
+ */
class PopSift
{
struct Pipe
@@ -91,16 +116,28 @@ class PopSift
};
public:
+
+ /**
+ * @brief Image modes
+ */
enum ImageMode
{
+ /// byte image, value range 0..255
ByteImages,
+ /// float images, value range [0..1[
FloatImages
};
+ /**
+ * @brief Results for the allocation test.
+ */
enum AllocTest
{
+ /// the image dimensions are supported by this device's CUDA texture engine.
Ok,
+ /// the input image size exceeds the dimensions of the CUDA Texture used for loading.
ImageExceedsLinearTextureLimit,
+ /// the scaled input image exceeds the dimensions of the CUDA Surface used for the image pyramid.
ImageExceedsLayeredSurfaceLimit
};
@@ -109,27 +146,46 @@ class PopSift
PopSift() = delete;
PopSift(const PopSift&) = delete;
- /* We support more than 1 streams, but we support only one sigma and one
+ /**
+ * @brief We support more than 1 streams, but we support only one sigma and one
* level parameters.
*/
explicit PopSift( ImageMode imode = ByteImages );
- explicit PopSift( const popsift::Config& config,
- popsift::Config::ProcessingMode mode = popsift::Config::ExtractingMode,
- ImageMode imode = ByteImages );
+
+ /**
+ * @brief
+ * @param config
+ * @param mode
+ * @param imode
+ */
+ explicit PopSift(const popsift::Config& config,
+ popsift::Config::ProcessingMode mode = popsift::Config::ExtractingMode,
+ ImageMode imode = ByteImages);
+
+ /**
+ * @brief Release all the resources.
+ */
~PopSift();
public:
- /** Provide the configuration if you used the PopSift default
- * constructor */
+ /**
+ * @brief Provide the configuration if you used the PopSift default
+ * constructor
+ */
bool configure( const popsift::Config& config, bool force = false );
+ /**
+ * @brief Release the resources.
+ */
void uninit( );
- /** Check whether the current CUDA device can support the image
+ /**
+ * @brief Check whether the current CUDA device can support the image
* resolution (width,height) with the current configuration
* based on the card's texture engine.
* The function does not check if there is sufficient available
* memory.
+ *
* The first part of the test depends on the parameters width and
* height. It checks whether the image size is supported by CUDA
* 2D linear textures on this card. This is used to load the image
@@ -142,8 +198,9 @@ class PopSift
* "levels", because it determines the number of levels in each
* octave. The CUDA 2D layered texture must support enough depth
* for each level.
- * @param width The width of the input image
- * @param height The height of the input image
+ *
+ * @param[in] width The width of the input image
+ * @param[in] height The height of the input image
* @return AllocTest::Ok if the image dimensions are supported by this device's
* CUDA texture engine,
* AllocTest::ImageExceedsLinearTextureLimit if the input image size
@@ -152,41 +209,60 @@ class PopSift
* AllocTest::ImageExceedsLayeredSurfaceLimit if the scaled input
* image exceeds the dimensions of the CUDA Surface used for the
* image pyramid. The scaling factor must be changes to fit in.
- * @remark { If you want to call configure() before extracting features,
- * you should call configure() before textTextureFit(). }
- * @remark { The current CUDA device is determined by a call to
- * cudaGetDevice(), card properties are only read once. }
+ * @remark * If you want to call configure() before extracting features,
+ * you should call configure() before textTextureFit().
+ * @remark * The current CUDA device is determined by a call to
+ * cudaGetDevice(), card properties are only read once.
+ * @see AllocTest
*/
AllocTest testTextureFit( int width, int height );
- /** Create a warning string for an AllocTest error code. */
+ /**
+ * @brief Create a warning string for an AllocTest error code.
+ */
std::string testTextureFitErrorString( AllocTest err, int w, int h );
- /** Enqueue a byte image, value range 0..255 */
+ /**
+ * @brief Enqueue a byte image, value range [0,255].
+ * @param[in] w the width of the image.
+ * @param[in] h the height of the image.
+ * @param[in] imageData the image buffer.
+ * @return the associated job
+ * @see SiftJob
+ */
SiftJob* enqueue( int w,
int h,
const unsigned char* imageData );
- /** Enqueue a float image, value range 0..1 */
+ /**
+ * @brief Enqueue a float image, value range [0,1].
+ * @param[in] w the width of the image.
+ * @param[in] h the height of the image.
+ * @param[in] imageData the image buffer.
+ * @return the associated job
+ * @see SiftJob
+ */
SiftJob* enqueue( int w,
int h,
const float* imageData );
/**
* @deprecated
- * */
+ */
inline void uninit( int /*pipe*/ ) { uninit(); }
/**
* @deprecated
- **/
+ */
inline bool init( int /*pipe*/, int w, int h ) {
_last_init_w = w;
_last_init_h = h;
return true;
}
- /** deprecated */
+ /**
+ * @deprecated
+ */
inline popsift::FeaturesBase* execute( int /*pipe*/, const unsigned char* imageData )
{
SiftJob* j = enqueue( _last_init_w, _last_init_h, imageData );
@@ -201,7 +277,7 @@ class PopSift
void private_apply_scale_factor( int& w, int& h );
void uploadImages( );
- /* The following method are alternative worker functions for Jobs submitted by
+ /* The following methods are alternative worker functions for Jobs submitted by
* a calling application. The choice of method is made by the mode parameter
* in the PopSift constructor. */
diff --git a/src/popsift/sift_conf.h b/src/popsift/sift_conf.h
index ecb5ea2f..583a958c 100644
--- a/src/popsift/sift_conf.h
+++ b/src/popsift/sift_conf.h
@@ -21,14 +21,22 @@
#else
#endif
-namespace popsift
-{
+namespace popsift {
+/**
+ * @brief Struct containing the parameters that control the extraction algorithm
+ */
struct Config
{
- Config( );
+ Config();
- enum GaussMode {
+ /**
+ * @brief The way the gaussian mode is compute.
+ *
+ * Each setting allows to mimic and reproduce the behaviour of other Sift implementations.
+ */
+ enum GaussMode
+ {
VLFeat_Compute,
VLFeat_Relative,
VLFeat_Relative_All,
@@ -37,68 +45,145 @@ struct Config
Fixed15
};
- enum SiftMode {
+ /**
+ * @brief General setting to reproduce the results of other Sift implementations.
+ */
+ enum SiftMode
+ {
+ /// Popsift implementation
PopSift,
+ /// OpenCV implementation
OpenCV,
+ /// VLFeat implementation
VLFeat,
+ /// Default implementation is PopSift
Default = PopSift
};
- enum LogMode {
+ /**
+ * @brief The logging mode.
+ */
+ enum LogMode
+ {
None,
All
};
- enum ScalingMode {
+ /**
+ * @brief The scaling mode.
+ */
+ enum ScalingMode
+ {
ScaleDirect,
- ScaleDefault // Indirect - only working method
+ /// Indirect - only working method
+ ScaleDefault
};
- /* Modes for descriptor extraction: */
- enum DescMode {
- Loop, // scan horizontal, extract valid points
- ILoop, // scan horizontal, extract valid points, interpolate with tex engine
- Grid, // scan in rotated mode, round pixel address
- IGrid, // scan in rotated mode, interpolate with tex engine
- NoTile // variant of IGrid, no duplicate gradiant fetching
+ /**
+ * @brief Modes for descriptor extraction.
+ */
+ enum DescMode
+ {
+ /// scan horizontal, extract valid points
+ Loop,
+ /// scan horizontal, extract valid points, interpolate with tex engine
+ ILoop,
+ /// scan in rotated mode, round pixel address
+ Grid,
+ /// scan in rotated mode, interpolate with tex engine
+ IGrid,
+ /// variant of IGrid, no duplicate gradient fetching
+ NoTile
};
- enum NormMode {
- RootSift, // The L1-inspired norm, gives better matching results
- Classic // The L2-inspired norm, all descriptors on a hypersphere
+ /**
+ * @brief Type of norm to use for matching.
+ */
+ enum NormMode
+ {
+ /// The L1-inspired norm, gives better matching results ("RootSift")
+ RootSift,
+ /// The L2-inspired norm, all descriptors on a hypersphere ("classic")
+ Classic
};
- /* To reduce time used in descriptor extraction, some extrema can be filtered
+ /**
+ * @brief Filtering strategy.
+ *
+ * To reduce time used in descriptor extraction, some extrema can be filtered
* immediately after finding them. It is possible to keep those with the largest
* scale (LargestScaleFirst), smallest scale (SmallestScaleFirst), or a random
* selection. Note that largest and smallest give a stable result, random does not.
*/
enum GridFilterMode {
+ /// keep a random selection
RandomScale,
+ /// keep those with the largest scale
LargestScaleFirst,
+ /// keep those with the smallest scale
SmallestScaleFirst
};
- /* A parameter for the PopSift constructor. Determines which data is kept in
- * the Job data structure after processing, which is downloaded to the host,
- * which is invalidated.
+ /**
+ * @brief Processing mode.
+ *
+ * Determines which data is kept in the Job data structure after processing, which one is downloaded to the host,
+ * which one is invalidated.
*/
enum ProcessingMode {
ExtractingMode,
MatchingMode
};
+ /**
+ * @brief Set the Gaussian mode from string.
+ * @param[in] m The string version of the GaussMode
+ * @see GaussMode
+ */
void setGaussMode( const std::string& m );
+ /**
+ * @brief Set the Gaussian mode.
+ * @param[in] m The Gaussian mode to use.
+ */
void setGaussMode( GaussMode m );
+
+ /**
+ * @brief Set the Sift mode.
+ * @param[in] m The Sift mode
+ * @see SiftMode
+ */
void setMode( SiftMode m );
+
+ /**
+ * @brief Set the log mode.
+ * @param mode The log mode.
+ * @see LogMode
+ */
void setLogMode( LogMode mode = All );
void setScalingMode( ScalingMode mode = ScaleDefault );
+
+ /**
+ * @brief Enable/desable verbose mode.
+ * @param[in] on Whether to display additional information .
+ */
void setVerbose( bool on = true );
+
+ /**
+ * @brief Set the descriptor mode by string.
+ * @param[in] byname The string containing the descriptor mode.
+ * @see DescMode
+ */
void setDescMode( const std::string& byname );
+
+ /**
+ * @brief Set the descriptor mode.
+ * @param[in] mode The descriptor mode.
+ * @see DescMode
+ */
void setDescMode( DescMode mode = Loop );
- void setGaussGroup( int groupsize );
- int getGaussGroup( ) const;
+// void setGaussGroup( int groupsize );
+// int getGaussGroup( ) const;
void setDownsampling( float v );
void setOctaves( int v );
@@ -107,9 +192,9 @@ struct Config
void setEdgeLimit( float v );
void setThreshold( float v );
void setInitialBlur( float blur );
- void setMaxExtreme( int m );
+// void setMaxExtreme( int m );
void setPrintGaussTables( );
- void setDPOrientation( bool on );
+// void setDPOrientation( bool on );
void setFilterMaxExtrema( int extrema );
void setFilterGridSize( int sz );
void setFilterSorting( const std::string& direction );
@@ -118,63 +203,80 @@ struct Config
bool hasInitialBlur( ) const;
float getInitialBlur( ) const;
- // computes the actual peak threshold depending on the threshold
- // parameter and the non-augmented number of levels
+ /// computes the actual peak threshold depending on the threshold
+ /// parameter and the non-augmented number of levels
float getPeakThreshold() const;
- // print Gauss spans and tables?
+ /// print Gauss spans and tables?
bool ifPrintGaussTables() const;
- // What Gauss filter scan is desired?
+ /// What Gauss filter scan is desired?
GaussMode getGaussMode( ) const;
- // Call this from the constructor.
+ /// Call this from the constructor.
static GaussMode getGaussModeDefault( );
+
// Helper functions for the main program's usage string.
+ /**
+ * @brief Get a message with the strings to use for setting the values of \p GaussMode
+ * @return A message with the list of strings
+ */
static const char* getGaussModeUsage( );
- // get the SIFT mode for more detailed sub-modes
+ /**
+ * @brief Get the SIFT mode for more detailed sub-modes
+ * @return The SiftMode
+ * @see SiftMode
+ */
SiftMode getSiftMode() const;
- // find out if we should print logging info or not
+ /// find out if we should print logging info or not
LogMode getLogMode() const;
- // The number of octaves is chosen freely. If not specified,
- // it is: log_2( min(x,y) ) - 3 - start_sampling
+ /// The number of octaves is chosen freely. If not specified,
+ /// it is: log_2( min(x,y) ) - 3 - start_sampling
int octaves;
- // The number of levels per octave. This is actually the
- // number of inner DoG levels where we can search for
- // feature points. The number of ...
- //
- // This is the non-augmented number of levels, meaning
- // the this is not the number of gauss-filtered picture
- // layers (which is levels+3), but the number of DoG
- // layers in which we can search for extrema.
+ /// The number of levels per octave. This is actually the
+ /// number of inner DoG levels where we can search for
+ /// feature points. The number of ...
+ ///
+ /// This is the non-augmented number of levels, meaning
+ /// the this is not the number of gauss-filtered picture
+ /// layers (which is levels+3), but the number of DoG
+ /// layers in which we can search for extrema.
int levels;
float sigma;
- // default edge_limit 16.0f from Celebrandil
- // default edge_limit 10.0f from Bemap
+ /// default edge_limit 16.0f from Celebrandil
+ /// default edge_limit 10.0f from Bemap
float _edge_limit;
/** Functions related to descriptor normalization: L2-like or RootSift
*/
void setNormMode( NormMode m );
void setNormMode( const std::string& m );
+ /**
+ * @brief Set the normalization mode.
+ * @param[in] on Use RootSift (\p true) or the L2-norm (\p false).
+ * @deprecated
+ * @see NormMode
+ */
DEPRECATED(void setUseRootSift( bool on ));
bool getUseRootSift( ) const;
NormMode getNormMode( NormMode m ) const;
static NormMode getNormModeDefault( ); // Call this from the constructor.
static const char* getNormModeUsage( ); // Helper functions for the main program's usage string.
- /** Functions related to descriptor normalization: multiply with a power of 2
+ /**
+ * @brief Functions related to descriptor normalization: multiply with a power of 2
*/
int getNormalizationMultiplier( ) const;
void setNormalizationMultiplier( int mul );
- /* The input image is stretched by 2^upscale_factor
+ /**
+ * @brief The input image is stretched by 2^upscale_factor
* before processing. The factor 1 is default.
*/
inline float getUpscaleFactor( ) const {
@@ -185,125 +287,124 @@ struct Config
return _max_extrema;
}
- /* Have we enabled filtering? This is a compile time decision.
+ /**
+ * Have we enabled filtering? This is a compile time decision.
* The reason is that we use Thrust, which increases compile
* considerably and can be deactivated at the CMake level when
* you work on something else.
*/
bool getCanFilterExtrema() const;
- /* Set the approximate number of extrema whose orientation and descriptor
+ /**
+ * Set the approximate number of extrema whose orientation and descriptor
* should be computed. Default is -1, which sets the hard limit defined
* by "number of octaves * getMaxExtrema()".
*/
- int getFilterMaxExtrema( ) const {
- return _filter_max_extrema;
- }
+ int getFilterMaxExtrema() const { return _filter_max_extrema; }
- /* To avoid that grid filtering happens only in a tiny piece of an image,
+ /**
+ * @brief Get the grid size for filtering.
+ *
+ * To avoid that grid filtering happens only in a tiny piece of an image,
* the image is split into getFilterGridSize() X getFilterGridSize() tiles
* and we allow getFilterMaxExtrema() / getFilterGridSize() extrema in
* each tile.
*/
- int getFilterGridSize( ) const {
- return _filter_grid_size;
- }
+ int getFilterGridSize() const { return _filter_grid_size; }
- /* See enum GridFilterMode */
- GridFilterMode getFilterSorting() const {
- return _grid_filter_mode;
- }
+ /**
+ * @brief Get the filtering mode.
+ * @return the filtering mode.
+ * @see GridFilterMode
+ */
+ GridFilterMode getFilterSorting() const { return _grid_filter_mode; }
- // check if we use direct downscaling from input image
- // for all octaves
- inline ScalingMode getScalingMode() const {
- return _scaling_mode;
- }
+ /**
+ * @brief Get the scaling mode.
+ * @return the descriptor extraction mode.
+ * @see ScalingMode
+ */
+ inline ScalingMode getScalingMode() const { return _scaling_mode; }
- inline DescMode getDescMode() const {
- return _desc_mode;
- }
+ /**
+ * @brief Get the descriptor extraction mode
+ * @return the descriptor extraction mode
+ * @see DescMode
+ */
+ inline DescMode getDescMode() const { return _desc_mode; }
bool equal( const Config& other ) const;
private:
- // default threshold 0.0 default of vlFeat
- // default threshold 5.0 / 256.0
- // default threshold 15.0 / 256.0 - it seems our DoG is really small ???
- // default threshold 5.0 from Celebrandil, not happening in our data
- // default threshold 0.04 / (_levels-3.0) / 2.0f * 255
- // from Bemap -> 1.69 (makes no sense)
+ /// default threshold 0.0 default of vlFeat
+ /// default threshold 5.0 / 256.0
+ /// default threshold 15.0 / 256.0 - it seems our DoG is really small ???
+ /// default threshold 5.0 from Celebrandil, not happening in our data
+ /// default threshold 0.04 / (_levels-3.0) / 2.0f * 255
+ /// from Bemap -> 1.69 (makes no sense)
float _threshold;
- // determine the image format of the first octave
- // relative to the input image's size (x,y) as follows:
- // (x / 2^start_sampling, y / 2^start_sampling )
+ /// determine the image format of the first octave
+ /// relative to the input image's size (x,y) as follows:
+ /// (x / 2^start_sampling, y / 2^start_sampling )
float _upscale_factor;
- // default LogMode::None
+ /// default LogMode::None
LogMode _log_mode;
- // default: ScalingMode::DownscaledOctaves
+ /// default: ScalingMode::DownscaledOctaves
ScalingMode _scaling_mode;
- // default: DescMode::Loop
+ /// default: DescMode::Loop
DescMode _desc_mode;
- // default: RandomScale
+ /// default: RandomScale
GridFilterMode _grid_filter_mode;
public:
bool verbose;
private:
- /* The number of initial extrema that can be discovered in an octave.
- * This parameter changes memory requirements.
- */
+ /// The number of initial extrema that can be discovered in an octave.
+ /// This parameter changes memory requirements.
int _max_extrema;
- /* The maximum number of extrema that are returned. There may be
- * several descriptors for each extremum.
- */
+ /// The maximum number of extrema that are returned. There may be
+ /// several descriptors for each extremum.
int _filter_max_extrema;
- // Used to achieve an approximation of _max_entrema
- // Subdivide the image in this number of vertical and horizontal tiles,
- // i.e. the grid is actually _grid_size X _grid_size tiles.
- // default: 1
+ /// Used to achieve an approximation of _max_entrema
+ /// Subdivide the image in this number of vertical and horizontal tiles,
+ /// i.e. the grid is actually _grid_size X _grid_size tiles.
+ /// default: 1
int _filter_grid_size;
- /* Modes are computation according to VLFeat or OpenCV,
- * or fixed size. Default is VLFeat mode.
- */
+ /// Modes are computation according to VLFeat or OpenCV,
+ /// or fixed size. Default is VLFeat mode.
GaussMode _gauss_mode;
- /* Modes are PopSift, OpenCV and VLFeat.
- * Default is currently identical to PopSift.
- */
+ /// Modes are PopSift, OpenCV and VLFeat.
+ /// Default is currently identical to PopSift.
SiftMode _sift_mode;
- /* VLFeat code assumes that an initial input image is partially blurred.
- * This changes the blur computation for the very first level of the first
- * octave, turning it into a special case.
- */
+ /// VLFeat code assumes that an initial input image is partially blurred.
+ /// This changes the blur computation for the very first level of the first
+ /// octave, turning it into a special case.
bool _assume_initial_blur;
float _initial_blur;
- /* OpenMVG requires a normalization named rootSift, the
- * classical L2-inspired mode is also supported.
- */
+ /// OpenMVG requires a normalization named rootSift, the
+ /// classical L2-inspired mode is also supported.
NormMode _normalization_mode;
- /* SIFT descriptors are normalized in a final step.
- * The values of the descriptor can also be multiplied
- * by a power of 2 if required.
- * Specify the exponent.
- */
+ /// SIFT descriptors are normalized in a final step.
+ /// The values of the descriptor can also be multiplied
+ /// by a power of 2 if required.
+ /// Specify the exponent.
int _normalization_multiplier;
- /* Call the debug functions in gauss_filter.cu to print Gauss
- * filter width and Gauss tables in use.
- */
+ /// Call the debug functions in gauss_filter.cu to print Gauss
+ /// filter width and Gauss tables in use.
bool _print_gauss_tables;
};
diff --git a/src/popsift/sift_extremum.h b/src/popsift/sift_extremum.h
index c3e41954..0363a02e 100755
--- a/src/popsift/sift_extremum.h
+++ b/src/popsift/sift_extremum.h
@@ -14,7 +14,8 @@
namespace popsift {
-/* This is an internal data structure.
+/**
+ * @brief This is an internal data structure.
* Separated from the final Extremum data structure to implement
* grid filtering in a space-efficient manner. In grid filtering,
* extrema are first found, after that some may be discarded in
@@ -25,14 +26,20 @@ struct InitialExtremum
{
float xpos;
float ypos;
- int lpos; // extremum refined into this level
- float sigma; // scale;
- int cell; // index into the grid for grid-based extrema filtering
- bool ignore; // true if this extremum has been filtered
- int write_index; // if any initial extrema are ignored, new index for Extremum
+ /// extremum refined into this level
+ int lpos;
+ /// scale
+ float sigma;
+ /// index into the grid for grid-based extrema filtering
+ int cell;
+ /// true if this extremum has been filtered
+ bool ignore;
+ /// if any initial extrema are ignored, new index for Extremum
+ int write_index;
};
-/* This is an internal data structure.
+/**
+ * @brief This is an internal data structure.
* For performance reasons, it would be appropriate to split
* the first 4 values from the rest of this structure. Right
* now, descriptor computation is a bigger concern.
@@ -41,16 +48,22 @@ struct Extremum
{
float xpos;
float ypos;
- int lpos; // extremum refined into this level
- float sigma; // scale;
+ /// extremum refined into this level
+ int lpos;
+ /// scale
+ float sigma;
- int octave; // belonging to this octave
- int num_ori; // number of this extremum's orientations
- int idx_ori; // exclusive prefix sum of the layer's orientations
+ /// belonging to this octave
+ int octave;
+ /// number of this extremum's orientations
+ int num_ori;
+ /// exclusive prefix sum of the layer's orientations
+ int idx_ori;
float orientation[ORIENTATION_MAX_COUNT];
};
-/* This is a data structure that is returned to a calling program.
+/**
+ * @brief This is a data structure that is returned to a calling program.
* This is the SIFT descriptor itself.
*/
struct Descriptor
diff --git a/src/popsift/sift_octave.h b/src/popsift/sift_octave.h
index 927b1cb1..fc2ad13b 100755
--- a/src/popsift/sift_octave.h
+++ b/src/popsift/sift_octave.h
@@ -131,10 +131,14 @@ class Octave
return _dog_3d_tex_linear;
}
- /**
- * alloc() - allocates all GPU memories for one octave
- * @param width in floats, not bytes!!!
- */
+ /**
+ * @brief Allocates all GPU memories for one octave.
+ * @param conf
+ * @param width in floats
+ * @param height
+ * @param levels
+ * @param gauss_group
+ */
void alloc( const Config& conf,
int width,
int height,