Install with distortion support
The PyPI wheel (pip install locus-tag) is compiled without the non_rectified Cargo feature. It supports the ideal pinhole camera model only. To detect markers in imagery from unrectified cameras — i.e. cameras with significant lens distortion (Brown-Conrady polynomial, Kannala-Brandt equidistant fisheye) — you must build from source with the non_rectified feature enabled.
Prerequisites
- A working Rust toolchain (stable). Install via rustup.
- A C compiler (for any transitive C dependencies of
numpy/pyo3). - Python ≥ 3.10 with
piporuv.
Install from source with the feature enabled
Pass --features locus-py/non_rectified to the maturin build backend via MATURIN_PEP517_ARGS:
MATURIN_PEP517_ARGS="--features locus-py/non_rectified" \
pip install --no-binary=locus-tag --force-reinstall locus-tag
The equivalent uv invocation:
MATURIN_PEP517_ARGS="--features locus-py/non_rectified" \
uv pip install --no-binary=locus-tag --reinstall locus-tag
--no-binary=locus-tag tells pip to ignore the prebuilt wheel on PyPI and install from the source distribution instead. MATURIN_PEP517_ARGS is then forwarded to cargo build.
Verify
import locus
assert locus.HAS_NON_RECTIFIED
assert hasattr(locus.DistortionModel, "BrownConrady")
assert hasattr(locus.DistortionModel, "KannalaBrandt")
Use
from locus import CameraIntrinsics, DistortionModel
# Brown-Conrady polynomial distortion (OpenCV convention)
intrinsics = CameraIntrinsics(
fx=800.0, fy=800.0, cx=640.0, cy=360.0,
distortion_model=DistortionModel.BrownConrady,
dist_coeffs=[-0.3, 0.1, 0.001, -0.002, 0.0], # [k1, k2, p1, p2, k3]
)
# Kannala-Brandt equidistant fisheye
fisheye = CameraIntrinsics(
fx=380.0, fy=380.0, cx=320.0, cy=240.0,
distortion_model=DistortionModel.KannalaBrandt,
dist_coeffs=[0.1, -0.01, 0.001, 0.0], # [k1, k2, k3, k4]
)
Error: LocusFeatureError
Using a distortion model on the lean (PyPI) wheel raises LocusFeatureError with the install recipe above:
>>> import locus
>>> locus.DistortionModel.BrownConrady
Traceback (most recent call last):
...
locus.LocusFeatureError: DistortionModel.BrownConrady is unavailable.
Distortion models require the `non_rectified` Cargo feature, which is not
compiled into this wheel. Reinstall from source:
MATURIN_PEP517_ARGS="--features locus-py/non_rectified" \
pip install --no-binary=locus-tag --force-reinstall locus-tag
...
Catch it programmatically with locus.LocusFeatureError:
import locus
try:
model = locus.DistortionModel.BrownConrady
except locus.LocusFeatureError:
model = locus.DistortionModel.Pinhole # fall back to rectified input
Why isn't this a separate PyPI wheel?
Two wheels (locus-tag, locus-tag-unrectified) would both ship a locus.abi3.so native extension and mechanically overwrite each other on pip install. The sdist-with-feature path keeps the PyPI surface clean while letting downstream robotics and AV users opt in to distortion at build time.