Skip to main content

equirectangular image processing with python using minimum dependencies

Project description

equilib

Processing Equirectangular Images with Python

PyPI version Python versions CI GitHub license Documentation
equilib

equilib is a library for processing equirectangular (360°) images in Python.

  • Pure Python, with numpy and torch as the only runtime dependencies.
  • Runs on CPU and CUDA tensors, with batched and mixed-precision processing.
  • Automatic input-type detection (numpy.ndarray or torch.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. Default False.
  • mode (str): interpolation mode. Default "bilinear".
  • clip_output (bool): clip values to the input range. Default True.

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 the x-axis
  • pitch: counter-clockwise rotation about the y-axis
  • yaw: counter-clockwise rotation about the z-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 torch backend uses the built-in torch.nn.functional.grid_sample by default, with a customizable pure-torch implementation also available.
  • The numpy backend uses a pure-numpy implementation that is faster than scipy and more robust than cv2.remap. You can override it with scipy or cv2 via the override_func argument.

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++/cuda grid 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pyequilib-0.6.0rc1.tar.gz (175.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pyequilib-0.6.0rc1-py3-none-any.whl (60.5 kB view details)

Uploaded Python 3

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

Hashes for pyequilib-0.6.0rc1.tar.gz
Algorithm Hash digest
SHA256 172b5d22d97f651bf1d5f4d8836e124d64a7da58f0ad4a390c8c9e30ae7280fc
MD5 22402cec127e39aec284687aa9663001
BLAKE2b-256 9d271b2af95584d35b103dbe6125c169de2e59676325bd4fd1a168f02d6236f2

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyequilib-0.6.0rc1.tar.gz:

Publisher: python-publish.yml on haruishi43/equilib

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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

Hashes for pyequilib-0.6.0rc1-py3-none-any.whl
Algorithm Hash digest
SHA256 d0f3986d384e03b68de41f036cb7022f34978771be2f3e156169da3998486c8b
MD5 49539da10d261332004b898d609efb15
BLAKE2b-256 e6aa8025df145059cb2699fa5cd986d870cb9f29d5623dc7feb33e8ff3d19ee0

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyequilib-0.6.0rc1-py3-none-any.whl:

Publisher: python-publish.yml on haruishi43/equilib

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page