Skip to main content

SigOrbit

CI License: MIT

Rotation-robust handwritten-signature embeddings with continuous SO(2) canonicalization and steerable C4/C8 backbones. Created and maintained by Jordi Murgó (GitHub · jordi.murgo@gmail.com · jordi.murgo@gft.com).

SigOrbit turns a cropped signature image into a deterministic, L2-normalized 256-dimensional vector. It is designed for retrieval, clustering and downstream verification systems that must tolerate arbitrary in-plane rotation without making mirrored signatures equivalent.

Demo

SigOrbit rotation-robustness demo

The analyzed signatures are compared with six references while rotation, scale, noise, blur and contrast vary. The matching reference remains identifiable in the per-reference cosine-similarity traces.

Watch or download the MP4 version.

Alpha release. SigOrbit generates embeddings; it is not a complete fraud detector, legal signature verifier, document detector, identity database or anti-spoofing system. Do not use one model score as the sole basis for legal, financial or access-control decisions.

Why the name?

A group action moves an input through its orbit. SigOrbit learns a canonical SO(2) pose and embeds signatures consistently across that rotation orbit. sigorbit was clear on PyPI and had no exact GitHub repository collision when checked on 2026-08-07. This is not a trademark opinion.

Architecture

Mermaid diagram

  • C4: 2,254,466 trainable parameters (2.2 M); C8: 4,276,354 (4.3 M)
  • 257×257 grayscale input
  • 256-dimensional float32 output
  • continuous SO(2) rotation canonicalization; no scale or reflection canonicalization
  • C4 or C8 regular representations and invariant group pooling; the canonicalizer handles continuous rotation, so C4 equivariance (90° symmetry) is sufficient for signatures and trains 2.7× faster

See the architecture notes and model card.

The end-to-end workflow wraps three training stages:

  1. validate an immutable local manifest and a separate rights attestation;
  2. train the C4 or C8 backbone from random weights with PK sampling, discrete rotation augmentation and a temporary ArcFace head;
  3. restore the best backbone and train only the SO(2) canonicalizer against known synthetic angles;
  4. jointly optimize canonicalizer, backbone and ArcFace head using identity, circular-orientation and cosine-consistency objectives;
  5. evaluate on signer-disjoint validation identities, restore the best joint checkpoint and export an inference-only SigOrbit artifact.

There are no reflections: the symmetry is SO(2)+C_N (N = group_order), not O(2)/D_N. The ArcFace classifier, optimizers and schedulers exist only in recovery checkpoints; the deployable artifact contains the canonicalizer and backbone.

Training and model lineage

The runtime package owns the exact model and preprocessing classes. The companion sigorbit-trainer package imports those classes directly rather than maintaining a second architecture. Its current from-scratch protocol has three stages:

  1. train the C4 or C8 backbone and a temporary ArcFace classifier;
  2. restore the best backbone, freeze it, and pretrain only the SO(2) canonicalizer against known synthetic angles;
  3. jointly fine-tune canonicalizer, backbone and ArcFace head with identity, circular-orientation and embedding-consistency losses.

The ArcFace head exists only during training and is not part of an exported encoder. The published package still identifies the historically selected checkpoint as sigorbit-c8-257-v1; that checkpoint used an older C8 initializer whose complete resume history was not archived. The auditable trainer produces two from-scratch model IDs: sigorbit-c8-257-retrained-v1 (C8, batch 32) and sigorbit-c4-257-b64 (C4, batch 64). Neither claims a byte-for-byte reproduction of the deployed model. See training and reproducibility for all lineages.

Install

Python 3.10+ is supported. Install the correct PyTorch build for your CPU, CUDA or ROCm platform first, then install SigOrbit:

python -m pip install sigorbit
# Optional FastAPI example:
python -m pip install "sigorbit[api]"

For an unreleased commit, installation directly from GitHub is also supported:

python -m pip install "sigorbit @ git+https://github.com/jordi-murgo/sigorbit.git@main"

For NVIDIA/ROCm, follow the official PyTorch selector rather than relying on the CPU wheel chosen by a generic resolver.

Python API

from sigorbit import SignatureEncoder

encoder = SignatureEncoder(
    checkpoint="/secure/path/sigorbit-c8-257-v1.pt",
    device="auto",
)
vector = encoder.embed("signature.png")

print(vector.shape)  # (256,)
print(vector.dtype)  # float32
print(float(vector @ vector))  # ~1.0
print(encoder.model_id)  # sigorbit-c8-257-v1
print(encoder.preprocess_version)  # sigorbit-gray-square-257-v1

Batch inference preserves order:

vectors = encoder.embed_batch(["a.png", "b.png"], batch_size=16)
assert vectors.shape == (2, 256)

Accepted inputs are PIL.Image, NumPy arrays, encoded bytes and file paths. Inputs must already be cropped signatures. Never compare embeddings generated by different model_id or preprocess_version values.

FastAPI example

pip install -e '.[api]'
export SIGORBIT_CHECKPOINT=/secure/path/sigorbit-c8-257-v1.pt
export SIGORBIT_CHECKPOINT_SHA256=ec8d99f887f5a2658d93b14a14911b29a1411e9cf142efa85862a47b30cd233e
export SIGORBIT_API_KEY=replace-with-a-secret-from-your-secret-manager
SIGORBIT_DEVICE=auto sigorbit-api

Then, from an authorized client:

curl http://127.0.0.1:8000/health
curl -X POST http://127.0.0.1:8000/embed \
  -H "Authorization: Bearer $SIGORBIT_API_KEY" \
  -F 'file=@signature.png'

The response includes the model/preprocess identity, predicted canonicalization angle and 256 normalized floats. Interactive docs are at /docs.

Configuration:

Variable Default Meaning
SIGORBIT_CHECKPOINT required in code-only release Local approved checkpoint path
SIGORBIT_CHECKPOINT_SHA256 required by HTTP API Expected approved artifact digest
SIGORBIT_DEVICE auto cpu, cuda, cuda:0, etc.
SIGORBIT_API_KEY unset on loopback Bearer token; required by CLI for non-loopback binding
SIGORBIT_HOST 127.0.0.1 Bind address
SIGORBIT_PORT 8000 Bind port
SIGORBIT_MAX_UPLOAD_BYTES 10485760 Encoded upload-file byte limit
SIGORBIT_MAX_REQUEST_BYTES upload limit + 65536 Pre-multipart request-body limit
SIGORBIT_MAX_IMAGE_PIXELS 4194304 Decompression-bomb pixel limit
SIGORBIT_MAX_CONCURRENT_REQUESTS 1 Full concurrent /embed request capacity
SIGORBIT_QUEUE_TIMEOUT_SECONDS 1.0 Wait before returning HTTP 503

Uploaded filenames are ignored: the API passes bytes to the decoder and never constructs or writes a filesystem path from client input. Encoded inputs are restricted to PNG, JPEG and WebP. The in-process Python API deliberately accepts trusted str/Path inputs, so applications must not forward a remote filename to SignatureEncoder.embed().

See the security review for the threat model, adversarial tests and residual risks.

The server binds to loopback by default. Before binding to a non-loopback address, configure bearer authentication and place it behind a TLS reverse proxy with request/time/rate limits. The built-in limits reduce accidental and simple resource exhaustion; they are not a replacement for an edge proxy or process isolation.

The example intentionally has no signer database and no hard-coded MATCH threshold. Thresholds are catalogue-, domain- and reference-count-specific.

Measured behavior

On the held-out 33-signer/792-image BHSig260 Bengali test split, the 257px checkpoint achieved:

  • clean leave-one-out top-1: 100.0% (792/792);
  • clean median margin: +0.3196;
  • model-canvas non-zero-angle mean top-1: 98.04%;
  • square-expand mean top-1: 98.16%;
  • raw-expand mean top-1: 89.87%;
  • real-signature all-triplet mean top-1: 87.64%.

These numbers describe one dataset/protocol, not a universal error rate. See the model card for exact protocols, limitations and the 129px comparison.

Development

python -m pip install -e '.[api,dev]'
ruff check .
pytest
python -m build

Repository layout:

src/sigorbit/model.py          architecture
src/sigorbit/checkpoint.py     safe artifact loading and identity
src/sigorbit/preprocessing.py  versioned image contract
src/sigorbit/encoder.py        public Python API
src/sigorbit/api.py            minimal FastAPI example
docs/                          architecture, model card, training and release notes
CITATION.bib                   project and technical bibliography

Responsible use and release status

Handwritten signatures are biometric personal data. Do not log uploads or embeddings unnecessarily, and establish retention, consent, access control and deletion policies before deployment.

The source code is MIT licensed. The repository contains no training images. Before publishing the trained checkpoint, read the completed dataset licence audit and complete RELEASING.md. All 7,560 aggregate images were matched pixel-for-pixel to genuine CEDAR and BHSig260 samples. CEDAR has no explicit licence grant, while the BHSig260 authors state only “for research purposes”. The Hub uploader's MIT tag therefore does not establish a sublicence chain. The local checkpoint is present to validate this extraction; do not push or publish it until upstream permission or counsel approval is recorded.

License and citation

Source code: MIT. Third-party notices: NOTICE. Repository: https://github.com/jordi-murgo/sigorbit.

If SigOrbit is useful in research, cite the software as:

@software{murgo2026sigorbit,
  author  = {Jordi Murgó},
  title   = {{SigOrbit}: Rotation-Robust Handwritten-Signature Embeddings},
  year    = {2026},
  version = {0.1.0},
  url     = {https://github.com/jordi-murgo/sigorbit},
  license = {MIT}
}

The complete BibTeX bibliography—including the e2cnn, CEDAR and BHSig260 references—is in CITATION.bib; machine-readable citation metadata is in CITATION.cff. Citing a dataset does not imply that it has an open licence; consult the dataset licence audit.

Download files

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

Source Distribution

sigorbit-0.2.5.tar.gz (2.4 MB view details)

Uploaded Source

Built Distribution

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

sigorbit-0.2.5-py3-none-any.whl (24.0 kB view details)

Uploaded Python 3

File details

Details for the file sigorbit-0.2.5.tar.gz.

File metadata

  • Download URL: sigorbit-0.2.5.tar.gz
  • Upload date:
  • Size: 2.4 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for sigorbit-0.2.5.tar.gz
Algorithm Hash digest
SHA256 5d919d17ae5a90ffb1d4fdc02f39924967d7bf055aca175f50d10af23d318b7f
MD5 a1301a9526a03748ad569759b12e6786
BLAKE2b-256 272cd72a77483b845b8f46bdb274d8fd86e2bc4236e03a3320fa32a528379879

See more details on using hashes here.

Provenance

The following attestation bundles were made for sigorbit-0.2.5.tar.gz:

Publisher: publish.yml on jordi-murgo/sigorbit

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

File details

Details for the file sigorbit-0.2.5-py3-none-any.whl.

File metadata

  • Download URL: sigorbit-0.2.5-py3-none-any.whl
  • Upload date:
  • Size: 24.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for sigorbit-0.2.5-py3-none-any.whl
Algorithm Hash digest
SHA256 b908bf3fc2140120e7cbcb3c99161ec018d832ef9f09356da42b8e5cf6a19450
MD5 648a7c7cef46d9c69325033cdb18bc16
BLAKE2b-256 1da7a9303c7628dc407f22c97e3c10dcfe8c9ea978ded8bcbd0c12d77a3ae2f6

See more details on using hashes here.

Provenance

The following attestation bundles were made for sigorbit-0.2.5-py3-none-any.whl:

Publisher: publish.yml on jordi-murgo/sigorbit

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

Release history Release notifications | RSS feed

This release

0.2.5 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page