0.11.0 (2021/01/09)

Very important change! The license text has been changed to a more generic BSD 3-Clause. Functionally (and hopefully legally) this changes nothing as the license a BSD 3-Clause anyway but with non-standard text -> it was based on the Scipy license. After agreement from all copyright holders (see #841) we changed the license to make it clearer that the project is licensed in a standard way.

Other major breaking change is the removal of the menpowidgets code as this has been functionally broken for probably close to 2 years. Removing this code simplifies the API and removes a common source of confusion. Examples still need to be updated across the board.

The project now has a unit test for passing mypy and passes a clean (non-strict) mypy check.

Python 3.9 builds are now supported by CI.

Github Pull Requests

  • #841 Simplify the license to an unmodified BSD 3-Clause (@patricksnape)

  • #842 Run black on all code and add unit test (@patricksnape)

  • #847 Fix exporting and importing of graphs without labels (@patricksnape)

  • #849 Add basic mypy testing (@patricksnape)

  • #850 Remove python 2 future imports (@patricksnape)

  • #851 Remove menpowidgets and associated methods (@patricksnape)

  • #852 Change from Travis to CircleCI (@patricksnape)

0.10.0 (2020/01/01)

Remove the last of the Cython code. This is in an effort to make supporting the package easier and also installing the package easier. Although we no longer support Windows in the open source builds - installing the package using pypi should now be trivial and thus essentially re-enable installation on Windows.

The breaking changes are possible differences in pixel outputs due to changing sampling methodologies.

  • Patch extraction now uses a pure Python fallback. In particular in the case where out of bounds patch extraction happens this now falls back to a sampling based strategy. The upside is that it is now possible to extract patches at subpixel locations using strategies such as cubic interpolation. The downside is that the nominal case of in bounds nearest neighbour sampling is now around 2x slower.

  • Remove Cython based image warping. Previously we maintained a fork of scikit-image’s fast interpolation code for Affine transforms. Since warping is one of the key capabilities of Menpo, we have added a fast OpenCV based fallback for Homogeneous transforms (actually more general transforms than previously). If OpenCV is not available then a Scipy fallback is used. The OpenCV fast path is actually around 3 times faster for common operations such as rescaling an image by 2x. The scipy fallback, however, remains around 4 times slower so having OpenCV installed is recommended. Note that OpenCV does appear to have minor differences in behaviour to scikit-image particularly on the boundaries so this is considered a breaking change.

  • Remove hog and lbp features. The HoG and LBP features were difficult to maintain and underutilized in the package. According to Antonakos et al Dense-Sift features outperform all other features. For this reason, we have removed the old features as a number of bugs were identified when using them that could cause Python to segfault.

Github Pull Requests

  • #818 Pure-Python implementations of patch extraction (@jabooth, @patricksnape)

  • #822 remove native image features (hog/lbp) (@jabooth)

  • #839 Remove Cython image warping (@patricksnape)

0.9.2 (2019/08/19)

Remove more Cython code, in this case the gradient computation as the per Python code gives identical results. Fix the Trimesh.boundary_tri_index() method and add a unit test checking it’s behaviour. Fix was required for correct non-rigid ICP computation.

Github Pull Requests

  • #821 remove cython gradient implementation (@jabooth)

  • #832 Fix boundary_tri_index (@patricksnape)

0.9.1 (2019/07/12)

Remove the Cython version of the normal method and just use the Python version as the two have similar performance. Also make the Cython interpolation module optional.

Github Pull Requests

  • #816 Make skimage interpolation optional (@jabooth)

  • #820 remove cython normals module (@jabooth)

0.9.0 (2019/07/10)

Remove Python 2.x from the build matrix as it is to difficult to continue support as all major packages are sunsetting Python 2.x support in 2020. At this time no regressions have been added but Python 2.x compatibility will not be guaranteed from this release onwards. This release also adds Python 3.7 support and builds.

Furthermore, the build system has moved to using conda-forge as its package repository. This is in preparation for adding Menpo to conda-forge. Many requirements were updated in turn and this the major version bump.

This also adds support for the LJSONv3 format (

Github Pull Requests

  • #785 Migrate towards LJSONv3. (@grigorisg9gr)

  • #802 minor .lms fix in test (@jabooth)

  • #803 3D LabelledPointUndirectedGraph visualization (@nontas)

  • #805 Update (@georgesterpu)

  • #807 Fall-back to querying numpy for inc dir (@jabooth)

  • #811 Pytest and upgrade to Matplotlib 2.x (@patricksnape)

  • #814 Bump deps, fix or disable problematic tests (@jabooth)

  • #815 Pure-Python mesh normal calculation fallback (@jabooth)

  • #817 remove (unused) Cython PWA (@jabooth)

  • #829 Move to conda-forge, update dependencies and drop Python 2.7 from build config (@patricksnape)

0.8.1 (2017/05/06)

Menpo 0.8.1 includes a few new minor features, and Python 3.6 support.

Github Pull Requests

  • #753 .view_widget() on LazyList (@jabooth)

  • #777 convenience constructors for 3D rotations (@jabooth)

0.8.0 (2017/05/04)

Menpo 0.8.0 includes a variety of minor bug fixes and a few major features:

A large simplification is made to how Menpo handles landmarks. In the past, Landmarks were a special type in Menpo, they weren’t shapes. That meant we frequently had to access the underlying shape information (at .lms), which was always a litle clunky and confusing, especailly to newcomers.

In this release, we instead change the dynamic so that any shape can be attached as a landmark directly. If you only need to store a list of points with no groups or labels, you can now just use a PointCloud, which is totally natural in Menpo. The traditional features of LandmarkGroup (handling groups etc) are now available in a speciailization Shape called LabelledPointUndirectedGraph.

The migration is simple - just remove .lms anywhere from your codebase (a warning will be raised when you do use .lms - this will be deprecated in the future).

A smaller set of additional features in 0.8:

  1. Most menpo objects print a sensible string for their __repr__, which is helpful in the notebook.

  2. you can now tab complete landmark keys in the notebook.

Github Pull Requests

  • #766 upgrades for menpowidgets (ipywidgets 6) (@nontas)

  • #798 move back to making macOS builds with travis (@patricksnape)

  • #799 move back to making Win builds with appveyor (@patricksnape)

  • #792 add throttling to print_progress for fast iterations (@jabooth)

  • #790 fix __setstate__ for old landmarks (@jabooth)

  • #787 add a default __str__ implementation to avoid inf recursion on __repr__ (@jabooth)

  • #782 __repr__ return __str__ for all Copyable objects (@jabooth)

  • #780 add support for ipython tab complete landmarks (@jabooth)

  • #675 LandmarkGroups are now Shapes (@patricksnape, @jabooth, @nontas)

  • #778 Minor documentation clarification in image rasterize utility (@grigorisg9gr)

  • #761 Add clip_pixels to Image and automatically clip RGB visualisations (@grigorisg9gr)

0.7.7 (2017/01/05)

Minor bug fixes

Github Pull Requests

  • #767 Minor fixes (@patricksnape)

  • #774 Fix pip install by properly including source files (@patricksnape)

  • #775 Allow Pillow 4.x (@patricksnape)

  • #776 Manifest includes should be recursive (@jabooth)

0.7.6 (2016/12/10)

Minor bug fixes and three new pieces of functionality:

  • 3D visualization improvements (@nontas)

  • Bounding cubiod method for 3D shapes (@nontas)

  • New transforms to change dimensionality of shapes (@jabooth)

Github Pull Requests

  • #745 Documentation change in image gradient for int pixels dtype. (@grigorisg9gr)

  • #750 Copy landmarks and path (@jabooth)

  • #751 WithDims transform and with_dims method (@jabooth)

  • #754 Restrict the video channels in exports(@grigorisg9gr)

  • #755 fix ndarray slicing of lazylist, cleaner __add__ implementation (@jabooth)

  • #756 remove duplicate import_pickles def (!) (@jabooth)

  • #757 don’t print_dynamic size report in as_matrix (@jabooth)

  • #759 Bounding cuboid (@nontas)

  • #760 Quaternions for 3D Rotations (@nontas)

  • #762 3D Visualization Upgrade (@nontas)

  • #764 Fix NUMPY_INC_PATH detection for multiple dirs found (@jabooth)

0.7.5 (2016/11/17)

Minor bug fixes and three new pieces of functionality:

  • Fix bug in video importing when importing long videos (closed pipe) (@patricksnape)

  • Update to include the LICENSE.txt and AUTHORS.txt

  • Add new transform_about_centre method on images. Allow easily performing operations such as rotating an image about it’s centre or shearing an image about it’s centre.

  • Allow path only exporters (rather than hard requiring a buffer). The exporting logic was also updated to support multiple kwargs to be passed through to the exporters easily.

  • New transforms to move between image and texture coordinates. (@jabooth).

Github Pull Requests

  • #724 add transforms for tcoords -> image coords (@jabooth)

  • #733 Remove user guide as it now lives at (@nontas)

  • #729 Fix PCA docs w.r.t centre parameter (@jabooth)

  • #736 Fix bug importing boolean images with pillow (@grigorisg9gr)

  • #739 Fix PointGraph printing to mention dimensionality (@nontas)

  • #737 Allow path only exporters. Fix landmarking exporting on Python 3. (@patricksnape)

  • #735 Fix init_from_channels_at_back to support 2D arrays. (@grigorisg9gr, @patricksnape)

  • #738 Add transform_about_centre to images (@nontas, @patricksnape)

  • #743 Set nan values to None in video importing (@JeanKossaifi)

  • #744 Fix Regression: Allow None for landmark_resolver (@grigorisg9gr, @patricksnape)

0.7.4 (2016/08/18)

Minor fixes and additions including improved compatibility with loading older menpo PCAModel pickles and importing Python 2 pickles in Python 3.

Github Pull Requests

  • #723 Add optional ‘encoding’ argument to import_pickle. (@patricksnape)

  • #728 Allow for unpickling of the older PCAModel. (@patricksnape)

  • #726 Improve pip install. (@patricksnape)

  • #731 Pin setuptools to 23.x. (@jabooth)

0.7.3 (2016/08/05)

Minor fixes and additions including allowing more flexibility in FFMPEG exporting options, supporting more types with normal calculations, and tidying up the conda build recipe.

Github Pull Requests

  • #716 allow for forced inexact frame count in FFMpegVideoReader. (@san-bil)

  • #714 Utilise the kwargs in exporting video with ffmpeg. (@grigorisg9gr)

  • #720 Simplify the conda build. (@patricksnape)

  • #719 Support more types for normals. (@patricksnape)

0.7.2 (2016/06/22)

Minor fixes including allowing exporting grayscale videos and fixing a minor bug in PointGraph masking. The Menpo logo has also been updated.

Github Pull Requests

  • #709 Minor change in documentation of pickle, contrain_landmarks in image. (@grigorisg9gr)

  • #713 Remove zero edge adjacency check. (@patricksnape)

  • #711 Enable greyscale video to be exported. (@grigorisg9gr,@patricksnape)

0.7.1 (2016/06/10)

We now ship our own FFMPEG video importer based on piping, thus removing the dependency on imageio. A couple of further minor improvements were also introduced:

  • Added register_* methods to the importing packages to make it simpler to add custom importers. For example, use'.extension', your_method) to register a new importer.

  • Fix rasterization bug for maplotlib on Python 3.x

  • normalise keyword arguments are now deprecated in favour of normalize to make spelling consistent across project.

  • LazyList is now copyable -> LazyList.copy

  • LazyList map method now accepts a list of callables as well as a single callable.

  • Add LazyList.init_from_iterable for easily creating lazy lists from existing iterables.

  • Fix small visualisation bug for viewing of LandmarkGroup that contain PointClouds

  • New pixel_with_channels_at_back method for images

  • Deprecate init_from_rolled_channels in favour of new method init_from_channels_at_back

  • Deprecate as_imageio

Finally, as of this release we no longer use Appveyor, in favour of our own Windows Jenkins build boxes.

Github Pull Requests

  • #694 Functional IO Package. (@patricksnape)

  • #703 Fix the bug with rasterize landmarks with matplotlib backend. (@grigorisg9gr)

  • #700 Standardise the normalize spelling in importers. (@grigorisg9gr)

  • #702 Now reading videos using subprocess and ffmpeg. Drop ImageIO. (@JeanKossaifi,@patricksnape)

  • #706 Autoscale PointCloud if no limits set. (@patricksnape)

  • #707 LazyList init methods and are now Copyable. (@patricksnape)

  • #708 Remove appveyor in favour of Jenkins. (@patricksnape)

0.7.0 (2016/05/20)

New release that contains some minor breaking changes. In general, the biggest changes are:

  • Use ImageIO rather than Pillow for basic importing of some image types. The most important aspect of this change is that we now support importing videos! Our GIF support also became much more robust. Note that importing videos is still considered to be relatively experimental due to the underlying implementation in imageio not being 100% accurate. Therefore, we warn our users that importing videos for important experiments is not advised.

  • Change multi-asset importing to use a new type - the LazyList. Lazy lists are a generic concept for a container that holds onto a list of callables which are invoked on indexing. This means that image importing, for example, returns immediately but can be randomly indexed. This is in contrast to generators, which have to be sequentially accessed. This is particularly important for video support, as the frames can be accessed randomly or sliced from the end (rather than having to pay the penalty of importing the entirety of a long video just to access the last frame, for example). A simple example of using the LazyList to import images is as follows:

    import as mio
    images = mio.import_images('/path/to/many/images')  # Returns immediately
    image0 = images[0]  # Loading performed at access
    # Example of much simpler preprocessing
    preprocess_func = lambda x: x.as_greyscale()
    greyscale_images =  # Returns immediately
    grey_image0 = greyscale_images[0]  # Loading and as_greyscale() performed at access
    # Visualizing randomly is now much simpler too!
    % matplotlib inline
    from menpowidgets import visualize_images
    visualize_images(greyscale_images)  # Can now randomly access list
  • Move one step closer to ensuring that all image operatons are copies rather than inplace. This means breaking some methods as there was no ‘non’ inplace method (the break was to change them to return a copy). Likely the most common anti-pattern was code such as:

    import as mio
    image = mio.import_builtin_asset.takeo_ppm().as_masked()

    Which now requires assigning the call to constrain_landmarks_to_bounds to a variable, as a copy is returned:

    import as mio
    image = mio.import_builtin_asset.takeo_ppm().as_masked()
    image = image.constrain_landmarks_to_bounds()

Note that this release also officially supports Python 3.5!

Breaking Changes

  • ImageIO is used for importing. Therefore, the pixel values of some images have changed due to the difference in underlying importing code.

  • Multi-asset importers are now of type LazyList.

  • HOG previously returned negative values due to rounding errors on binning. This has been rectified, so the output values of HOG are now slightly different.

  • set_boundary_pixels is no longer in place.

  • normalize_inplace has been deprecated and removed. normalize is now a feature that abstracts out the normalisation logic.

  • gaussian_pyramid and pyramid always return copies (before the first image was the original image, not copied).

  • constrain_to_landmarks/constrain_to_pointcloud/constrain_mask_to_landmarks are no longer in place.

  • set_patches is no longer in place.

  • has_landmarks_outside_bounds is now a method.

New Features

  • from_tri_mask method added to TriMesh

  • LazyList type that holds a list of callables that are invoked on indexing.

  • New rasterize methods. Given an image and a landmark group, return a new image with the landmarks rasterized onto the image. Useful for saving results to disk.

  • Python 3.5 support!

  • Better support for non float64 image types. For example, as_greyscale can be called on a uint8 image.

  • New method rasterize_landmarks that allows easy image rasterization. By default, MaskedImages are masked with a black background. Use as_unmasked to change the colour/not returned masked image.

  • Add bounds method to images. This is defined as ((0, 0), (height - 1, width - 1)) - the set of indices that are indexable into the image for sampling.

  • Add constrain_to_bounds to PointCloud. Snaps the pointcloud exactly to the bounds given.

  • init_from_pointcloud method add to Image. Allows the creation of an image that completely bounds a given pointcloud. This is useful for both viewing images of pointclouds and for creating ‘reference frames’ for algorithms like Active Appearance Models.

  • init_from_depth_image method on PointCloud and subclasses. Allows the creation of a mesh from an image that contains pixel values that represent depth/height values. Very useful for visualising RGB-D data.

  • pickle_paths method.

  • Overwriting images now throws OverwriteError rather than just ValueError (OverwriteError is a subclass of ValueError) so this is not a breaking change.


  • The previously deprecated inplace image methods were not removed in this release.

  • set_h_matrix is deprecated for Homogeneous transforms.

  • set_masked_pixels is deprecated in favor of from_vector.

  • Deprecate constrain_landmarks_to_bounds on images.

Github Pull Requests

  • #698 Video importing warnings. (@patricksnape)

  • #697 Relex version constraints on dependencies. (@jabooth)

  • #695 condaci fixes. (@patricksnape)

  • #692 new OverwriteError raised specifically for overwrite errors in io.export. (@jabooth)

  • #691 Add mio.pickle_paths(glob). (@jabooth)

  • #690 Fix init_2d_grid for TriMesh subclasses + add init_from_depth_image. (@patricksnape)

  • #687 WIP: BREAKING: Various release fixes. (@patricksnape)

  • #685 GMRF mahalanobis computation with sparse precision. (@nontas)

  • #684 Video importer docs and negative max_images. (@grigorisg9gr)

  • #683 Bugfix: Widget imports. (@nontas)

  • #682 Update the view_patches to show only the selected landmarks. (@grigorisg9gr)

  • #680 Expose file extension to exporters (Fix PIL exporter bug). (@patricksnape)

  • #678 Deprecate set_h_matrix and fix #677. (@patricksnape)

  • #676 Implement LazyList __add__. (@patricksnape)

  • #673 Fix the widgets in PCA. (@grigorisg9gr)

  • #672 Use Conda environment.yml on RTD. (@patricksnape)

  • #670 Rasterize 2D Landmarks Method. (@patricksnape)

  • #669 BREAKING: Add LazyList - default importing is now Lazy. (@patricksnape)

  • #668 Speedup as_greyscale. (@patricksnape)

  • #666 Add the protocol option in exporting pickle. (@grigorisg9gr)

  • #665 Fix bug with patches of different type than float64. (@patricksnape)

  • #664 Python 3.5 builds. (@patricksnape)

  • #661 Return labels - which maps to a KeysView as a list. (@patricksnape)

  • #648 Turn coverage checking back on. (@patricksnape)

  • #644 Remove label kwarg. (@patricksnape)

  • #639 add from_tri_mask method to TriMesh instances. (@jabooth)

  • #633 BREAKING: Imageio. (@patricksnape)

  • #606 Fix negative values in HOG calculation. (@patricksnape)

0.6.2 (2015/12/13)

Add axes ticks option to view_patches.

Github Pull Requests

  • #659 Add axes ticks options to view_patches (@nontas)

0.6.1 (2015/12/09)

Fix a nasty bug pertaining to a Diamond inheritance problem in PCA. Add the Gaussion Markov Random Field (GRMF) model. Also a couple of other bugfixes for visualization.

Github Pull Requests

  • #658 PCA Diamond problem fix (@patricksnape)

  • #655 Bugfix and improvements in visualize package (@nontas)

  • #656 print_dynamic bugfix (@nontas)

  • #635 Gaussian Markov Random Field (@nontas, @patricksnape)

0.6.0 (2015/11/26)

This release is another set of breaking changes for Menpo. All in_place methods have been deprecated to make the API clearer (always copy). The largest change is the removal of all widgets into a subpackage called menpowidgets. To continue using widgets within the Jupyter notebook, you should install menpowidgets.

Breaking Changes

  • Procrustes analysis now checks for mirroring and disables it by default. This is a change in behaviour.

  • The sample_offsets argument of menpo.image.Image.extract_patches() now expects a numpy array rather than a PointCloud.

  • All widgets are removed and now exist as part of the menpowidgets project. The widgets are now only compatible with Jupyter 4.0 and above.

  • Landmark labellers have been totally refactored and renamed. They have not been deprecated due to the changes. However, the new changes mean that the naming scheme of labels is now much more intuitive. Practically, the usage of labelling has only changed in that now it is possible to label not only LandmarkGroup but also PointCloud and numpy arrays directly.

  • Landmarks are now warped by default, where previously they were not.

  • All vlfeat features have now become optional and will not appear if cyvlfeat is not installed.

  • All label keyword arguments have been removed. They were not found to be useful. For the same effect, you can always create a new landmark group that only contains that label and use that as the group key.

New Features

Github Pull Requests

  • #652 Deprecate a number of inplace methods (@jabooth)

  • #653 New features (vector dsift) (@patricksnape)

  • #651 remove deprecations from 0.5.0 (@jabooth)

  • #650 PointCloud init_2d_grid (@patricksnape)

  • #646 Add ibug_49 -> ibug_49 labelling (@patricksnape)

  • #645 Add new PCAVectorModel class, refactor model package (@patricksnape, @nontas)

  • #644 Remove label kwarg (@patricksnape)

  • #643 Build fixes (@patricksnape)

  • #638 bugfix 2D triangle areas sign was ambiguous (@jabooth)

  • #634 Fixing @patricksnape and @nontas foolish errors (@yuxiang-zhou)

  • #542 Add mirroring check to procrustes (@nontas, @patricksnape)

  • #632 Widgets Migration (@patricksnape, @nontas)

  • #631 Optional transform return on Image methods (@nontas)

  • #628 Patches Visualization (@nontas)

  • #629 Image counter-clockwise rotation (@nontas)

  • #630 Mirror image (@nontas)

  • #625 Labellers Refactoring (@patricksnape)

  • #623 Fix widgets for new Jupyter/IPython 4 release (@patricksnape)

  • #620 Define patches offsets as ndarray (@nontas)

0.5.3 (2015/08/12)

Tiny point release just fixing a typo in the unique_edge_indices method.

0.5.2 (2015/08/04)

Minor bug fixes and impovements including:

  • Menpo is now better at preserving dtypes other than np.float through common operations

  • Image has a new convenience constructor init_from_rolled_channels() to handle building images that have the channels at the back of the array.

  • There are also new crop_to_pointcloud() and crop_to_pointcloud_proportion() methods to round out the Image API, and a deprecation of rescale_to_reference_shape() in favour of rescale_to_pointcloud() to make things more consistent.

  • The gradient() method is deprecated (use menpo.feature.gradient instead)

  • Propagation of the .path property when using as_masked() was fixed

  • Fix for exporting 3D LJSON landmark files

  • A new shuffle kwarg (default False) is present on all multi importers.

Github Pull Requests

  • #617 add shuffle kwarg to multi import generators (@jabooth)

  • #619 Ensure that LJSON landmarks are read in as floats (@jabooth)

  • #618 Small image fix (@patricksnape)

  • #613 Balance out rescale/crop methods (@patricksnape)

  • #615 Allow exporting of 3D landmarks. (@mmcauliffe)

  • #612 Type maintain (@patricksnape)

  • #602 Extract patches types (@patricksnape)

  • #608 Slider for selecting landmark group on widgets (@nontas)

  • #605 tmp move to master condaci (@jabooth)

0.5.1 (2015/07/16)

A small point release that improves the Cython code (particularly extracting patches) compatibility with different data types. In particular, more floating point data types are now supported. print_progress was added and widgets were fixed after the Jupyter 4.0 release. Also, upgrade cyvlfeat requirement to 0.4.0.

Github Pull Requests

  • #604 print_progress enhancements (@jabooth)

  • #603 Fixes for new cyvlfeat (@patricksnape)

  • #599 Add erode and dilate methods to MaskedImage (@jalabort)

  • #601 Add sudo: false to turn on container builds (@patricksnape)

  • #600 Human3.6M labels (@nontas)

0.5.0 (2015/06/25)

This release of Menpo makes a number of very important BREAKING changes to the format of Menpo’s core data types. Most importantly is #524 which swaps the position of the channels on an image from the last axis to the first. This is to maintain row-major ordering and make iterating over the pixels of a channel efficient. This made a huge improvement in speed in other packages such as MenpoFit. It also makes common operations such as iterating over the pixels in an image much simpler:

for channels in image.pixels:
    print(channels.shape)  # This will be a (height x width) ndarray

Other important changes include:

  • Updating all widgets to work with IPython 3

  • Incremental PCA was added.

  • non-inplace cropping methods

  • Dense SIFT features provided by vlfeat

  • The implementation of graphs was changed to use sparse matrices by default. This may cause breaking changes.

  • Many other improvements detailed in the pull requests below!

If you have serialized data using Menpo, you will likely find you have trouble reimporting it. If this is the case, please visit the user group for advice.

Github Pull Requests

  • #598 Visualize sum of channels in widgets (@nontas, @patricksnape)

  • #597 test new dev tag behavior on condaci (@jabooth)

  • #591 Scale around centre (@patricksnape)

  • #596 Update to versioneer v0.15 (@jabooth, @patricksnape)

  • #495 SIFT features (@nontas, @patricksnape, @jabooth, @jalabort)

  • #595 Update mean_pointcloud (@patricksnape, @jalabort)

  • #541 Add triangulation labels for ibug_face_(66/51/49) (@jalabort)

  • #590 Fix centre and diagonal being properties on Images (@patricksnape)

  • #592 Refactor out bounding_box method (@patricksnape)

  • #566 TriMesh utilities (@jabooth)

  • #593 Minor bugfix on AnimationOptionsWidget (@nontas)

  • #587 promote non-inplace crop methods, crop performance improvements (@jabooth, @patricksnape)

  • #586 fix as_matrix where the iterator finished early (@jabooth)

  • #574 Widgets for IPython3 (@nontas, @patricksnape, @jabooth)

  • #588 test condaci 0.2.1, less noisy slack notifications (@jabooth)

  • #568 rescale_pixels() for rescaling the range of pixels (@jabooth)

  • #585 Hotfix: suffix change led to double path resolution. (@patricksnape)

  • #581 Fix the landmark importer in case the landmark file has a ‘.’ in its filename. (@grigorisg9gr)

  • #584 new print_progress visualization function (@jabooth)

  • #580 export_pickle now ensures pathlib.Path save as PurePath (@jabooth)

  • #582 New readers for Middlebury FLO and FRGC ABS files (@patricksnape)

  • #579 Fix the image importer in case of upper case letters in the suffix (@grigorisg9gr)

  • #575 Allowing expanding user paths in exporting pickle (@patricksnape)

  • #577 Change to using (@patricksnape)

  • #570 Zoom (@jabooth, @patricksnape)

  • #569 Add new point_in_pointcloud kwarg to constrain (@patricksnape)

  • #563 TPS Updates (@patricksnape)

  • #567 Optional cmaps (@jalabort)

  • #559 Graphs with isolated vertices (@nontas)

  • #564 Bugfix: PCAModel print (@nontas)

  • #565 fixed minor typo in introduction.rst (@evanjbowling)

  • #562 IPython3 widgets (@patricksnape, @jalabort)

  • #558 Channel roll (@patricksnape)

  • #524 BREAKING CHANGE: Channels flip (@patricksnape, @jabooth, @jalabort)

  • #512 WIP: remove_all_landmarks convienience method, quick lm filter (@jabooth)

  • #554 Bugfix:visualize_images (@nontas)

  • #553 Transform docs fixes (@nontas)

  • #533 LandmarkGroup.init_with_all_label, init_* convenience constructors (@jabooth, @patricksnape)

  • #552 Many fixes for Python 3 support (@patricksnape)

  • #532 Incremental PCA (@patricksnape, @jabooth, @jalabort)

  • #528 New as_matrix and from_matrix methods (@patricksnape)

0.4.4 (2015/03/05)

A hotfix release for properly handling nan values in the landmark formats. Also, a few other bug fixes crept in:

  • Fix 3D Ljson importing

  • Fix trim_components on PCA

  • Fix setting None key on the landmark manager

  • Making mean_pointcloud faster

Also makes an important change to the build configuration that syncs this version of Menpo to IPython 2.x.

Github Pull Requests

  • #560 Assorted fixes (@patricksnape)

  • #557 Ljson nan fix (@patricksnape)

0.4.3 (2015/02/19)

Adds the concept of nan values to the landmarker format for labelling missing landmarks.

Github Pull Requests

  • #556 [0.4.x] Ljson nan/null fixes (@patricksnape)

0.4.2 (2015/02/19)

A hotfix release for landmark groups that have no connectivity.

Github Pull Requests

  • #555 don’t try and build a Graph with no connectivity (@jabooth)

0.4.1 (2015/02/07)

A hotfix release to enable compatibility with

Github Pull Requests

  • #551 HOTFIX: remove incorrect tojson() methods (@jabooth)

0.4.0 (2015/02/04)

The 0.4.0 release (pending any currently unknown bugs), represents a very significant overhaul of Menpo from v0.3.0. In particular, Menpo has been broken into four distinct packages: Menpo, MenpoFit, Menpo3D and MenpoDetect.

Visualization has had major improvements for 2D viewing, in particular through the use of IPython widgets and explicit options on the viewing methods for common tasks (like changing the landmark marker color). This final release is a much smaller set of changes over the alpha releases, so please check the full changelog for the alphas to see all changes from v0.3.0 to v0.4.0.

Summary of changes since v0.4.0a2:

  • Lots of documentation rendering fixes and style fixes including this changelog.

  • Move the LJSON format to V2. V1 is now being deprecated over the next version.

  • More visualization customization fixes including multiple marker colors for landmark groups.

Github Pull Requests

  • #546 IO doc fixes (@jabooth)

  • #545 Different marker colour per label (@nontas)

  • #543 Bug fix for importing an image, case of a dot in image name. (@grigorisg9gr)

  • #544 Move docs to Sphinx 1.3b2 (@patricksnape)

  • #536 Docs fixes (@patricksnape)

  • #530 Visualization and Widgets upgrade (@patricksnape, @nontas)

  • #540 LJSON v2 (@jabooth)

  • #537 fix BU3DFE connectivity, pretty JSON files (@jabooth)

  • #529 BU3D-FE labeller added (@jabooth)

  • #527 fixes paths for pickle importing (@jabooth)

  • #525 Fix .rst doc files, auto-generation script (@jabooth)

v0.4.0a2 (2014/12/03)

Alpha 2 moves towards extending the graphing API so that visualization is more dependable.


  • Add graph classes, PointUndirectedGraph, PointDirectedGraph, PointTree. This makes visualization of landmarks much nicer looking.

  • Better support of pickling menpo objects

  • Add a bounding box method to PointCloud for calculating the correctly oriented bounding box of point clouds.

  • Allow PCA to operate in place for large data matrices.

Github Pull Requests

  • #522 Add bounding box method to pointclouds (@patricksnape)

  • #523 HOTFIX: fix export_pickle bug, add path support (@jabooth)

  • #521 add pickle support, move to pathlib (@jabooth)

  • #520 Documentation fixes (@patricksnape, @jabooth)

  • #518 PCA memory improvements, inplace dot product (@jabooth)

  • #519 replace wrapt with functools.wraps - we can pickle (@jabooth)

  • #517 (@jabooth)

  • #514 Remove the use of triplot (@patricksnape)

  • #516 Fix how images are converted to PIL (@patricksnape)

  • #515 Show the path in the image widgets (@patricksnape)

  • #511 2D Rotation convenience constructor, Image.rotate_ccw_about_centre (@jabooth)

  • #510 all menpo io glob operations are now always sorted (@jabooth)

  • #508 visualize image on MaskedImage reports Mask proportion (@jabooth)

  • #509 path is now preserved on image warping (@jabooth)

  • #507 fix rounding issue in n_components (@jabooth)

  • #506 is_tree update in Graph (@nontas)

  • #505 (@nontas)

  • #504 explicitly have kwarg in IO for landmark extensions (@jabooth)

  • #503 Update the README (@patricksnape)

v0.4.0a1 (2014/10/31)

This first alpha release makes a number of large, breaking changes to Menpo from v0.3.0. The biggest change is that Menpo3D and MenpoFit were created and thus all AAM and 3D visualization/rasterization code has been moved out of the main Menpo repository. This is working towards Menpo being pip installable.


  • Fixes memory leak whereby weak references were being kept between landmarks and their host objects. The Landmark manager now no longer keeps references to its host object. This also helps with serialization.

  • Use pathlib instead of strings for paths in the io module.

  • Importing of builtin assets from a simple function

  • Improve support for image importing (including ability to import without normalising)

  • Add fast methods for image warping, warp_to_mask and warp_to_shape instead of warp_to

  • Allow masking of triangle meshes

  • Add IPython visualization widgets for our core types

  • All expensive properties (properties that would be worth caching in a variable and are not merely a lookup) are changed to methods.

Github Pull Requests

  • #502 Fixes pseudoinverse for Alignment Transforms (@jalabort, @patricksnape)

  • #501 Remove menpofit widgets (@nontas)

  • #500 Shapes widget (@nontas)

  • #499 spin out AAM, CLM, SDM, ATM and related code to menpofit (@jabooth)

  • #498 Minimum spanning tree bug fix (@nontas)

  • #492 Some fixes for PIL image importing (@patricksnape)

  • #494 Widgets bug fix and Active Template Model widget (@nontas)

  • #491 Widgets fixes (@nontas)

  • #489 remove _view, fix up color_list -> colour_list (@jabooth)

  • #486 Image visualisation improvements (@patricksnape)

  • #488 Move expensive image properties to methods (@jabooth)

  • #487 Change expensive PCA properties to methods (@jabooth)

  • #485 MeanInstanceLinearModel.mean is now a method (@jabooth)

  • #452 Advanced widgets (@patricksnape, @nontas)

  • #481 Remove 3D (@patricksnape)

  • #480 Graphs functionality (@nontas)

  • #479 Extract patches on image (@patricksnape)

  • #469 Active Template Models (@nontas)

  • #478 Fix residuals for AAMs (@patricksnape, @jabooth)

  • #474 remove HDF5able making room for h5it (@jabooth)

  • #475 Normalize norm and std of Image object (@nontas)

  • #472 Daisy features (@nontas)

  • #473 Fix from_mask for Trimesh subclasses (@patricksnape)

  • #470 expensive properties should really be methods (@jabooth)

  • #467 get a progress bar on top level feature computation (@jabooth)

  • #466 Spin out rasterization and related methods to menpo3d (@jabooth)

  • #465 ‘me_norm’ error type in tests (@nontas)

  • #463 goodbye ioinfo, hello path (@jabooth)

  • #464 make mayavi an optional dependency (@jabooth)

  • #447 Displacements in fitting result (@nontas)

  • #451 AppVeyor Windows continuous builds from condaci (@jabooth)

  • #445 Serialize fit results (@patricksnape)

  • #444 remove pyramid_on_features from Menpo (@jabooth)

  • #443 create_pyramid now applies features even if pyramid_on_features=False, SDM uses it too (@jabooth)

  • #369 warp_to_mask, warp_to_shape, fast resizing of images (@nontas, @patricksnape, @jabooth)

  • #442 add rescale_to_diagonal, diagonal property to Image (@jabooth)

  • #441 adds constrain_to_landmarks on BooleanImage (@jabooth)

  • #440 pathlib.Path can no be used in (@jabooth)

  • #439 Labelling fixes (@jabooth, @patricksnape)

  • #438 extract_channels (@jabooth)

  • #437 GLRasterizer becomes HDF5able (@jabooth)

  • #435 import_builtin_asset.ASSET_NAME (@jabooth)

  • #434 check_regression_features unified with check_features, classmethods removed from SDM (@jabooth)

  • #433 tidy classifiers (@jabooth)

  • #432 aam.fitter, clm.fitter, sdm.trainer packages (@jabooth)

  • #431 More fitmultilevel tidying (@jabooth)

  • #430 Remove classmethods from DeformableModelBuilder (@jabooth)

  • #412 First visualization widgets (@jalabort, @nontas)

  • #429 Masked image fixes (@patricksnape)

  • #426 rename ‘feature_type’ to ‘features throughout Menpo (@jabooth)

  • #427 Adds HDF5able serialization support to Menpo (@jabooth)

  • #425 Faster cached piecewise affine, Cython varient demoted (@jabooth)

  • #424 (@nontas)

  • #378 Fitting result fixes (@jabooth, @nontas, @jalabort)

  • #423 name now displays on constrained features (@jabooth)

  • #421 Travis CI now makes builds, Linux/OS X Python 2.7/3.4 (@jabooth, @patricksnape)

  • #400 Features as functions (@nontas, @patricksnape, @jabooth)

  • #420 move IOInfo to use pathlib (@jabooth)

  • #405 import menpo is now twice as fast (@jabooth)

  • #416 Badge (@waffle-iron)

  • #415 export_mesh with .OBJ exporter (@jabooth, @patricksnape)

  • #410 Fix the render_labels logic (@patricksnape)

  • #407 Exporters (@patricksnape)

  • #406 Fix greyscale PIL images (@patricksnape)

  • #404 LandmarkGroup tojson method and PointGraph (@patricksnape)

  • #403 Fixes a couple of viewing problems in fitting results (@patricksnape)

  • #402 Landmarks fixes (@jabooth, @patricksnape)

  • #401 Dogfood landmark_resolver in (@jabooth)

  • #399 bunch of Python 3 compatibility fixes (@jabooth)

  • #398 throughout Menpo. (@jabooth)

  • #397 Performance improvements for Similarity family (@jabooth)

  • #396 More efficient initialisations of Menpo types (@jabooth)

  • #395 remove cyclic target reference from landmarks (@jabooth)

  • #393 Groundwork for dense correspondence pipeline (@jabooth)

  • #394 weakref to break cyclic references (@jabooth)

  • #389 assorted fixes (@jabooth)

  • #390 (@jabooth)

  • #387 Adds landmark label for tongues (@nontas)

  • #386 Adds labels for the ibug eye annotation scheme (@jalabort)

  • #382 BUG fixed: block element not reset if norm=0 (@dubzzz)

  • #381 Recursive globbing (@jabooth)

  • #384 Adds support for odd patch shapes in function extract_local_patches_fast (@jalabort)

  • #379 imported textures have ioinfo, docs improvements (@jabooth)

v0.3.0 (2014/05/27)

First public release of Menpo, this release coincided with submission to the ACM Multimedia Open Source Software Competition 2014. This provides the basic scaffolding for Menpo, but it is not advised to use this version over the improvements in 0.4.0.

Github Pull Requests

  • #377 Simple fixes (@patricksnape)

  • #375 improvements to importing multiple assets (@jabooth)

  • #374 Menpo’s User guide (@jabooth)