Python code for Polyhedral Unmixing: unsupervised segmentation-to-unmixing model for linear spectral unmixing via polyhedral partitioning of space.
Examples with Samson, Jasper Ridge and Urban-6 hyperspectral datasets in the blind setting (see notebooks).
The code is based on the papers [1], [2] and was developed on Linux - Ubuntu 22.04.
If you find the code useful, please cite us as follows.
@article{...,
author = {Bottenmuller, Antoine and Decenci\`ere, Etienne and Dokl\'adal, Petr},
title = {Polyhedral Unmixing ...},
year = {2026}
}
@article{...,
author = {Bottenmuller, Antoine and Decenci\`ere, Etienne and Dokl\'adal, Petr},
title = {Abundance Estimation ...},
year = {2027}
}
Polyhedral Unmixing makes a direct bridge between spectral image classification (semantic segmentation) and unmixing, as illustrated in the figure below, via a theoretical characterization of the so-called dominant-material regions in the spectral space
Under the linear mixing model (LMM), these regions are polyhedral cones when endmembers are linearly independent (see paper [1]), or can be constructed as more general polyhedral sets under linear dependence via a limit-based formulation (see paper [2]), forming a partition of
We leverage this property to propose a new unmixing pipeline that, from an input spectral image
The pipeline of the proposed method is described in the next section.
The Polyhedral unmixing model follows the pipeline illustrated in the figure below (with
From a given input spectral dataset (col. 1.) and classification map (or clustering model) with
Signed distances to the
Under linear independence of the endmembers, an endmember estimate
See papers [1], [2] for a detailed method presentation.
-
datasets/: Folder dedicated to datasets (
$Y$ ) and their ground-truths (endmembers$M$ and abundances$A$ ). - figures/: Folder containing the figures used to illustrate this README and the Polyhedral Unmixing model.
-
src/: Main source code.
-
unmixing.py: Main unmixing functions and class. -
datasets.py: Downloading and loading datasets. -
display.py: Displaying datasets and results. -
metrics.py: Evaluation of unmixing results. -
polyset.py: Functions for polyhedral computation. -
min_norm_point_solvers/: Solvers for the minimal-norm point problem in convex polyhedra.
-
min_norm_point_DAQP.py: Minimal-norm point algorithm using the DAQP solver. -
min_norm_point_PYTHON.py: Minimal-norm point algorithm using our own solver in Python. - min_norm_point_C/: Minimal-norm point algorithm using our own solver in C (requires compilation).
-
-
-
example_<...>.ipynb: Example notebooks applying the unmixing model to datasets, with results. -
requirements.txt: List of required Python packages. -
LICENSE: MIT license for this software. -
README.md: This file.
python3 -m venv ./env # create virtual environment
source env/bin/activate # activate environmentpip install -r requirements.txt # install Python packagesIn order to use the C version of our minimal-norm point solver, please install GLPK and compile the min_norm_point package using the following commands (for Linux):
sudo apt-get install glpk-utils libglpk-dev glpk-doc # install GLPK
pip install ./src/min_norm_point_solvers/min_norm_point_C # compile & install C min_norm_point packagesrc/min_norm_point_solvers/min_norm_point_C/README.md for manual compilation.
You can also use either DAQP (min_norm_point_DAQP.py) or the Python version of our MNP algorithm (min_norm_point_PYTHON.py) instead, but note that the latter is about 100× slower than the C version.
Please download and drop the datasets in the datasets/ folder (see datasets/README.md).
This may be done either manually or automatically using the load functions provided in datasets.py.
Open and run one of the three Notebooks as an example.
To use the main unmixing model, import the PolyhedralUnmixingModel class and initialize it via
# Import the Polyhedral Unmixing Model class
from src.unmixing import PolyhedralUnmixingModel
# Initialize the model with given arguments
model = PolyhedralUnmixingModel(*init_args)Then, fit the model by passing the indicated arguments and predict unmixing matrices over your input spectral image.
Two main uses of the same model are possible:
Under linear independence of the endmembers, both endmembers
model.fit(*args)M_hat, A_hat = model.predict(Y)You can also use M_hat, A_hat = model.fit_predict(Y, *args) to fit and predict at the same time.
Under linear dependence of the endmembers, matrix pseudo-inversion is either not stable or impossible, and the search for a couple
model.fit_initial(*args)A_init = model.predict_initial_abundances(Y)You can also use A_init = model.fit_predict_initial_abundances(Y, *args) to fit and predict at the same time.
This code is based on our two papers available online:
[1] ...
Open access: ...
[2] ...
Open access: ...