rightwayup
Python package and CLI for RightWayUp, a neural network model by ORTUS AI that estimates how far an image is rotated from upright, over the full 360° at 1° resolution, and abstains when an image has no clear "up".
pip install rightwayup
rightwayup predict frame.jpg # angle, confidence, abstain flag
rightwayup fix photo.jpg --snap 90 --out upright/ # writes the upright image; leaves it alone if it abstains
rightwayup predict frames/*.jpg --tier nano --batch --batch-size 64 --json
from rightwayup import Orienter
o = Orienter(tier="max") # weights download from Hugging Face on first use
r = o.predict("frame.jpg") # r.angle_cw, r.confidence, r.abstain, r.routed
upright = o.correct("photo.jpg", snap=90)
results = Orienter(tier="fast", batch=True).predict_batch(["a.jpg", "b.jpg"], batch_size=64)
angle_cw is the clockwise rotation of the image content; turning the image counter-clockwise by angle_cw makes
it upright (r.correction_ccw). abstain is true when the image has no reliable "up" (the angle is still
reported); correct() then returns the image unchanged unless force=True.
Tiers
| Tier | Model | Input | Laptop CPU, one image¹ | Notes |
|---|---|---|---|---|
pico |
ViT-S/14, fill-drop | 70 px | 3.21 ms | smallest and least accurate; development numbers only |
nano |
ViT-S/14, fill-drop | 112 px | 7.73 ms | camera fleets and edge devices |
fast |
ViT-S/14, fill-drop | 224 px | 29.7 ms | quick general default |
balanced |
Fast → Max for ~10% | 224 → 280 px | 62.2 ms (derived) | cascade |
pro |
Fast → Max for ~20% | 224 → 280 px | 94.8 ms (derived) | cascade |
max (default) |
ViT-L/14 on every image | 280 px | 326 ms | most accurate |
¹ Intel Core i7-1260P, ONNX Runtime INT8, 4 threads, batch 1. Cascade shares are those of the calibration data; on photos and thermal images Balanced and Pro route more (10–33% / 30–80% on the sealed test sets). Accuracy tables, GPU and Apple timings: model card.
Options
| Argument (Python / CLI) | Values |
|---|---|
tier / --tier |
pico, nano, fast, balanced, pro, max (default) |
device / --device |
auto (CUDA if available, else CPU), cpu, cuda, tensorrt, coreml |
precision / --precision |
auto (INT8 on CPU, FP16 on GPU), fp32, fp16, int8 |
batch / --batch |
False (default): one-image files, fastest for single images; True: batch-capable files for predict_batch throughput. Same answers. |
abstain / --abstain |
standard (about 90% of calibration images answered), strict (at most 1% wrong on calibration images, never looser than standard), off |
model_dir / --model-dir |
folder with the ONNX files (or set RIGHTWAYUP_MODEL_DIR); default: download from the Hugging Face Hub |
threads |
ONNX Runtime intra-op threads |
predict_batch(images, batch_size=16) accepts file paths, PIL images or NumPy arrays. rightwayup fix also takes
--min-angle (treat smaller corrections as upright, default 1.0°) and --force; it exits with status 2 if it left
any image unchanged because the model abstained.
Abstain and route thresholds were fixed on calibration data only, separately for each file format (FP32, FP16, INT8, and the batch-capable files); the package applies the thresholds of the format it loads.
Files and formats
The weights repository ortusai/rightwayup holds, for every model, ONNX
FP32 / FP16 / INT8 files (pico-s70-*, nano-s112-*, fast-s224-*, max-l280-*), batch-capable ONNX files for
Pico, Nano and Fast (*-batch-*), a full-token Pico build for ONNX Runtime Web (pico-s70-web-*), and Core ML
packages for Apple silicon (coreml/*-b1.mlpackage, *-b16.mlpackage). The package uses the ONNX files; tiers.json
in the weights repository documents the preprocessing and every threshold for use without Python.
Known limitations
- Thermal images: accuracy on unseen thermal cameras varies widely and confidence is not reliable there; use
maxand do not rely on the abstain flag alone. - Clean photos with small tiers:
nanoandfastare less accurate than Woehrer 2026 on clean everyday photos; useproormaxfor photo apps. - Pico is weak on strongly rolled CCTV (41.1% on one held-out camera rolled about 36°).
- Rotation corners: images turned by software get flat-colour corners; black, white and grey corners are handled
by every tier, but a sky-blue fill can flip
nanoby 180°. - No "up": straight-down aerial images and featureless close-ups have no defined "up"; use the abstain flag.
- Max is not the fast tier: per image it is slower than Woehrer 2026 on CPUs and most GPUs.
No telemetry: the only network calls go to Hugging Face to fetch the weight files (and check cached copies). Pass
model_dir= or set HF_HUB_OFFLINE=1 to run fully offline.
- Write-up and video: https://cheqit.ortusai.io/resources/rightwayup/
- Code, results, technical report and data provenance: https://github.com/ortusaitech/rightwayup
- Weights (all six tiers): https://huggingface.co/ortusai/rightwayup
Apache-2.0. Built by ORTUS AI, the team behind CHEQIT camera-health monitoring.
Metadata
Release files for rightwayup 1.0.0
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 | Actions |
|---|---|---|---|---|
| rightwayup-1.0.0.tar.gz | 19.2 kB | Without provenance | Details for rightwayup-1.0.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| rightwayup-1.0.0-py3-none-any.whl | Python 3 | none | any | Details for rightwayup-1.0.0-py3-none-any.whl |
Total release size: 35.5 kB
Release files / rightwayup-1.0.0.tar.gz
| Download URL | rightwayup-1.0.0.tar.gz |
|---|---|
| Size | 19.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
25b73cb34d7dc68d241934604928d2e20515e3e9e0fa8537e80334d51fa1b534
|
|
BLAKE2b-256 checksum How to use checksums |
aa86088bd25f44fb971ed8ed20c717a5383ec48dff03ec5aabc025bfd2651722
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|
Release files / rightwayup-1.0.0-py3-none-any.whl
| Download URL | rightwayup-1.0.0-py3-none-any.whl |
|---|---|
| Size | 16.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
694aa8b27f6dd229ab811eecb1962af0e1fb508c3c23f11609a6adc00ab657db
|
|
BLAKE2b-256 checksum How to use checksums |
67f4b79294c988146c1deca3ee0ee8fa7c4b9f90b0adac165c5c2d69d06c00cc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|
Security for rightwayup 1.0.0
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.
To learn more about protecting yourself from malicious actors, visit our package security documentation.