equirectangular image processing with python using minimum dependencies
Project description
equilib
Processing Equirectangular Images with Python
equilib is a library for processing equirectangular (360°) images in Python.
- Pure Python, with
numpyandtorchas the only runtime dependencies. - Runs on CPU and CUDA tensors, with batched and mixed-precision processing.
- Automatic input-type detection (
numpy.ndarrayortorch.Tensor). - Extras such as rotation-matrix creation and a customizable grid sampler.
- Highly modular and extensible.
📖 Full documentation: https://haruishi43.github.io/equilib/
Installation
Prerequisites:
- Python
>=3.9 - PyTorch
>=2.8
pip install pyequilib
Transforms
equilib provides transforms between equirectangular, cubemap, and perspective
images. Each transform ships both a class API and a func API.
| Transform | Description |
|---|---|
Cube2Equi / cube2equi |
cubemap → equirectangular |
Equi2Cube / equi2cube |
equirectangular → cubemap |
Equi2Equi / equi2equi |
equirectangular → equirectangular |
Equi2Pers / equi2pers |
equirectangular → perspective |
Pers2Equi / pers2equi |
perspective → equirectangular |
The class API instantiates a reusable object configured once; the func API
takes the configuration on every call. The class API calls the func API
internally, so there is no behavioral difference — both are extensible.
Inputs are channel-first (BxCxHxW or CxHxW); the output type matches the
input. Common arguments shared across transforms:
rots: rotation as three angles pitch, yaw, roll in radians.z_down(bool): use a z-axis-down coordinate system. DefaultFalse.mode(str): interpolation mode. Default"bilinear".clip_output(bool): clip values to the input range. DefaultTrue.
Basic usage
Example with Equi2Pers / equi2pers.
class API
import numpy as np
from PIL import Image
from equilib import Equi2Pers
# Input equirectangular image (channel-first: HWC -> CHW)
equi_img = np.asarray(Image.open("./some_image.jpg"))
equi_img = np.transpose(equi_img, (2, 0, 1))
rots = {
"roll": 0.0,
"pitch": np.pi / 4, # rotate vertical
"yaw": np.pi / 4, # rotate horizontal
}
equi2pers = Equi2Pers(height=480, width=640, fov_x=90.0, mode="bilinear")
pers_img = equi2pers(equi=equi_img, rots=rots)
func API
import numpy as np
from PIL import Image
from equilib import equi2pers
equi_img = np.asarray(Image.open("./some_image.jpg"))
equi_img = np.transpose(equi_img, (2, 0, 1))
rots = {"roll": 0.0, "pitch": np.pi / 4, "yaw": np.pi / 4}
pers_img = equi2pers(
equi=equi_img,
rots=rots,
height=480,
width=640,
fov_x=90.0,
mode="bilinear",
)
See the documentation for every
transform's arguments, or browse the examples under tests, benchmarks, and
scripts.
Coordinate system
A right-handed XYZ global coordinate system: x-axis faces forward and
z-axis faces up.
roll: counter-clockwise rotation about thex-axispitch: counter-clockwise rotation about they-axisyaw: counter-clockwise rotation about thez-axis
Pass z_down=True to flip the system so the z-axis faces down. See more in the
coordinate system docs.
Grid sampling
To process equirectangular images quickly, equilib relies on grid sampling and
implements its own numpy and torch backends to minimize dependencies and
exploit cuda and batching:
- The
torchbackend uses the built-intorch.nn.functional.grid_sampleby default, with a customizable pure-torchimplementation also available. - The
numpybackend uses a pure-numpyimplementation that is faster thanscipyand more robust thancv2.remap. You can override it withscipyorcv2via theoverride_funcargument.
A c++/cuda implementation is WIP. See the
grid sampling docs and the
benchmark scripts in
benchmarks/.
Development
This project uses uv and
Ruff. Image/video assets are stored with
Git LFS (git lfs install once before cloning).
git clone https://github.com/haruishi43/equilib.git
cd equilib
uv sync --group dev # create the venv and install package + dev tools
uv run pytest tests # run tests
uv run ruff check . # lint
uv run ruff format . # format
Pull requests and issues are welcome. See CONTRIBUTING.md for the full workflow, including how releases are published.
Roadmap
-
c++/cudagrid sampling - More accurate intrinsic matrix using vertical FOV for
equi2pers - Multiprocessing support (slow on
torch.distributed)
Citation
If this project was helpful to your work, please cite it:
@software{pyequilib2021github,
author = {Haruya Ishikawa},
title = {PyEquilib: Processing Equirectangular Images with Python},
url = {https://github.com/haruishi43/equilib},
version = {0.6.0},
year = {2021},
}
Acknowledgements
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
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 pyequilib-0.6.0rc1.tar.gz.
File metadata
- Download URL: pyequilib-0.6.0rc1.tar.gz
- Upload date:
- Size: 175.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
172b5d22d97f651bf1d5f4d8836e124d64a7da58f0ad4a390c8c9e30ae7280fc
|
|
| MD5 |
22402cec127e39aec284687aa9663001
|
|
| BLAKE2b-256 |
9d271b2af95584d35b103dbe6125c169de2e59676325bd4fd1a168f02d6236f2
|
Provenance
The following attestation bundles were made for pyequilib-0.6.0rc1.tar.gz:
Publisher:
python-publish.yml on haruishi43/equilib
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pyequilib-0.6.0rc1.tar.gz -
Subject digest:
172b5d22d97f651bf1d5f4d8836e124d64a7da58f0ad4a390c8c9e30ae7280fc - Sigstore transparency entry: 1884636006
- Sigstore integration time:
-
Permalink:
haruishi43/equilib@9c95b4b25a0d0525f65627b1b77e677079fef6ab -
Branch / Tag:
- Owner: https://github.com/haruishi43
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@9c95b4b25a0d0525f65627b1b77e677079fef6ab -
Trigger Event:
release
-
Statement type:
File details
Details for the file pyequilib-0.6.0rc1-py3-none-any.whl.
File metadata
- Download URL: pyequilib-0.6.0rc1-py3-none-any.whl
- Upload date:
- Size: 60.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d0f3986d384e03b68de41f036cb7022f34978771be2f3e156169da3998486c8b
|
|
| MD5 |
49539da10d261332004b898d609efb15
|
|
| BLAKE2b-256 |
e6aa8025df145059cb2699fa5cd986d870cb9f29d5623dc7feb33e8ff3d19ee0
|
Provenance
The following attestation bundles were made for pyequilib-0.6.0rc1-py3-none-any.whl:
Publisher:
python-publish.yml on haruishi43/equilib
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pyequilib-0.6.0rc1-py3-none-any.whl -
Subject digest:
d0f3986d384e03b68de41f036cb7022f34978771be2f3e156169da3998486c8b - Sigstore transparency entry: 1884636050
- Sigstore integration time:
-
Permalink:
haruishi43/equilib@9c95b4b25a0d0525f65627b1b77e677079fef6ab -
Branch / Tag:
- Owner: https://github.com/haruishi43
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@9c95b4b25a0d0525f65627b1b77e677079fef6ab -
Trigger Event:
release
-
Statement type: