diff --git a/bob/ip/facelandmarks/__init__.py b/bob/ip/facelandmarks/__init__.py index d5d61f05021867a5aac356dc8a567c2a4a8d4347..380abf60442fbec74dd4bcfa80a737c937a4cfe1 100644 --- a/bob/ip/facelandmarks/__init__.py +++ b/bob/ip/facelandmarks/__init__.py @@ -1,6 +1,30 @@ #!/usr/bin/env python # vim: set fileencoding=utf-8 : +from .utils import * +from .utils import _Result + +# gets sphinx autodoc done right - don't remove it +def __appropriate__(*args): + """Says object was actually declared here, an not on the import module. + + Parameters: *args: An iterable of objects to modify + + Resolves `Sphinx referencing issues <https://github.com/sphinx- + doc/sphinx/issues/3048>` """ + + for obj in args: + obj.__module__ = __name__ + + +__appropriate__( + _Result, + Result, + detect_landmarks_on_boundingbox, + detect_landmarks, + draw_landmarks, + save_landmarks, +) def get_config(): @@ -12,7 +36,5 @@ def get_config(): return bob.extension.get_config(__name__) - # gets sphinx autodoc done right - don't remove it __all__ = [_ for _ in dir() if not _.startswith('_')] - diff --git a/bob/ip/facelandmarks/script/detect_landmarks.py b/bob/ip/facelandmarks/script/detect_landmarks.py index 5e771961181c4a77277e6eacca5ba5ebab61c803..e10167ff842db451a1c2be3fb8900d6f3286e332 100644 --- a/bob/ip/facelandmarks/script/detect_landmarks.py +++ b/bob/ip/facelandmarks/script/detect_landmarks.py @@ -1,7 +1,5 @@ #!/usr/bin/env python # encoding: utf-8 -# Andre Anjos <andre.anjos@idiap.ch> -# Tue 16 Feb 2016 15:52:30 CET '''Face landmark detector using menpo (%(version)s) diff --git a/bob/ip/facelandmarks/test.py b/bob/ip/facelandmarks/test.py index 734625b02224702e14f048ba1966eb6d390fcb33..470fe0f96817a67695df8e518ec1414c5d4a82df 100644 --- a/bob/ip/facelandmarks/test.py +++ b/bob/ip/facelandmarks/test.py @@ -1,7 +1,5 @@ #!/usr/bin/env python # encoding: utf-8 -# Andre Anjos <andre.anjos@idiap.ch> -# Wed 17 Feb 14:32:58 CET 2016 '''Test units for bob.ip.facelandmarks''' diff --git a/bob/ip/facelandmarks/utils.py b/bob/ip/facelandmarks/utils.py index 9c7ccb98c076f768c541dbaf282643d7004c1877..49c3ca1ca8d6db593a231f7f9acc40265d11b126 100644 --- a/bob/ip/facelandmarks/utils.py +++ b/bob/ip/facelandmarks/utils.py @@ -1,7 +1,5 @@ #!/usr/bin/env python # encoding: utf-8 -# Andre Anjos <andre.dos.anjos@gmail.com> -# Wed 17 Feb 2016 10:53:06 CET '''A set of helper utitilities to deal with menpo images and point clouds''' @@ -132,11 +130,10 @@ class Result(_Result): '''A :py:class:`collections.namedtuple` with landmark information Attributes: - bounding_box (:py:class:`bob.ip.facedetect.BoundingBox`): A bounding box extracted with :py:mod:`bob.ip.facedetect`. - quality (float): A floating-point number expressing the quality of the + quality (:py:class:`float`): the quality of the extracted bounding-box, as returned by :py:mod:`bob.ip.facedetect`'s Boosted classifier @@ -166,18 +163,22 @@ def _detect_multiple_landmarks_on_gray_image(data, top=0, min_quality=0.): '''Detects landmarks on a gray-scale image, returns point-clouds from menpo This helper will detect faces and landmarks, possibly many, on the input - gray-scale image. + gray-scale image. It first detects faces in the input image, using + :py:mod:`bob.ip.facedetect`, and then uses the result of the + face-detection-step for detecting facial-landmarks. + Parameters: data (:py:class:`numpy.ndarray`): An ``uint8`` array with 2 dimensions, corresponding to a gray-scale image loaded with Bob (y, x) ordering. - top (int): An integer which indicates if we should only consider the first - N detections or all of them. A value of zero means the selector ignores - this field. + top (:py:class:`int`): An integer which indicates if we should only + consider the first N detections or all of them. A value of zero means the + selector ignores this field. A value of 1 returns only the best detection + (with the highest quality). - min_quality (float): A float that also trims the face detector output list + min_quality (:py:class:`float`): Also trims the face detector output list by considering a minimum quality for the detection. A value of zero (0.0) means "any quality will do". Good detections have a typical value which is greater than 30. Use this parameter with care. If this and ``top`` are @@ -186,7 +187,7 @@ def _detect_multiple_landmarks_on_gray_image(data, top=0, min_quality=0.): Returns: - :py:class:`list`: A list of named tuples of type :py:class:`.utils.Result`, + :py:class:`list`: A list of named tuples of type :py:class:`Result`, each containing the result of face detection and landmarks extracted from the input image. The list MAY BE EMPTY if no face is detected in the input image (data). @@ -265,11 +266,11 @@ def _detect_multiple_landmarks_on_color_image(data, top=0, min_quality=0.): data (:py:class:`numpy.ndarray`): An ``uint8`` array with 3 dimensions, corresponding to a color image loaded with Bob (planes, y, x) ordering. - top (int): An integer which indicates if we should only consider the first + top (:py:class:`int`): An integer which indicates if we should only consider the first N detections or all of them. A value of zero means the selector ignores this field. - min_quality (float): A float that also trims the face detector output list + min_quality (:py:class:`float`): also trims the face detector output list by considering a minimum quality for the detection. A value of zero (0.0) means "any quality will do". Good detections have a typical value which is greater than 30. Use this parameter with care. If this and ``top`` are @@ -278,9 +279,9 @@ def _detect_multiple_landmarks_on_color_image(data, top=0, min_quality=0.): Returns: - :py:class:`list`: A list of named tuples of type :py:class:`.utils.Result`, - each containing the result of face detection and landmarks extracted from - the input image. + :py:class:`list`: A list of named tuples of type :py:class:`Result`, each + containing the result of face detection and landmarks extracted from the + input image. ''' @@ -294,17 +295,18 @@ def detect_landmarks(data, top=0, min_quality=0.): This helper will detect faces and landmarks, possibly many, on the input image. + Parameters: data (:py:class:`numpy.ndarray`): An ``uint8`` array with either 2 or 3 dimensions, corresponding to a either a gray-scale or color image loaded with Bob. - top (int): An integer which indicates if we should only consider the first - N detections or all of them. A value of zero means the selector ignores - this field. + top (:py:class:`int`): An integer which indicates if we should only + consider the first N detections or all of them. A value of zero means the + selector ignores this field. - min_quality (float): A float that also trims the face detector output list + min_quality (:py:class:`float`): trims the face detector output list by considering a minimum quality for the detection. A value of zero (0.0) means "any quality will do". Good detections have a typical value which is greater than 30. Use this parameter with care. If this and ``top`` are @@ -313,9 +315,9 @@ def detect_landmarks(data, top=0, min_quality=0.): Returns: - :py:class:`list`: A list of named tuples of type :py:class:`.utils.Result`, - each containing the result of face detection and landmarks extracted from - the input image. + :py:class:`list`: A list of named tuples of type :py:class:`Result`, each + containing the result of face detection and landmarks extracted from the + input image. ''' @@ -336,8 +338,8 @@ def draw_landmarks(data, results): with Bob. results (:py:class:`list`): A list of named tuples of type - :py:class:`.utils.Result`, each containing the result of face detection - and landmarks extracted from the input image. + :py:class:`Result`, each containing the result of face detection and + landmarks extracted from the input image. ''' @@ -396,10 +398,10 @@ def save_landmarks(results, fname): Parameters: results (:py:class:`list`): A list of named tuples of type - :py:class:`.utils.Result`, each containing the result of face detection - and landmarks extracted from the input image. + :py:class:`Result`, each containing the result of face detection and + landmarks extracted from the input image. - fname (str): A path with the output filename + fname (:py:class:`str`): A path with the output filename ''' diff --git a/bootstrap-buildout.py b/bootstrap-buildout.py deleted file mode 100644 index a4599211f741c468cd37a29861d1c7f2c3a641d1..0000000000000000000000000000000000000000 --- a/bootstrap-buildout.py +++ /dev/null @@ -1,210 +0,0 @@ -############################################################################## -# -# Copyright (c) 2006 Zope Foundation and Contributors. -# All Rights Reserved. -# -# This software is subject to the provisions of the Zope Public License, -# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. -# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -# FOR A PARTICULAR PURPOSE. -# -############################################################################## -"""Bootstrap a buildout-based project - -Simply run this script in a directory containing a buildout.cfg. -The script accepts buildout command-line options, so you can -use the -c option to specify an alternate configuration file. -""" - -import os -import shutil -import sys -import tempfile - -from optparse import OptionParser - -__version__ = '2015-07-01' -# See zc.buildout's changelog if this version is up to date. - -tmpeggs = tempfile.mkdtemp(prefix='bootstrap-') - -usage = '''\ -[DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options] - -Bootstraps a buildout-based project. - -Simply run this script in a directory containing a buildout.cfg, using the -Python that you want bin/buildout to use. - -Note that by using --find-links to point to local resources, you can keep -this script from going over the network. -''' - -parser = OptionParser(usage=usage) -parser.add_option("--version", - action="store_true", default=False, - help=("Return bootstrap.py version.")) -parser.add_option("-t", "--accept-buildout-test-releases", - dest='accept_buildout_test_releases', - action="store_true", default=False, - help=("Normally, if you do not specify a --version, the " - "bootstrap script and buildout gets the newest " - "*final* versions of zc.buildout and its recipes and " - "extensions for you. If you use this flag, " - "bootstrap and buildout will get the newest releases " - "even if they are alphas or betas.")) -parser.add_option("-c", "--config-file", - help=("Specify the path to the buildout configuration " - "file to be used.")) -parser.add_option("-f", "--find-links", - help=("Specify a URL to search for buildout releases")) -parser.add_option("--allow-site-packages", - action="store_true", default=False, - help=("Let bootstrap.py use existing site packages")) -parser.add_option("--buildout-version", - help="Use a specific zc.buildout version") -parser.add_option("--setuptools-version", - help="Use a specific setuptools version") -parser.add_option("--setuptools-to-dir", - help=("Allow for re-use of existing directory of " - "setuptools versions")) - -options, args = parser.parse_args() -if options.version: - print("bootstrap.py version %s" % __version__) - sys.exit(0) - - -###################################################################### -# load/install setuptools - -try: - from urllib.request import urlopen -except ImportError: - from urllib2 import urlopen - -ez = {} -if os.path.exists('ez_setup.py'): - exec(open('ez_setup.py').read(), ez) -else: - exec(urlopen('https://bootstrap.pypa.io/ez_setup.py').read(), ez) - -if not options.allow_site_packages: - # ez_setup imports site, which adds site packages - # this will remove them from the path to ensure that incompatible versions - # of setuptools are not in the path - import site - # inside a virtualenv, there is no 'getsitepackages'. - # We can't remove these reliably - if hasattr(site, 'getsitepackages'): - for sitepackage_path in site.getsitepackages(): - # Strip all site-packages directories from sys.path that - # are not sys.prefix; this is because on Windows - # sys.prefix is a site-package directory. - if sitepackage_path != sys.prefix: - sys.path[:] = [x for x in sys.path - if sitepackage_path not in x] - -setup_args = dict(to_dir=tmpeggs, download_delay=0) - -if options.setuptools_version is not None: - setup_args['version'] = options.setuptools_version -if options.setuptools_to_dir is not None: - setup_args['to_dir'] = options.setuptools_to_dir - -ez['use_setuptools'](**setup_args) -import setuptools -import pkg_resources - -# This does not (always?) update the default working set. We will -# do it. -for path in sys.path: - if path not in pkg_resources.working_set.entries: - pkg_resources.working_set.add_entry(path) - -###################################################################### -# Install buildout - -ws = pkg_resources.working_set - -setuptools_path = ws.find( - pkg_resources.Requirement.parse('setuptools')).location - -# Fix sys.path here as easy_install.pth added before PYTHONPATH -cmd = [sys.executable, '-c', - 'import sys; sys.path[0:0] = [%r]; ' % setuptools_path + - 'from setuptools.command.easy_install import main; main()', - '-mZqNxd', tmpeggs] - -find_links = os.environ.get( - 'bootstrap-testing-find-links', - options.find_links or - ('http://downloads.buildout.org/' - if options.accept_buildout_test_releases else None) - ) -if find_links: - cmd.extend(['-f', find_links]) - -requirement = 'zc.buildout' -version = options.buildout_version -if version is None and not options.accept_buildout_test_releases: - # Figure out the most recent final version of zc.buildout. - import setuptools.package_index - _final_parts = '*final-', '*final' - - def _final_version(parsed_version): - try: - return not parsed_version.is_prerelease - except AttributeError: - # Older setuptools - for part in parsed_version: - if (part[:1] == '*') and (part not in _final_parts): - return False - return True - - index = setuptools.package_index.PackageIndex( - search_path=[setuptools_path]) - if find_links: - index.add_find_links((find_links,)) - req = pkg_resources.Requirement.parse(requirement) - if index.obtain(req) is not None: - best = [] - bestv = None - for dist in index[req.project_name]: - distv = dist.parsed_version - if _final_version(distv): - if bestv is None or distv > bestv: - best = [dist] - bestv = distv - elif distv == bestv: - best.append(dist) - if best: - best.sort() - version = best[-1].version -if version: - requirement = '=='.join((requirement, version)) -cmd.append(requirement) - -import subprocess -if subprocess.call(cmd) != 0: - raise Exception( - "Failed to execute command:\n%s" % repr(cmd)[1:-1]) - -###################################################################### -# Import and run buildout - -ws.add_entry(tmpeggs) -ws.require(requirement) -import zc.buildout.buildout - -if not [a for a in args if '=' not in a]: - args.append('bootstrap') - -# if -c was provided, we push it back into args for buildout' main function -if options.config_file is not None: - args[0:0] = ['-c', options.config_file] - -zc.buildout.buildout.main(args) -shutil.rmtree(tmpeggs) diff --git a/develop.cfg b/develop.cfg index 58164cdc6501ddf000a90cfce65db499abfecbe3..701bced202f4ac7137bae6c25f265cee8477a7b3 100644 --- a/develop.cfg +++ b/develop.cfg @@ -2,26 +2,46 @@ ; Sat 3 Dec 20:21:13 2016 CET [buildout] -parts = environment scripts +parts = scripts eggs = bob.ip.facelandmarks extensions = bob.buildout mr.developer auto-checkout = * +develop = src/bob.extension + src/bob.blitz + src/bob.core + src/bob.io.base + src/bob.io.image + src/bob.io.video + src/bob.math + src/bob.sp + src/bob.learn.boosting + src/bob.ip.base + src/bob.ip.color + src/bob.ip.draw + src/bob.ip.facedetect + . -develop = . - +; options for bob.buildout extension +debug = true +verbose = true newest = false -[versions] -pillow = >=2.9,<2.10 - -[environment] -;required for MacPorts (OSX) builds -;make sure to install port vlfeat before -recipe = collective.recipe.environment -CFLAGS = -I/opt/local/include -LDFLAGS = -L/opt/local/lib -lvl +[sources] +bob.extension = git https://gitlab.idiap.ch/bob/bob.extension +bob.blitz = git https://gitlab.idiap.ch/bob/bob.blitz +bob.core = git https://gitlab.idiap.ch/bob/bob.core +bob.io.base = git https://gitlab.idiap.ch/bob/bob.io.base +bob.io.image = git https://gitlab.idiap.ch/bob/bob.io.image +bob.io.video = git https://gitlab.idiap.ch/bob/bob.io.video +bob.math = git https://gitlab.idiap.ch/bob/bob.math +bob.sp = git https://gitlab.idiap.ch/bob/bob.sp +bob.learn.boosting = git https://gitlab.idiap.ch/bob/bob.learn.boosting +bob.ip.base = git https://gitlab.idiap.ch/bob/bob.ip.base +bob.ip.color = git https://gitlab.idiap.ch/bob/bob.ip.color +bob.ip.draw = git https://gitlab.idiap.ch/bob/bob.ip.draw +bob.ip.facedetect = git https://gitlab.idiap.ch/bob/bob.ip.facedetect [scripts] recipe = bob.buildout:scripts - +dependent-scripts = true diff --git a/doc/guide.rst b/doc/guide.rst index 7a69e87ef76fd094ff391d6e3dc727eef3dbd1fe..cf06261588fb7b23769091675a46c1633ae6b135 100644 --- a/doc/guide.rst +++ b/doc/guide.rst @@ -11,7 +11,6 @@ import bob.ip.color import bob.ip.facedetect import bob.ip.facelandmarks - import bob.ip.facelandmarks.utils import pkg_resources #lena_file = '/idiap/user/sbhatta/work/git/bob.ip.facelandmarks/data/lena.jpg' @@ -21,28 +20,31 @@ face_image = bob.io.base.load(lena_file) multi_image = bob.io.base.load(multi_file) + ============= User Guide ============= -This Bob package allows you to use the [Menpofit_] package to detect facial landmarks. -Given a gray-level image depicting a human face, this package can be used to extract a specific set of 68 landmarks, -as defined in Menpofit. Please refer to the original Menpofit [documentation_] for implementation details. -Here, we show some examples of how to use the ``bob.ip.facelandmarks`` package. +This Bob package allows you to use the Menpofit_ package to detect facial +landmarks. Given a gray-level image depicting a human face, this package can +be used to extract a specific set of 68 landmarks, as defined in Menpofit. +Please refer to the original Menpofit documentation_ for implementation +details. Here, we show some examples of how to use this package. Landmark Detection on a Single Face ----------------------------------- The most simple face detection task is to detect a single face in an image. -This task can be accomplished using the ``detect_landmarks()`` function in this package. -The following code-example shows how to extract facial keypoints for a single face in a gray-level input image: +This task can be accomplished using the :py:func:`detect_landmarks` function in +this package. The following code-example shows how to extract facial keypoints +for a single face in a gray-level input image: .. doctest:: >>> face_image = bob.io.base.load('lena.jpg') # doctest: +SKIP >>> gray_image = bob.ip.color.rgb_to_gray(face_image) - >>> key_points = bob.ip.facelandmarks.utils.detect_landmarks(gray_image, 1) + >>> key_points = bob.ip.facelandmarks.detect_landmarks(gray_image, 1) >>> print(key_points[0].landmarks.shape) (68, 2) @@ -52,47 +54,34 @@ The following code-example shows how to extract facial keypoints for a single fa >>> print(key_points[0].bounding_box.bottomright) (394, 376) -This package also provides a handy function, ``draw_landmarks()``, for plotting the extracted facial-landmarks on an image. +This package also provides a handy function, :py:func:`draw_landmarks`, for +plotting the extracted facial-landmarks on an image. .. doctest:: - >>> bob.ip.facelandmarks.utils.draw_landmarks(gray_image, key_points) + >>> bob.ip.facelandmarks.draw_landmarks(gray_image, key_points) -The result is shown in the image below. +The result is shown in the image below: .. plot:: plot/single_face_lmks.py :include-source: False +The return value of :py:func:`detect_landmarks` is a list. When only one face +is expected in the input, this list will contain only one element. Each +element in the list is an object of type :py:class:`Result`. -The ``detect_landmarks()`` function has the following signature: `detect_landmarks(gray_image, top=0, min_quality=0.0)`. - - * ``gray_image``: a numpy-array containing the gray-level input image, and, - * ``top``: positive integer (default=0), specifying the number of faces to be detected in this image. - * ``min_quality``: positive floating-point number (default=0), specifying the minimum acceptable quality for the result of face-detection. - -The first parameter is obligatory, and should be a valid 2D numpy-array representing a gray-level image. -The remaining two parameters are optional. -In the example above, ``top`` is specified as 1, hence, landmarks for only one face are extracted. - -The function ``detect_landmarks()`` first detects faces in the input image, using ``bob.ip.facedetect``, and then uses the result of the face-detection-step for detecting facial-landmarks. - - -If the ``min_quality`` parameter is specified, then bounding-boxes having a quality-value lower than the specified value are ignored. +The first two members, ``bounding_box`` and ``quality``, come from +:py:mod:`bob.ip.facedetect`. The detected bounding-boxes are sorted in order of +decreasing quality, and the top-N (where N is the value specified for the +parameter ``top``) bounding-boxes are used, one by one, in the +landmark-detection step. -The return value of ``detect_landmarks()`` is a list. -When only one face is expected in the input, this list will contain only one element. -Each element in the list is an object with three members, named as follows: - - * ``bounding_box``: an object with two elements (topright, and bottomleft), each of which is a tuple (row,col) giving the coordinates of the top-left and bottom-right corners of the detected face-bounding-box. - * ``quality``: a floating-point number between 0 and 100.0, giving a quality-estimate for the result of the face-detection step. - * ``landmarks``: a numpy-array of shape (68, 2). - -The first two members, ``bounding_box`` and ``quality``, come from ``bob.ip.facedetect``. -The detected bounding-boxes are sorted in order of decreasing quality, and the top-N (where N is the value specified for the parameter ``top``) bounding-boxes are used, one by one, in the landmark-detection step. - -For each detected face, each row in ``landmarks`` represents one of the 68 facial-landmarks, and gives the coordinates (row,col) of that landmark. -As described in the Menpofit documentation, The facial-landmarks are listed in a specific order in the array: +For each detected face, each row in third member of :py:class:`Result` called +``landmarks`` represents one of the 68 facial-landmarks, and gives the +coordinates (row, column) of that landmark. As described in the Menpofit_ +documentation, The facial-landmarks are listed in a specific order in the +array: .. code-block:: python @@ -107,14 +96,19 @@ As described in the Menpofit documentation, The facial-landmarks are listed in a inner_mouth_indices = [60, 67] -If the bounding-box of the desired face is already available (via a preceding call to the function ``face.ip.facedetect.detect_single_face()``), the function ``detect_landmarks_on_boundingbox(gray_image, bounding_box)`` may be used to determine the facial-landmarks within this bounding-box. -Note that the return-value of ``detect_landmarks_on_boundingbox()`` is a 2D numpy-array representing the coordinates of the 68 landmarks (and not an object as in the case of ``detect_landmarks()``). +If the bounding-box of the desired face is already available (via a preceding +call to the function :py:func:`bob.ip.facedetect.detect_single_face`), the +function :py:func:`detect_landmarks_on_boundingbox` may be used to determine +the facial-landmarks within this bounding-box. Note that the return-value of +:py:func:`detect_landmarks_on_boundingbox` is a 2D numpy-array representing the +coordinates of the 68 landmarks (and not an object as in the case of +:py:func:`detect_landmarks`). .. doctest:: - + >>> gray_image = bob.ip.color.rgb_to_gray(face_image) >>> my_bounding_box, _ = bob.ip.facedetect.detect_single_face(gray_image) - >>> my_key_points = bob.ip.facelandmarks.utils.detect_landmarks_on_boundingbox(gray_image, my_bounding_box) + >>> my_key_points = bob.ip.facelandmarks.detect_landmarks_on_boundingbox(gray_image, my_bounding_box) >>> print(my_key_points.shape) (68, 2) @@ -123,16 +117,18 @@ Note that the return-value of ``detect_landmarks_on_boundingbox()`` is a 2D nump Landmark Detection on Multiple Faces ------------------------------------ -To extract landmarks for multiple faces in the same image, use the ``top`` parameter when calling ``detect_landmarks()``. -In the following example, the input image contains several faces, out of which, landmarks are extracted for the 5 faces with the best face-detection-quality. +To extract landmarks for multiple faces in the same image, use the ``top`` +parameter when calling :py:func:`detect_landmarks`. In the following example, +the input image contains several faces, out of which, landmarks are extracted +for the 5 faces with the best face-detection-quality. .. doctest:: >>> multi_image = bob.io.base.load('multiple-faces.jpg') # doctest: +SKIP >>> gray_image = bob.ip.color.rgb_to_gray(multi_image) - >>> key_points = bob.ip.facelandmarks.utils.detect_landmarks(gray_image, top=5) + >>> key_points = bob.ip.facelandmarks.detect_landmarks(gray_image, top=5) >>> for i in range(5): - ... print(key_points[i].bounding_box.topleft) + ... print(key_points[i].bounding_box.topleft) (136, 2243) (1480, 2226) (1574, 2959) @@ -140,6 +136,5 @@ In the following example, the input image contains several faces, out of which, (107, 3016) -.. _Menpofit: http://www.menpo.org/menpofit/ - +.. _Menpofit: http://www.menpo.org/menpofit/ .. _documentation: https://menpofit.readthedocs.io/en/stable/ diff --git a/doc/nitpick-exceptions.txt b/doc/nitpick-exceptions.txt index 21e54e64debbe1d792aed74efab96f1540d78c14..d46d4e0246ffdcb963cc4551554f3fae4f7cc6b2 100644 --- a/doc/nitpick-exceptions.txt +++ b/doc/nitpick-exceptions.txt @@ -1,3 +1,4 @@ -# Solve some Python 2.7 misses on its documentation +# This is not documented as py:exc in Python 2.7 - works in Python 3.x +py:obj list py:class list py:class collections.namedtuple diff --git a/doc/py_api.rst b/doc/py_api.rst index 2abe2eda451d17efb6a6517e875317ec71c622bd..a46ce76cba8ec8471a7859ff9c7435b4ae9500b1 100644 --- a/doc/py_api.rst +++ b/doc/py_api.rst @@ -7,4 +7,4 @@ Detailed Information -------------------- -.. automodule:: bob.ip.facelandmarks.utils +.. automodule:: bob.ip.facelandmarks