Library / SDK
luispedro/mahotas avatar
luispedro/mahotas

Mahotas: numpy-native computer vision algorithms in C++

Computer Vision in Python

890 stars150 forksPythonNOASSERTION

At a glance

What is it?
Mahotas is a Python computer vision library whose algorithms are implemented in C++ and operate directly on numpy arrays. It is a good fit when you want classic image processing primitives without pulling in a full framework, and a poor fit when you need GPU inference or deep learning models.
Who is it for?
Adopt mahotas if your pipeline is already numpy-centric and you need classic primitives such as watershed, Haralick, Zernike, LBP or TAS features without adding a framework dependency. Do not adopt it if you need trained deep models, GPU execution, or a single library that also handles video and camera I/O, because mahotas deliberately leaves those to other packages.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 100 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 20, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

What mahotas solves, and for whom

Mahotas targets the middle of a computer vision pipeline: the part between loading an image and feeding numbers into a classifier. The README describes it as "a library of fast computer vision algorithms (all implemented in C++ for speed) operating over numpy arrays." That sentence is the whole design brief. There is no image container type, no session object, no graph. An image is a numpy array, and every function takes arrays and returns arrays or plain Python values.

The intended audience is scientific and research code. The pyproject classifiers list "Science/Research" and "Image Recognition" as the intended audiences, and the project asks to be cited in publications that use it. If you are computing Haralick texture features for a microscopy study, or running a seeded watershed on a segmented mask, mahotas is aimed at you. If you are building a service that classifies photographs into categories, it is not: the library ships no trained models at all.

The notable algorithm list is the clearest statement of scope: watershed, convex points calculations, hit and miss and thinning, Zernike and Haralick, LBP and TAS features, SURF, thresholding, convolution, Sobel edge detection, spline interpolation and SLIC superpixels. The README states the library has over 100 functions. Those are classical, deterministic operations, not learned ones.

How the C++ layer and numpy arrays fit together

The mechanism is a thin C++ core exposed to Python, with numpy doing the array plumbing. The README says the algorithms are implemented in C++ for speed, and the examples show that numpy operations are used for everything around them, including the thresholding step itself.

The build system confirms this split. pyproject.toml uses meson-python as the build backend, with meson, ninja and numpy declared as build requirements, and the project depends on numpy at runtime. The repository's top level contains mahotas/ alongside meson.build and meson_options.txt, so the compiled extension modules live inside the Python package directory and are built by Meson.

The consequence for data flow is that nothing is copied into a private buffer format. When the README's watershed example computes a threshold with mh.thresholding.otsu, it then compares the array with numpy's own operator to produce a boolean mask, passes that mask to mh.label, and passes the resulting seed labels to mh.cwatershed. Every intermediate value is a numpy array you can inspect, slice or save. That is the main architectural difference from frameworks that own the image type.

It also means the boundary between mahotas and numpy is where most bugs will appear. If the dtype or shape is wrong, you get a numpy or C++ level error rather than a helpful framework message.

Installing mahotas and running a first watershed

The README gives two installation routes. With conda, you add the conda-forge channel and install the package. Note that the README shows these as two separate commands and does not combine them.

bash
conda config --add channels conda-forge
conda install mahotas

With pip, the README says you need Python, NumPy and a C++ compiler, then:

bash
pip install mahotas

After either route, the README gives this verification command. It imports the package under the conventional mh alias and runs the bundled test suite; you should see the tests run and report their result.

bash
python -c "import mahotas as mh; mh.test()"

For a first real use, the README's watershed example is the shortest complete pipeline. It loads a demo image shipped with the package, computes an Otsu threshold, labels the above-threshold regions as seeds, and expands them with a seeded watershed. The call to mh.cwatershed passes the inverted image, which is how this API expects the landscape.

python
import mahotas as mh

im = mh.demos.load('nuclear')
T_otsu = mh.thresholding.otsu(im)
seeds, nr_regions = mh.label(im > T_otsu)
labeled = mh.cwatershed(im.max() - im, seeds)

If you are developing against a checkout rather than a release, the README documents an editable install with test extras, and a Makefile with debug and fast targets. The Makefile's debug target builds an editable install with assertions enabled and _GLIBCXX_DEBUG, while fast builds a plain release install. The README warns not to use the debug build in production, because _GLIBCXX_DEBUG adds runtime checks and can be much slower than a release build.

Where mahotas is the wrong tool

The most obvious boundary is learned models. There is no neural network in the notable algorithms list, no inference runtime and no model zoo. If your task is detection or segmentation of arbitrary objects in photographs, mahotas gives you the preprocessing primitives and nothing else.

The second boundary is the build. A pip install needs a C++ compiler on the machine, which is a real cost in slim containers and on platforms without pre-built wheels. The README acknowledges this by pointing to the install page for "pre-built for several platforms", which is an admission that the source build is not always the path you want. The pyproject cibuildwheel configuration also skips some targets, including cp31*-win32, with the comment that there are no scipy wheels for that version, so the tested wheel matrix is not universal.

The third boundary is the debug build. The README is explicit that make debug is for chasing bugs and that the _GLIBCXX_DEBUG configuration "can still be much slower than a plain release build". Teams that copy the debug target into a CI performance job will measure the wrong thing.

Finally, the licence metadata is inconsistent in a way worth noticing before you depend on it. The README badge and pyproject.toml both say MIT, and pyproject carries the MIT classifier, but the repository's licence field is reported as NOASSERTION. That usually means the detector could not classify the licence file, not that the terms differ, but it is the kind of thing to confirm with whoever handles licensing at your organisation rather than assume.

Mahotas versus OpenCV, and versus scikit-image

The comparison people search for is mahotas versus OpenCV, and the difference is not speed, it is scope. OpenCV is a framework: it has its own matrix type, video capture, camera calibration, a DNN module and bindings for many languages. Mahotas has none of that. It has functions that take numpy arrays. If your data already lives in numpy, mahotas avoids a conversion layer; if you need to read a video stream or run a pre-trained network, OpenCV covers ground mahotas does not attempt.

Against scikit-image the split is subtler, because both operate on numpy arrays and both cover classical algorithms. scikit-image is pure Python plus compiled helpers and aims at breadth and readable implementations. Mahotas puts the algorithms themselves in C++. The practical difference shows up in the texture feature set: mahotas ships Haralick, Zernike, LBP and TAS features, and exposes a mahotas-features command line entry point through the mahotas.features_cli module, which scikit-image does not provide in the same form. For a pipeline that extracts texture descriptors from many small images, that CLI and feature set is the reason to pick mahotas.

A third option is to use both. Because mahotas consumes and produces numpy arrays, there is no object model to reconcile. You can threshold with one library and label with the other without an adapter.

Maintenance, releases and upgrade cost

The repository is not archived, and the last push was on 2026-06-12. The most recent release listed is v1.4.14 from 2024-03-23, after v1.4.13 and v1.4.12 in 2022. The README claims a release schedule of roughly one release a month, which the release history does not match; treat that sentence as an aspiration rather than a description of the current cadence.

On upgrade cost, the README makes a strong stability claim: "code written using a version of mahotas from years back will work just fine in the current version", with deprecated interfaces removed only after a few years of warnings, and occasional result changes where old code had a bug. That is a favourable position for a research codebase, because pinning an old version and upgrading later is not the usual rewrite. The trade-off is that a behaviour change caused by a bug fix can alter published numbers, so if you are reproducing an experiment, record the mahotas version alongside the results.

The supported Python range is 3.10 through 3.14 per the README, and pyproject.toml sets requires-python to >=3.10 with classifiers for those five versions. Older Python is out of scope, so an upgrade of the interpreter is the more likely forcing function than an upgrade of mahotas itself.

On licensing, the README badge and pyproject.toml both state MIT, and the MIT classifier is present. The repository licence field is NOASSERTION. MIT is permissive, but I am not giving legal advice: if the distinction matters to your organisation, read the COPYING file in the repository root and the licence text it points to.

Editorial conclusion

Adopt mahotas if your pipeline is already numpy-centric and you need classic primitives such as watershed, Haralick, Zernike, LBP or TAS features without adding a framework dependency. Do not adopt it if you need trained deep models, GPU execution, or a single library that also handles video and camera I/O, because mahotas deliberately leaves those to other packages. Before committing, run the documented import and test command in the exact Python version you deploy on, and confirm the C++ build works on your platform; the README points to the install page for pre-built options, and the repository's pyproject.toml lists Python 3.10 through 3.14 as the supported range.

Frequently asked questions

How do I install mahotas?

With conda, add the conda-forge channel and then install mahotas, which the README shows as two separate commands. With pip, the README says you need Python, NumPy and a C++ compiler, after which pip install mahotas works. The README also points to the online manual's install page for pre-built packages on several platforms.

What is mahotas used for?

It provides classical computer vision and image processing algorithms that operate on numpy arrays, including watershed, thresholding, convolution, Sobel edge detection, SLIC superpixels, and Haralick, Zernike, LBP and TAS texture features. The README describes it as a library of fast computer vision algorithms implemented in C++.

Does mahotas include deep learning models?

No. The notable algorithm list covers classical operations such as watershed, convex points, hit and miss, thinning, SURF, thresholding, convolution, spline interpolation and SLIC superpixels. There is no model zoo or inference runtime in the documented feature set, so tasks that need trained models require another library.

What Python versions does mahotas support?

The README states that Python 3.10 through 3.14 are supported, and pyproject.toml sets requires-python to >=3.10 with classifiers for those same five versions. Older interpreters are outside the documented range.

Official sources

  1. Issues
  2. luispedro/mahotas on GitHub
  3. Project website
  4. README
  5. Releases
Community notes

Community notes