diff --git a/doc/conf.py b/doc/conf.py new file mode 100644 index 0000000000000000000000000000000000000000..7bef0dee123d04c73277ba3984f233ad391f76f2 --- /dev/null +++ b/doc/conf.py @@ -0,0 +1,266 @@ +#!/usr/bin/env python +# vim: set fileencoding=utf-8 : + +import os +import sys +import glob +import pkg_resources + + +# -- General configuration ----------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +needs_sphinx = '1.3' + +# Add any Sphinx extension module names here, as strings. They can be extensions +# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. +extensions = [ + 'sphinx.ext.todo', + 'sphinx.ext.coverage', + 'sphinx.ext.ifconfig', + 'sphinx.ext.autodoc', + 'sphinx.ext.autosummary', + 'sphinx.ext.doctest', + 'sphinx.ext.graphviz', + 'sphinx.ext.intersphinx', + 'sphinx.ext.napoleon', + 'sphinx.ext.viewcode', + 'matplotlib.sphinxext.plot_directive' + ] + +import sphinx +if sphinx.__version__ >= "1.4.1": + extensions.append('sphinx.ext.imgmath') + imgmath_image_format = 'svg' +else: + extensions.append('sphinx.ext.pngmath') + +# Be picky about warnings +nitpicky = True + +# Ignores stuff we can't easily resolve on other project's sphinx manuals +nitpick_ignore = [] + +# Allows the user to override warnings from a separate file +if os.path.exists('nitpick-exceptions.txt'): + for line in open('nitpick-exceptions.txt'): + if line.strip() == "" or line.startswith("#"): + continue + dtype, target = line.split(None, 1) + target = target.strip() + try: # python 2.x + target = unicode(target) + except NameError: + pass + nitpick_ignore.append((dtype, target)) + +# Always includes todos +todo_include_todos = True + +# Generates auto-summary automatically +autosummary_generate = True + +# Create numbers on figures with captions +numfig = True + +# If we are on OSX, the 'dvipng' path maybe different +dvipng_osx = '/opt/local/libexec/texlive/binaries/dvipng' +if os.path.exists(dvipng_osx): pngmath_dvipng = dvipng_osx + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The encoding of source files. +#source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'bob.ip.qualitymeasure' +import time +copyright = u'%s, Idiap Research Institute' % time.strftime('%Y') + +# Grab the setup entry +distribution = pkg_resources.require(project)[0] + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = distribution.version +# The full version, including alpha/beta/rc tags. +release = distribution.version + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +#language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = ['links.rst'] + +# The reST default role (used for this markup: `text`) to use for all documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + +# Some variables which are useful for generated material +project_variable = project.replace('.', '_') +short_description = u'Extraction of image quality measures for face-PAD experiments.' +owner = [u'Idiap Research Institute'] + + +# -- Options for HTML output --------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +import sphinx_rtd_theme +html_theme = 'sphinx_rtd_theme' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +#html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = project_variable + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +html_logo = 'img/logo.png' + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +html_favicon = 'img/favicon.ico' + +# 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'] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +#html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +#html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = None + +# Output file base name for HTML help builder. +htmlhelp_basename = project_variable + u'_doc' + + +# -- Post configuration -------------------------------------------------------- + +# Included after all input documents +rst_epilog = """ +.. |project| replace:: Bob +.. |version| replace:: %s +.. |current-year| date:: %%Y +""" % (version,) + +# Default processing flags for sphinx +autoclass_content = 'class' +autodoc_member_order = 'bysource' +autodoc_default_flags = [ + 'members', + 'undoc-members', + 'inherited-members', + 'show-inheritance', + ] + +# For inter-documentation mapping: +from bob.extension.utils import link_documentation, load_requirements +sphinx_requirements = "extra-intersphinx.txt" +if os.path.exists(sphinx_requirements): + intersphinx_mapping = link_documentation(additional_packages=['python', 'numpy']+load_requirements(sphinx_requirements)) +else: + intersphinx_mapping = link_documentation() + + +# We want to remove all private (i.e. _. or __.__) members +# that are not in the list of accepted functions +accepted_private_functions = ['__array__'] + +def member_function_test(app, what, name, obj, skip, options): + # test if we have a private function + if len(name) > 1 and name[0] == '_': + # test if this private function should be allowed + if name not in accepted_private_functions: + # omit privat functions that are not in the list of accepted private functions + return skip + else: + # test if the method is documented + if not hasattr(obj, '__doc__') or not obj.__doc__: + return skip + return False + +def setup(app): + app.connect('autodoc-skip-member', member_function_test) diff --git a/doc/guide.rst b/doc/guide.rst new file mode 100644 index 0000000000000000000000000000000000000000..e6b540b14be6e189b01157a92f47b3ea68632657 --- /dev/null +++ b/doc/guide.rst @@ -0,0 +1,92 @@ +.. py:currentmodule:: bob.ip.qualitymeasure + +.. testsetup:: * + + from __future__ import print_function + import math + import os, sys + import argparse + + import bob.io.image #remove this if possible + import bob.io.base + import bob.io.video + import bob.ip.color + import numpy as np + from bob.ip.qualitymeasure import galbally_iqm_features as iqm + from bob.ip.qualitymeasure import msu_iqa_features as iqa + + import bob.io.base.test_utils #remove this if possible + + import pkg_resources + video_file = bob.io.base.test_utils.datafile('real_client001_android_SD_scene01.mp4', 'bob.ip.qualitymeasure', 'data') + video4d = bob.io.video.reader(video_file) + +============= + User Guide +============= + +You can used this Bob package to extract image-quality features for face-PAD applications. +Two sets of quality-features are implemented in this package: + +1. The image-quality measures proposed by Galbally et al. (TIFS 2014), and + +2. The image-quality features proposed by Wen et al. (TIFS 2015). + +The package includes separate modules for implementing the two feature-sets. +The module ``galbally_iqm_features`` implements the features proposed by Gabally et al., and the module ``msu_iqa_features`` implements the features proposed by Wen et al. +In each module, a single function needs to be called, to retrieve all the features implemented in the module. +The examples below show how to use the functions in the two modules. + +Note that both feature-sets are extracted from still-images. However, in face-PAD experiments, we typically process videos. +Therefore, the examples below use a video as input, but show how to extract image-quality features for a single frame. + +Computing Galbally's image-quality measures +------------------------------------------- +The function ``compute_quality_features()`` (in the module galbally_iqm_features) can be used to compute 18 image-quality measures +proposed by Galbally et al. Note that Galbally et al. proposed 25 features in their paper. This package implements the following +18 features from their paper, namely: +[mse, psnr, ad, sc, nk, md, lmse, nae, snrv, ramdv, mas, mams, sme, gme, gpe, ssim, vif, hlfi]. +Therefore, the function ``galbally_iqm_features::compute_quality_features()`` returns a tuple of 18 scalars, in the order listed above. + +.. doctest:: + + + >>> from bob.ip.qualitymeasure import galbally_iqm_features as iqm + >>> video4d = bob.io.video.reader(video_file) # doctest: +SKIP + >>> rgb_frame = video4d[0] + >>> print(len(rgb_frame)) + [3, 480, 720] + >>> gf_set = iqm.compute_quality_features(rgb_frame) + >>> print(len(gf_set)) + 18 + +In the example-code above, we have used a color (RGB) image as input to the function ``compute_quality_features()``. +In fact, the features proposed by Galbally et al. are computed over gray-level images. +Therefore, the function ``galbally_iqm_features::compute_quality_features()`` takes as input either a RGB color-image, +or a gray-level image. +(The input image should be a numpy-array. RGB color-images should be in the format expected by Bob_.) +When the input image is 3-dimensional, the first dimension being '3' (as is the case in the example above), the input +is considered to represent a color RGB image, and is first converted to a gray-level image. +If the input is 2-dimensional (say, a numpy array of shape [480, 720]), then it is considered to represent a gray-level +image, and the RGB-to-gray conversion step is skipped. + +Computing Wen's image-quality measures +-------------------------------------- +The code below shows how to compute the image-quality features proposed by Wen et al. (Here, we refer to these features as +'MSU features'.) +These features are computed from a RGB color-image. The 2 feature-types (image-blur, color-diversity) all together form +a 118-D feature-vector. +The function ``compute_msu_iqa_features()`` (from the module ``msu_iqa_features``) returns a 1D numpy array of length 118. + +.. doctest:: + + >>> from bob.ip.qualitymeasure import msu_iqa_features as iqa + >>> video4d = bob.io.video.reader(video_file) # doctest: +SKIP + >>> rgb_frame = video4d[0] + >>> msuf_set = iqa.compute_msu_iqa_features(rgb_frame) + >>> print(len(msuf_set)) + 118 + + +.. _Bob: https://www.idiap.ch/software/bob/ +.. _documentation: https://menpofit.readthedocs.io/en/stable/ diff --git a/doc/img/favicon.ico b/doc/img/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..4cc3264302627d40868261add69eb755856611b6 Binary files /dev/null and b/doc/img/favicon.ico differ diff --git a/doc/img/logo.png b/doc/img/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..b60858a7068bf45c1ed8e3da12fe244ccdcfe85d Binary files /dev/null and b/doc/img/logo.png differ diff --git a/doc/index.rst b/doc/index.rst new file mode 100644 index 0000000000000000000000000000000000000000..da9ff8ff8f5dccef74181225ddc03ef236b679d0 --- /dev/null +++ b/doc/index.rst @@ -0,0 +1,34 @@ +.. vim: set fileencoding=utf-8 : +.. Sushil Bhattacharjee +.. Tue 08 Mar 2017 15:42:29 CET + +=============================================================== + Bob's Routines for Image-Quality Measures for PAD Applications +=============================================================== + +.. todolist:: + +This package provides functions for extracting image-quality features for still, color images. +Two sets of features are computed: the set of features proposed by Galbally et al.(TIFS2014), +and the set of features proposed by Wen et al. (TIFS2015). +Note that not all features proposed by the authors of the papers are available in this package. + + +Documentation +------------- + +.. toctree:: + :maxdepth: 2 + + guide + py_api + + +Indices and tables +------------------ + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` + +.. include:: links.rst diff --git a/doc/links.rst b/doc/links.rst new file mode 100644 index 0000000000000000000000000000000000000000..71d2091319d54e0e47458d51142c112b66965d27 --- /dev/null +++ b/doc/links.rst @@ -0,0 +1,7 @@ +.. vim: set fileencoding=utf-8 : +.. Andre Anjos +.. Tue 20 Mar 2012 08:57:32 CET +.. +.. Place here references to all citations in lower case + +.. _bob: https://www.idiap.ch/software/bob/ diff --git a/doc/py_api.rst b/doc/py_api.rst new file mode 100644 index 0000000000000000000000000000000000000000..33ad5ef21177b4aa2992c79b499b6c3d84d06658 --- /dev/null +++ b/doc/py_api.rst @@ -0,0 +1,10 @@ +.. vim: set fileencoding=utf-8 : + +============ + Python API +============ + +Detailed Information +-------------------- + +.. automodule:: bob.ip.qualitymeasure