pixelmap-python
Dense image correspondence: given two photographs of the same scene, work out where each pixel of the first one went in the second.
Python bindings for the pixelmap Rust crate, the
reference implementation of the PIXELMAP framework
(white paper). Every cell of an
affine correspondence grid acts as an autonomous agent holding its own local affine
transform; agents refine their transform against the image data and propagate what they
find to their neighbours, and a forward/backward consistency check culls the ones that
disagree. Repeating that coarse-to-fine yields a dense, geometrically consistent mapping.
Useful for optical flow, image registration and stitching, stereo matching, morphing, and as the front half of a 3D reconstruction.
Install
pip install pixelmap-python
The package installs as pixelmap-python but imports as pixelmap — PyPI will not accept
pixelmap as a distribution name, because it collides with the unrelated pixel-map
project under PyPI's similarity rule.
Wheels are published for Linux (x86-64, aarch64, musl), macOS (Apple silicon and Intel) and Windows (x86-64), for CPython 3.9 and newer. NumPy is the only runtime dependency; no Rust toolchain is needed unless you build from source.
Quick start
import numpy as np
import pixelmap
from PIL import Image
a = np.asarray(Image.open("a.jpg").convert("RGB"))
b = np.asarray(Image.open("b.jpg").convert("RGB")) # same dimensions as a
mapping = pixelmap.correspond(a, b, quality="low")
flow = mapping.flow() # (H, W, 2) float32: how far each pixel moved
print(f"{mapping.coverage:.1%} of the image was mapped")
# Where did the pixel at (120, 84) end up?
print(mapping.lookup(120.0, 84.0)) # (114.2, 80.6), or None if unmapped
flow[y, x] is (dx, dy) in the source photos' own pixel coordinates. Regions the
algorithm could not map — occlusions, featureless sky, anything the consistency check
rejected — are NaN rather than a plausible-looking coordinate:
unmapped = np.isnan(flow[..., 0])
Coverage well below 1.0 is normal and not a failure. A very low value means the two photos had little in common, or are related by something an affine grid cannot express.
Warping one photo onto the other
flow(absolute=True) returns destination coordinates instead of displacements, which is
what OpenCV's remap wants:
import cv2
dst = mapping.flow(absolute=True)
warped = cv2.remap(a, dst[..., 0], dst[..., 1], cv2.INTER_LINEAR)
There is also a built-in morph, which interpolates the first photo t of the way towards
the second:
halfway = mapping.morph(0.5, detail=2) # (h, w, 4) uint8, at working resolution
Watching a long run
mapping = pixelmap.correspond(
a,
b,
quality=pixelmap.Quality.HIGH,
progress=lambda step, total: print(f"{step}/{total}"),
)
The GIL is released while the solver runs, so correspond can be called from a worker
thread without blocking the rest of your program.
To stop a run early, raise from the callback: the solver stops at the end of that step and
your exception comes out of correspond. Ctrl-C stops it the same way, callback or not.
API
correspond(photo1, photo2, *, quality, seed, max_round_trip_error, progress) |
Run the pipeline. |
Correspondence.flow(*, backward=False, absolute=False) |
The dense field as (H, W, 2) float32. |
Correspondence.lookup(x, y, *, backward=False) |
One point, or NumPy arrays of them. |
Correspondence.morph(t, *, detail=1) |
The first photo warped towards the second. |
Correspondence.coverage |
Fraction of the image that got a mapping. |
Correspondence.comparisons |
Region comparisons performed. |
Correspondence.source_dimensions / .working_dimensions / .working_scale |
Geometry. |
Correspondence.to_bytes() / .from_bytes(data, photo1, photo2) |
Save and reload a mapping. |
Quality.LOW / .MEDIUM / .HIGH |
Presets, or the equivalent strings. |
Input. Photos are uint8 arrays of shape (H, W), (H, W, 1), (H, W, 3) or
(H, W, 4) — Pillow images work directly. Both must have the same dimensions and be at
least 32 pixels on each side. Violations raise SizeMismatchError, PhotoTooSmallError
or ValueError, all of which are ValueError subclasses.
Quality. LOW, MEDIUM and HIGH run 4, 10 and 13 refinement steps and finish at a
working width of 400, 800 and 1600 pixels respectively, so cost grows faster than the step
count suggests. flow and lookup answer in your photos' coordinates regardless; use
working_scale if you need to reason about the solver's effective resolution.
Determinism. The same photos, quality and seed give the same mapping — run to run,
thread to thread, and machine to machine. Pass seed= to vary it.
Building from source
Requires Rust 1.83 or newer.
git clone https://github.com/d4per/pixelmap-python
cd pixelmap-python
pip install maturin
maturin develop --release
pytest
maturin develop without --release builds an unoptimised solver that is many times
slower; use it only for iterating on the bindings themselves.
See also
- Interactive demo — upload your own images.
pixelmapon crates.io and its API docs — the Rust library this wraps.- The PIXELMAP repository — the algorithm, a command line tool, a viewer, and 3D reconstruction.
- White paper.
License
MIT — see LICENSE.
Release files for pixelmap-python 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pixelmap_python-0.3.0.tar.gz | 26.3 kB | Details |
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| pixelmap_python-0.3.0-cp39-abi3-win_amd64.whl | CPython 3.9 | abi3 | Windows x86-64 | Details |
| pixelmap_python-0.3.0-cp39-abi3-musllinux_1_2_x86_64.whl | CPython 3.9 | abi3 | Linux musl 1.2+ x86-64 | Details |
| pixelmap_python-0.3.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl | CPython 3.9 | abi3 | Linux glibc 2.17+ x86-64 | Details |
| pixelmap_python-0.3.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl | CPython 3.9 | abi3 | Linux glibc 2.17+ ARM64 | Details |
| pixelmap_python-0.3.0-cp39-abi3-macosx_11_0_arm64.whl | CPython 3.9 | abi3 | macOS 11.0+ ARM64 | Details |
| pixelmap_python-0.3.0-cp39-abi3-macosx_10_12_x86_64.whl | CPython 3.9 | abi3 | macOS 10.12+ x86-64 | Details |
Total release size: 2.4 MB
Release files / pixelmap_python-0.3.0.tar.gz
| Download URL | pixelmap_python-0.3.0.tar.gz |
|---|---|
| Size | 26.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
5a716dd387b75de50c5f6bca4e860a9d09ff67781c85d072be1996a84c4cad87
|
|
BLAKE2b-256 checksum How to use checksums |
fc12b987177da8044d0eadc27969872b21c240a35472efe6f19c9be94cc526ff
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 24, 2026.
Transparency logRelease files / pixelmap_python-0.3.0-cp39-abi3-win_amd64.whl
| Download URL | pixelmap_python-0.3.0-cp39-abi3-win_amd64.whl |
|---|---|
| Size | 273.2 kB |
| Tags | CPython 3.9 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
02b47b80f9d09c85c721e737668c16664c5db0a69854915c46c10f9cb9e84bc2
|
|
BLAKE2b-256 checksum How to use checksums |
23ccfb35faed2f07a12f931badf97034fad1049ae48df582e9dd71b5c2ba6fab
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 24, 2026.
Transparency logRelease files / pixelmap_python-0.3.0-cp39-abi3-musllinux_1_2_x86_64.whl
| Download URL | pixelmap_python-0.3.0-cp39-abi3-musllinux_1_2_x86_64.whl |
|---|---|
| Size | 607.0 kB |
| Tags | CPython 3.9 Linux musl 1.2+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
86fda05a57d470fa8fca562245b257c32a08015641149783704529115180e514
|
|
BLAKE2b-256 checksum How to use checksums |
316be11ee32e477ed688be562472f2d7e4a761d38149a76e4e81b1618611fdc0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 24, 2026.
Transparency logRelease files / pixelmap_python-0.3.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | pixelmap_python-0.3.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 395.8 kB |
| Tags | CPython 3.9 Linux glibc 2.17+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
bb6e2e79e2c4bc5c53a090d40088dd02df17497c7886ffe9c769addf16fa440f
|
|
BLAKE2b-256 checksum How to use checksums |
5af13220d252932a70932d310de568850e1ad40b7c00137394b86ae68e9a923e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 24, 2026.
Transparency logRelease files / pixelmap_python-0.3.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
| Download URL | pixelmap_python-0.3.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl |
|---|---|
| Size | 389.4 kB |
| Tags | CPython 3.9 Linux glibc 2.17+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
404b26e5c10db2acc4bd0474b68cb98e4a3e0dad74b929a38e0d47ac3b1e8072
|
|
BLAKE2b-256 checksum How to use checksums |
17a9c9f6234414a1027368cbf174d7af5357118a09dd62de569848c8ce000344
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 24, 2026.
Transparency logRelease files / pixelmap_python-0.3.0-cp39-abi3-macosx_11_0_arm64.whl
| Download URL | pixelmap_python-0.3.0-cp39-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 354.5 kB |
| Tags | CPython 3.9 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
4ac22cae5c8be07ec3e1849b1651fb43b64bf36fb0c92f842b57d9e8ee28ca9f
|
|
BLAKE2b-256 checksum How to use checksums |
079e5d2d5146cd28204ca8729a16f20639df57336f965dabd812e636279e0eeb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 24, 2026.
Transparency logRelease files / pixelmap_python-0.3.0-cp39-abi3-macosx_10_12_x86_64.whl
| Download URL | pixelmap_python-0.3.0-cp39-abi3-macosx_10_12_x86_64.whl |
|---|---|
| Size | 365.1 kB |
| Tags | CPython 3.9 abi3 macOS 10.12+ x86-64 |
|
SHA-256 checksum How to use checksums |
f2a49c097f83934bd5393bf117cae65783c616ec68a566583a4fedc40e3d2a94
|
|
BLAKE2b-256 checksum How to use checksums |
56118389f0f891fb3b0846202dfe0b1d9598f59bf29e7b263be713120f47c344
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 24, 2026.
Transparency log