UnitField
UnitField is a high-performance N-dimensional coordinate remapping library built on a Cython kernel with OpenMP parallelism. It maps unit-space coordinates ([0, 1]) through arbitrary displacement fields with configurable interpolation and border handling — purpose-built for image warping, morphing, and nonlinear coordinate transformations.
Why UnitField?
- Cython-accelerated kernel — 2D and 1D remap loops compiled to C with OpenMP threading. Significantly faster than pure NumPy for large images.
- Asymmetric per-edge feathering — Control feather blend independently on left, right, top, and bottom borders. Useful for seamless compositing and panorama blending.
- Per-channel feather masks — Feather only specific channels (e.g., alpha-only) via the
feather_dimsparameter. - Multiple border modes — CLAMP, CONSTANT, REFLECT, WRAP, REFLECT_101, and ARRAY compositing.
- Multiple interpolation methods — Nearest-neighbor, bilinear, bicubic (Catmull-Rom), Lanczos-3/4.
- 1-D signal remapping — The same kernel operates on 1-D signals, useful for audio, time-series, and look-up table applications.
- Endomorphism composition —
Unit2DMappedEndomorphismsupports composition (f ∘ g) for chaining transformations. - Endomorphism interpolation —
Unit1DEndoInterpolatorandUnit2DEndoInterpolatorblend transforms over time, even when endpoint maps use different sampled sizes. - Fast nearest map resize —
resize_unit_field_nearestupsamples or downsamples sampled remap fields for low-resolution interactive previews.
Installation
pip install unitfield
For the fastest installation with a pre-built wheel, ensure you have the cv2 extras (optional — used for comparison benchmarks only):
pip install "unitfield[cv2]"
From Source (Cython)
git clone https://github.com/Grayjou/UnitField.git
cd UnitField
pip install -e ".[dev]"
Requires: Python ≥ 3.10, NumPy ≥ 1.20, Cython ≥ 3.0 (for source builds), a C99 compiler with OpenMP support.
Quick Start
2-D Image Remapping
import numpy as np
from unitfield import (
BorderConfig, BorderMode, InterpMethod,
Unit2DMappedEndomorphism, remap_tensor,
)
# Simple identity field
H, W = 256, 256
xs, ys = np.meshgrid(np.linspace(0, 1, W), np.linspace(0, 1, H), indexing="xy")
identity = np.stack([xs, ys], axis=-1)
endo = Unit2DMappedEndomorphism(identity, interp_method=InterpMethod.LINEAR)
# Remap an image with asymmetric feathering
bc = BorderConfig(
mode=BorderMode.CONSTANT,
constant_value=0.0,
feathering_width=0.2,
feathering_x_overshoot_multiplier=3.0, # heavy feather on right
feathering_x_undershoot_multiplier=0.0, # hard edge on left
feather_dims=[True, True, True, False], # RGB feathers, alpha hard
)
result = endo.remap(image, interpolation=1, border_config=bc)
Direct remap with coordinate maps
map_x = np.random.rand(H, W).astype(np.float64)
map_y = np.random.rand(H, W).astype(np.float64)
result = remap_tensor(
image, map_x, map_y,
interpolation=1,
border_config=BorderConfig.constant(0.0, feathering_width=0.1),
)
Fast Preview From A Low-Resolution Map
from unitfield import InterpMethod, remap_tensor, resize_unit_field_nearest
# low_res_map shape: (preview_h, preview_w, 2), storing x/y unit coordinates
full_res_map = resize_unit_field_nearest(
low_res_map,
width=image.shape[1],
height=image.shape[0],
)
preview = remap_tensor(
image,
full_res_map[..., 0],
full_res_map[..., 1],
interpolation=InterpMethod.NEAREST_MANHATTAN,
)
resize_unit_field_nearest is the preferred helper for preview remap fields. resize_nearest is also available for generic 2-D or 3-D arrays when a nearest resize is needed directly.
1-D Signal Remapping
from unitfield import remap_tensor_1d
signal = np.sin(np.linspace(0, 4 * np.pi, 1000))
map_x = np.linspace(0, 1, 800) ** 2 # nonlinear time warp
warped = remap_tensor_1d(signal, map_x, interpolation=1)
Endomorphism Interpolation
import numpy as np
from unitfield import Unit1DEndoInterpolator
ease = np.array([0.0, 0.125, 0.25, 0.5625, 1.0])
linear = np.array([0.0, 0.25, 0.5, 0.75, 1.0])
interpolator = Unit1DEndoInterpolator(ease, linear)
halfway = interpolator.interpolate(t=0.5)
value = halfway.get_value((0.5,))[0]
remapped_signal = halfway.remap(signal, interpolation=1)
Endpoint maps can be raw 1-D arrays, Unit1DMappedEndomorphism, Unit2DMappedEndomorphism, or generic UnitMappedEndomorphism instances. If endpoint maps use different sampled sizes, both are evaluated on the requested output grid before blending.
Asymmetric Feathering
BorderConfig now exposes four independent feather multipliers — one per edge:
| Field | Edge | Applies when |
|---|---|---|
feathering_x_undershoot_multiplier |
left | u_x < 0.0 |
feathering_x_overshoot_multiplier |
right | u_x > 1.0 |
feathering_y_undershoot_multiplier |
top | u_y < 0.0 |
feathering_y_overshoot_multiplier |
bottom | u_y > 1.0 |
All default to 1.0. Set to 0.0 for a hard edge, or higher for a softer blend.
API Overview
| Module | Key exports |
|---|---|
unitfield |
BorderConfig, BorderMode, InterpMethod, remap_tensor, remap_tensor_1d, resize_unit_field_nearest, resize_nearest, Unit2DMappedEndomorphism, Unit1DMappedEndomorphism, Unit1DEndoInterpolator, Unit2DEndoInterpolator, MappedUnitField |
unitfield.core |
Same + UnitNdimField, UnitMappedEndomorphism, UnitEndomorphismInterpolator, UnitArray, UnitSpaceVector |
unitfield.utilities |
pbm_2d, upbm_2d, flat_1d_pbm — positional basematrix generators |
Performance
The kernel is written in Cython with:
- OpenMP-accelerated inner loops (
prange) - No Python overhead at runtime (
nogil) - Bicubic (Catmull-Rom) and Lanczos interpolation with efficient separable sampling
- Per-edge feather distance computed inline with the border handler
Run benchmarks locally:
pytest tests/ -v -m benchmark
Development
pip install -e ".[dev]"
pytest tests/ -v
License
MIT — see LICENSE.
Citation
@software{unitfield2026,
author = {GrayJou},
title = {UnitField: N-dimensional Unit Field Transformations},
year = {2026},
url = {https://github.com/Grayjou/UnitField},
}
Metadata
Release files for unitfield 0.2.12
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| unitfield-0.2.12.tar.gz | 725.3 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| unitfield-0.2.12-cp312-cp312-win_amd64.whl | CPython 3.12 | CPython 3.12 | Windows x86-64 | Details |
Total release size: 1.8 MB
Release files / unitfield-0.2.12.tar.gz
| Download URL | unitfield-0.2.12.tar.gz |
|---|---|
| Size | 725.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
034cec6faf1de6a3927d2c3fee76d7bdbf61a889dd5eac6f9f6cc69311fb4ebc
|
|
BLAKE2b-256 checksum How to use checksums |
d591b2f1d6c00321467fa812e2166ca085791b8bde12e9c86ec5c4daca03271e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.0
|
Release files / unitfield-0.2.12-cp312-cp312-win_amd64.whl
| Download URL | unitfield-0.2.12-cp312-cp312-win_amd64.whl |
|---|---|
| Size | 1.0 MB |
| Tags | CPython 3.12 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
c23824764b2cdd8a94d31ae89e4c749c44f8c636def3357b254d00cf4bb1d6cb
|
|
BLAKE2b-256 checksum How to use checksums |
f351247c3e7892c93b69da0098b8aa05311fe580646d624f65c7b26a69ae933e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.0
|
Security for unitfield 0.2.12
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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.