Skip to main content

Vernier — Geometric calibration toolkit for multi-camera and multi-sensor systems

Project description

vernier

CI PyPI License

Geometric calibration, fast. Multi-camera intrinsics, multi-sensor extrinsics, and bundle adjustment through a clean Python API on top of a Ceres Solver / Sophus core.

pip install pyvernier
import numpy as np
import vernier

K = np.array([[1400, 0, 960], [0, 1400, 540], [0, 0, 1]], dtype=np.float64)
distortion = np.zeros(5)

estimator = vernier.Estimator(loss="huber", loss_scale=1.0)
camera = estimator.add_camera("brown_conrady", K, distortion, fixed=["k3"])
frame  = estimator.add_frame(vernier.SE3(), vernier.Submanifold.SE3)

for point_3d, pixel_2d in observations:
    estimator.add_observation(camera, frame, point_3d, pixel_2d)

result = estimator.solve(max_iterations=200)
# SolveResult(converged=True, rms=0.31, iterations=8, time=0.076)

K_opt    = estimator.get_camera_matrix(camera)
dist_opt = estimator.get_dist_coefficients(camera)
pose_opt = estimator.get_frame_pose(frame)

Features

Projection Models

Model Distortion vector Use case
BrownConrady [k1, k2, p1, p2, k3] Standard rectilinear cameras (OpenCV default)
KannalaBrandt [k1, k2, k3, k4] Fisheye / wide-angle
Division [k1, k2] Lightweight radial distortion
Rational [k1..k6, p1, p2] Complex optics
# String API
camera = estimator.add_camera("kannala_brandt", K, dist)

# Class API
camera = estimator.add_camera(vernier.KannalaBrandt, K, dist)

Per-Parameter Fixing

Hold any subset of intrinsic parameters constant during optimization:

# Fix k3 by name
camera = estimator.add_camera("brown_conrady", K, dist, fixed=["k3"])

# Fix by enum
camera = estimator.add_camera(
    vernier.BrownConrady, K, dist,
    fixed=[vernier.BrownConrady.Param.K3],
)

# Optimize distortion only
camera = estimator.add_camera(
    "brown_conrady", K, dist,
    fixed=["fx", "fy", "cx", "cy"],
)

Submanifold Pose Constraints

Choose which degrees of freedom of an SE(3) frame are optimized:

# Full 6-DOF (default)
frame = estimator.add_frame(pose, vernier.Submanifold.SE3)

# Translation only
frame = estimator.add_frame(pose, vernier.Submanifold.TRANSLATION)

# Rotation only
frame = estimator.add_frame(pose, vernier.Submanifold.ROTATION)

# Arbitrary axis combination
frame = estimator.add_frame(
    pose,
    vernier.Submanifold.X | vernier.Submanifold.Y | vernier.Submanifold.WZ,
)

# Held fixed
frame = estimator.add_frame(pose, vernier.Submanifold.NONE)

Robust Loss Functions

Per-observation loss for outlier handling. Default is Huber (1.0 px) — the standard in bundle adjustment.

Loss Behavior When to use
"none" Pure L2 Clean synthetic data
"huber" L2 below scale, L1 above Default — calibration with mild outliers
"cauchy" Aggressive downweighting Noisy real-world data
"soft_l1" Smooth L1 approximation Dense correspondences
# Estimator-wide default
estimator = vernier.Estimator(loss="cauchy", loss_scale=0.5)

# Per-observation override
estimator.add_observation(camera, frame, p3d, p2d, loss="cauchy", loss_scale=0.5)

Architecture

src/vernier/
├── __init__.py        Public re-exports + version
├── _core.py           Lie groups, projection models, enums, results
└── estimator.py       Estimator — Pythonic problem-construction API

The optimization core wraps Ceres Solver for non-linear least squares with autodiff and Sophus for SE(3) / SO(3) manifold operations. Projection models are stateless C++ trait structs dispatched via std::variant + std::visit so Ceres gets exact Jacobian block sizes per camera.

Documentation

Full documentation will be available at vistralis.org/vernier.

Development

pip install -e ".[dev]"
ruff check .
ruff format --check .
pytest

License

Apache-2.0 — see LICENSE for details.

Copyright (c) 2026 Vistralis Labs.

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

pyvernier-0.0.1.dev1.tar.gz (18.4 kB view details)

Uploaded Source

Built Distributions

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

pyvernier-0.0.1.dev1-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl (36.1 kB view details)

Uploaded CPython 3.14manylinux: glibc 2.24+ x86-64manylinux: glibc 2.28+ x86-64

pyvernier-0.0.1.dev1-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl (34.7 kB view details)

Uploaded CPython 3.14manylinux: glibc 2.24+ ARM64manylinux: glibc 2.28+ ARM64

pyvernier-0.0.1.dev1-cp314-cp314-macosx_14_0_arm64.whl (31.7 kB view details)

Uploaded CPython 3.14macOS 14.0+ ARM64

pyvernier-0.0.1.dev1-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl (36.1 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.24+ x86-64manylinux: glibc 2.28+ x86-64

pyvernier-0.0.1.dev1-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl (34.6 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.24+ ARM64manylinux: glibc 2.28+ ARM64

pyvernier-0.0.1.dev1-cp313-cp313-macosx_14_0_arm64.whl (31.8 kB view details)

Uploaded CPython 3.13macOS 14.0+ ARM64

pyvernier-0.0.1.dev1-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl (36.1 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.24+ x86-64manylinux: glibc 2.28+ x86-64

pyvernier-0.0.1.dev1-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl (34.6 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.24+ ARM64manylinux: glibc 2.28+ ARM64

pyvernier-0.0.1.dev1-cp312-cp312-macosx_14_0_arm64.whl (31.8 kB view details)

Uploaded CPython 3.12macOS 14.0+ ARM64

pyvernier-0.0.1.dev1-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl (36.6 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.24+ x86-64manylinux: glibc 2.28+ x86-64

pyvernier-0.0.1.dev1-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl (35.1 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.24+ ARM64manylinux: glibc 2.28+ ARM64

pyvernier-0.0.1.dev1-cp311-cp311-macosx_14_0_arm64.whl (32.4 kB view details)

Uploaded CPython 3.11macOS 14.0+ ARM64

pyvernier-0.0.1.dev1-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl (36.6 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.24+ x86-64manylinux: glibc 2.28+ x86-64

pyvernier-0.0.1.dev1-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl (35.1 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.24+ ARM64manylinux: glibc 2.28+ ARM64

pyvernier-0.0.1.dev1-cp310-cp310-macosx_14_0_arm64.whl (32.4 kB view details)

Uploaded CPython 3.10macOS 14.0+ ARM64

File details

Details for the file pyvernier-0.0.1.dev1.tar.gz.

File metadata

  • Download URL: pyvernier-0.0.1.dev1.tar.gz
  • Upload date:
  • Size: 18.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pyvernier-0.0.1.dev1.tar.gz
Algorithm Hash digest
SHA256 085c35d63329070d7d20d49700e6a9b519fed63e66194d9fbda1e89454178154
MD5 2ac40528ee18c44662ab874e20a2e53c
BLAKE2b-256 5572439153969241529a6c06ae4baeaf94237cffd9a33ec003aeb7860fb78930

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyvernier-0.0.1.dev1.tar.gz:

Publisher: release.yml on vistralis/vernier

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

File details

Details for the file pyvernier-0.0.1.dev1-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pyvernier-0.0.1.dev1-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 62773c3674313790f7a273747b2db586bd5297a6b8b2e60095f1ca2cf53f7843
MD5 cec458855e50d93c7afd2d33dfd2178e
BLAKE2b-256 305de4bde8641588080a751261df72f3a32ed38f1529ff239cc572fb44659a69

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyvernier-0.0.1.dev1-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl:

Publisher: release.yml on vistralis/vernier

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

File details

Details for the file pyvernier-0.0.1.dev1-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for pyvernier-0.0.1.dev1-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 46864c59846daf7b8b139c8abd05fcf388d7b2302e0f32f71a73b143b4142095
MD5 b66b6447fae5ee5835d3d30f40bf0ebb
BLAKE2b-256 f267c6e22d8fdd7d4ae8ee30cbc6fff73fe555f404a48c60d0538c4cbf83ecbe

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyvernier-0.0.1.dev1-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl:

Publisher: release.yml on vistralis/vernier

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

File details

Details for the file pyvernier-0.0.1.dev1-cp314-cp314-macosx_14_0_arm64.whl.

File metadata

File hashes

Hashes for pyvernier-0.0.1.dev1-cp314-cp314-macosx_14_0_arm64.whl
Algorithm Hash digest
SHA256 c01a464615fa97e8aa1e099cc6ea852fce40ade24378835b2a8d33b8dc7435b7
MD5 c43ccb40fe338da29979702fc868a51e
BLAKE2b-256 10c169a1ec47251058c9741b1a5f21415e433cedfa96d2c91253badb93d5283f

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyvernier-0.0.1.dev1-cp314-cp314-macosx_14_0_arm64.whl:

Publisher: release.yml on vistralis/vernier

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

File details

Details for the file pyvernier-0.0.1.dev1-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pyvernier-0.0.1.dev1-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 a8e068f947c7a8625526d5352d276c0007510445df0d050bbc96a4c3fcf81a4d
MD5 c85bb92f49bb0a82b31a8887de31c6f1
BLAKE2b-256 f02083e7f0662e048f5fbce930e224912a62b025f0736a3c769811367e162953

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyvernier-0.0.1.dev1-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl:

Publisher: release.yml on vistralis/vernier

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

File details

Details for the file pyvernier-0.0.1.dev1-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for pyvernier-0.0.1.dev1-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 f2d3ebcca192e5799c0c82f0b49bdb7f38cb609f68d96ea1b415f8a974df7482
MD5 a4503c52cabb2bc5c4bb2f85fb10b99b
BLAKE2b-256 169cf5858d4aa858b793ca1fe37199cd8c639b7b218562600c114faa9f03f08e

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyvernier-0.0.1.dev1-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl:

Publisher: release.yml on vistralis/vernier

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

File details

Details for the file pyvernier-0.0.1.dev1-cp313-cp313-macosx_14_0_arm64.whl.

File metadata

File hashes

Hashes for pyvernier-0.0.1.dev1-cp313-cp313-macosx_14_0_arm64.whl
Algorithm Hash digest
SHA256 96e5d1be63182993387a6f3e4dfcf76c1e1c98139d20308d4d932c5f4b5cef40
MD5 87e96c62f1a6b29c5b717abcdc759240
BLAKE2b-256 7ed459d1902fa550fc4b15db6947e799f55dc977a220cbaae7cbd4968e4f8126

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyvernier-0.0.1.dev1-cp313-cp313-macosx_14_0_arm64.whl:

Publisher: release.yml on vistralis/vernier

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

File details

Details for the file pyvernier-0.0.1.dev1-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pyvernier-0.0.1.dev1-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 2753f4069dfd39aa7c0c0c6a94f2e6a2b8db1501e0e072b61a92e404fbefe619
MD5 a41f3252ee25411d8f4a642aa4262da1
BLAKE2b-256 b30027deeb7a7bfbcb801e8c561987d6696e7659238bcccd7c7ea4c031145c60

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyvernier-0.0.1.dev1-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl:

Publisher: release.yml on vistralis/vernier

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

File details

Details for the file pyvernier-0.0.1.dev1-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for pyvernier-0.0.1.dev1-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 8d0c9b4db066f183f364cd4517072a67b22aba39bc971e9c22b2cc7dc5364821
MD5 afb94ec5fa6481d024a5aeb562d5e2a4
BLAKE2b-256 1bc343a8a45ff1204e4108513610da66a5cbd370afcecd7ae2e4991de9aeda90

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyvernier-0.0.1.dev1-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl:

Publisher: release.yml on vistralis/vernier

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

File details

Details for the file pyvernier-0.0.1.dev1-cp312-cp312-macosx_14_0_arm64.whl.

File metadata

File hashes

Hashes for pyvernier-0.0.1.dev1-cp312-cp312-macosx_14_0_arm64.whl
Algorithm Hash digest
SHA256 9ddd041f194568887647c2c19e01e98895e0eba4ed408d510308526b6475b54f
MD5 daf398d209dfa8c09cc6a214e89b7c90
BLAKE2b-256 bbef69bfbea9f75eedd5da7b64c018658e023e0d8da92d60e90d9d94fcf432a8

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyvernier-0.0.1.dev1-cp312-cp312-macosx_14_0_arm64.whl:

Publisher: release.yml on vistralis/vernier

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

File details

Details for the file pyvernier-0.0.1.dev1-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pyvernier-0.0.1.dev1-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 f6bb8badab70dc20e72b2eba6828b64e7262005e05307d39134d0b2b344e3cb0
MD5 cb86d6eaf44e23cdaa7060f9c1e1304c
BLAKE2b-256 463f8d088e1e6549847b48f53a1d890cc14f205a331c9e38a513dc122b58d1b4

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyvernier-0.0.1.dev1-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl:

Publisher: release.yml on vistralis/vernier

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

File details

Details for the file pyvernier-0.0.1.dev1-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for pyvernier-0.0.1.dev1-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 b89416f702f67d0f009a00a071a2a6821d8f3acd5c761b91a2cb8e5e12ae2319
MD5 10973584b58744858580e22b0f466f3f
BLAKE2b-256 32530f4cf7699cf35aed8066bdc114ca3b844850153f5a4230f01d69249487fd

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyvernier-0.0.1.dev1-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl:

Publisher: release.yml on vistralis/vernier

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

File details

Details for the file pyvernier-0.0.1.dev1-cp311-cp311-macosx_14_0_arm64.whl.

File metadata

File hashes

Hashes for pyvernier-0.0.1.dev1-cp311-cp311-macosx_14_0_arm64.whl
Algorithm Hash digest
SHA256 380cf79e3539059497e357c36e794aecdd4841f812fe4b96bedf4ff65f9248eb
MD5 d72df3a665951f8e6a15a0cd2a45d431
BLAKE2b-256 f89170d93ba7556493bc77c76fae0e809e3dc865f8258695dba0120492651740

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyvernier-0.0.1.dev1-cp311-cp311-macosx_14_0_arm64.whl:

Publisher: release.yml on vistralis/vernier

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

File details

Details for the file pyvernier-0.0.1.dev1-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pyvernier-0.0.1.dev1-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 9db48f0b5916f86fdd698b68f8388f0d1f5ecfbfeeaec4a41592a661a5d122bc
MD5 6fd922049f8ec9b403af05d4301e314f
BLAKE2b-256 94f2a42c3e1384bb156f7bf1a236f2632ff4d9bcef97fd01d0a25cf001114bd4

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyvernier-0.0.1.dev1-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl:

Publisher: release.yml on vistralis/vernier

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

File details

Details for the file pyvernier-0.0.1.dev1-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for pyvernier-0.0.1.dev1-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 a5594238570db07ed491c4c5b2cf22e1cabda83dfaa4e49c8bd390eaa005893b
MD5 7cce902c53354058660e3b422a3c1306
BLAKE2b-256 0ceec9f843e812bc5cab5636138a3e5f290cb84b26b57a50d28602fa46bf53f1

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyvernier-0.0.1.dev1-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl:

Publisher: release.yml on vistralis/vernier

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

File details

Details for the file pyvernier-0.0.1.dev1-cp310-cp310-macosx_14_0_arm64.whl.

File metadata

File hashes

Hashes for pyvernier-0.0.1.dev1-cp310-cp310-macosx_14_0_arm64.whl
Algorithm Hash digest
SHA256 966da02c630bf2de32e621c8481ea5e97eef1dfc1dcbe922c578692aa19dc508
MD5 a22d769d6dc38d15f42d3055d22d5d5f
BLAKE2b-256 685ec4a7e26d4583f1cfb3bbb2111cbd72f9c6ccad0f75d7ce3a51cb231fd6c1

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyvernier-0.0.1.dev1-cp310-cp310-macosx_14_0_arm64.whl:

Publisher: release.yml on vistralis/vernier

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