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.
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.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pixelmap_python-0.1.0.tar.gz.
File metadata
- Download URL: pixelmap_python-0.1.0.tar.gz
- Upload date:
- Size: 25.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4c4fe356189c5401dc244a2940f62ce432d1efe3d0a180d39a739ad011709580
|
|
| MD5 |
1ca68f03d8626af0afd35620abba94cd
|
|
| BLAKE2b-256 |
013db2ccdaeda6c62ff48cd3c086ed7551baf4c301813b02aeae91de6b2b6dbe
|
Provenance
The following attestation bundles were made for pixelmap_python-0.1.0.tar.gz:
Publisher:
release.yml on d4per/pixelmap-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pixelmap_python-0.1.0.tar.gz -
Subject digest:
4c4fe356189c5401dc244a2940f62ce432d1efe3d0a180d39a739ad011709580 - Sigstore transparency entry: 2731040734
- Sigstore integration time:
-
Permalink:
d4per/pixelmap-python@3dcb28028bd20a9e6d6cb68ebe73575abf467514 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/d4per
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@3dcb28028bd20a9e6d6cb68ebe73575abf467514 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pixelmap_python-0.1.0-cp39-abi3-win_amd64.whl.
File metadata
- Download URL: pixelmap_python-0.1.0-cp39-abi3-win_amd64.whl
- Upload date:
- Size: 253.1 kB
- Tags: CPython 3.9+, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
34503721696663b984884139f065cfaaba41dca2f8ad26149267ec59a33434ff
|
|
| MD5 |
911bd1beaaae9a107d7d233d89657ac0
|
|
| BLAKE2b-256 |
06004d869b25827fd5dcbdfbd6ea72cb728cc479624d16796a7221dc6b2480eb
|
Provenance
The following attestation bundles were made for pixelmap_python-0.1.0-cp39-abi3-win_amd64.whl:
Publisher:
release.yml on d4per/pixelmap-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pixelmap_python-0.1.0-cp39-abi3-win_amd64.whl -
Subject digest:
34503721696663b984884139f065cfaaba41dca2f8ad26149267ec59a33434ff - Sigstore transparency entry: 2731040988
- Sigstore integration time:
-
Permalink:
d4per/pixelmap-python@3dcb28028bd20a9e6d6cb68ebe73575abf467514 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/d4per
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@3dcb28028bd20a9e6d6cb68ebe73575abf467514 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pixelmap_python-0.1.0-cp39-abi3-musllinux_1_2_x86_64.whl.
File metadata
- Download URL: pixelmap_python-0.1.0-cp39-abi3-musllinux_1_2_x86_64.whl
- Upload date:
- Size: 586.7 kB
- Tags: CPython 3.9+, musllinux: musl 1.2+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dc7b0d2d5e0e019423a86c983f942491cccd0dfbf6283a562e8256b05d1e9c1a
|
|
| MD5 |
8ab2ba82b5277c2bc777d173d214b31c
|
|
| BLAKE2b-256 |
bd364502174b1a61cc20514825644d9a04d4ae48479667a366007b534ae4a3f1
|
Provenance
The following attestation bundles were made for pixelmap_python-0.1.0-cp39-abi3-musllinux_1_2_x86_64.whl:
Publisher:
release.yml on d4per/pixelmap-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pixelmap_python-0.1.0-cp39-abi3-musllinux_1_2_x86_64.whl -
Subject digest:
dc7b0d2d5e0e019423a86c983f942491cccd0dfbf6283a562e8256b05d1e9c1a - Sigstore transparency entry: 2731041104
- Sigstore integration time:
-
Permalink:
d4per/pixelmap-python@3dcb28028bd20a9e6d6cb68ebe73575abf467514 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/d4per
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@3dcb28028bd20a9e6d6cb68ebe73575abf467514 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pixelmap_python-0.1.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: pixelmap_python-0.1.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 375.0 kB
- Tags: CPython 3.9+, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a861fa57218ac9e5439765b4da503378dd77862613880c46d48558e5a7f48e44
|
|
| MD5 |
47fab0e99f74260f6844d86fbc857889
|
|
| BLAKE2b-256 |
ff15aeb4fe843392372690b108734c7c829956507c90da87d5096156ee7516a2
|
Provenance
The following attestation bundles were made for pixelmap_python-0.1.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:
Publisher:
release.yml on d4per/pixelmap-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pixelmap_python-0.1.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl -
Subject digest:
a861fa57218ac9e5439765b4da503378dd77862613880c46d48558e5a7f48e44 - Sigstore transparency entry: 2731041281
- Sigstore integration time:
-
Permalink:
d4per/pixelmap-python@3dcb28028bd20a9e6d6cb68ebe73575abf467514 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/d4per
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@3dcb28028bd20a9e6d6cb68ebe73575abf467514 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pixelmap_python-0.1.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: pixelmap_python-0.1.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 368.8 kB
- Tags: CPython 3.9+, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e931873f281a3f599bc2fe5fc3eb0fad43bd44c3815eeee3edb6c2f106c91ec1
|
|
| MD5 |
3613afd1f463fa92d04c343bd09c3627
|
|
| BLAKE2b-256 |
4700ce646f2bec35f7bb776bc891418e90cdbbf773d1002a8cd1e5c849f6e395
|
Provenance
The following attestation bundles were made for pixelmap_python-0.1.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:
Publisher:
release.yml on d4per/pixelmap-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pixelmap_python-0.1.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl -
Subject digest:
e931873f281a3f599bc2fe5fc3eb0fad43bd44c3815eeee3edb6c2f106c91ec1 - Sigstore transparency entry: 2731041466
- Sigstore integration time:
-
Permalink:
d4per/pixelmap-python@3dcb28028bd20a9e6d6cb68ebe73575abf467514 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/d4per
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@3dcb28028bd20a9e6d6cb68ebe73575abf467514 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pixelmap_python-0.1.0-cp39-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: pixelmap_python-0.1.0-cp39-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 334.4 kB
- Tags: CPython 3.9+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d7539fd06ba12bcc3a28e230a06ed1a1561ece040e1d87c3382fd982d67f0e1e
|
|
| MD5 |
3fe6c90efe08e9784fe6997586417549
|
|
| BLAKE2b-256 |
05b888e1a201babb17207610fd6dd8d903011db6f91502e524fc1cfa49e8b54b
|
Provenance
The following attestation bundles were made for pixelmap_python-0.1.0-cp39-abi3-macosx_11_0_arm64.whl:
Publisher:
release.yml on d4per/pixelmap-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pixelmap_python-0.1.0-cp39-abi3-macosx_11_0_arm64.whl -
Subject digest:
d7539fd06ba12bcc3a28e230a06ed1a1561ece040e1d87c3382fd982d67f0e1e - Sigstore transparency entry: 2731040883
- Sigstore integration time:
-
Permalink:
d4per/pixelmap-python@3dcb28028bd20a9e6d6cb68ebe73575abf467514 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/d4per
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@3dcb28028bd20a9e6d6cb68ebe73575abf467514 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pixelmap_python-0.1.0-cp39-abi3-macosx_10_12_x86_64.whl.
File metadata
- Download URL: pixelmap_python-0.1.0-cp39-abi3-macosx_10_12_x86_64.whl
- Upload date:
- Size: 345.1 kB
- Tags: CPython 3.9+, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5484839f0bfb33f7650da87b985dec544c4ac7319660c8c67e6dbb9e9940162c
|
|
| MD5 |
05d1a74430422d7744986ffbb1fc680f
|
|
| BLAKE2b-256 |
2f5690d9ec044ff18a16ff0bb8e3e9cc15b1e3051c228ffd9809faeb525816d2
|
Provenance
The following attestation bundles were made for pixelmap_python-0.1.0-cp39-abi3-macosx_10_12_x86_64.whl:
Publisher:
release.yml on d4per/pixelmap-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pixelmap_python-0.1.0-cp39-abi3-macosx_10_12_x86_64.whl -
Subject digest:
5484839f0bfb33f7650da87b985dec544c4ac7319660c8c67e6dbb9e9940162c - Sigstore transparency entry: 2731041385
- Sigstore integration time:
-
Permalink:
d4per/pixelmap-python@3dcb28028bd20a9e6d6cb68ebe73575abf467514 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/d4per
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@3dcb28028bd20a9e6d6cb68ebe73575abf467514 -
Trigger Event:
push
-
Statement type: