Skip to main content

annofmt

Immutable geometry types and utilities for computer-vision annotations. Zero dependencies, fully typed, Python 3.12+.

Install

uv add annofmt
# or
pip install annofmt
# or straight from the repo
uv add git+https://github.com/peachfuzz11/annofmt.git

Quickstart

from annofmt.annotation import Annotation
from annofmt.geometry.bbox import BBox
from annofmt.geometry.rbbox import RBBox
from annofmt.geometry.segm import Segm
from annofmt.tag import Tag

bbox = BBox(x=30, y=50, w=40, h=20)   # center + extent
bbox.x_min                            # derived corner values
bbox.to_xywh()

rotated = RBBox.from_degrees(x=30, y=50, w=40, h=20, degrees=25)   # same xywh, plus `a`
rotated.corners()
rotated.to_bbox()                     # lossy enclosing axis-aligned box

segm = Segm.from_polygon([(0, 0), (9, 0), (9, 9), (5, 5), (0, 9)])
segm.indices                          # integer pixel-index rings
segm.to_rle(height=10, width=10)      # COCO-style column-major run-length counts
Segm.from_rle(runs, 10, 10)           # ...and back to rings

annotation = Annotation(geometry=segm).add_tag(Tag("person", score=0.98))
annotation.bbox                       # works for every geometry type

All types are immutable: operations return new instances and never mutate the receiver.

Geometry types

BBox is the base class; storage is always center-plus-extent (x, y, w, h).

Type Extra storage Description
BBox — axis-aligned box; corners are derived properties
RBBox a adds rotation in radians; corners become the enclosing box
Segm indices polygon rings over integer pixel indices; x/y/w/h hold the enclosing box

Conversion matrix

From \ To BBox RBBox Segm
BBox — unavailable (rotation cannot be invented) exact rectangle ring (Segm.from_bbox)
RBBox enclosing box (to_bbox, lossy) — corner ring (Segm.from_rbbox, rounded to lattice)
Segm enclosing box (to_bbox, lossy) minimum-area rect (as_rbbox, lossy) —

IoU is defined only between two geometries of the same type and raises TypeError otherwise. Convert explicitly first when a cross-type comparison is really wanted (e.g. compare every geometry's to_bbox()).

Conventions

  • Angles: stored in radians, canonically wrapped to [-pi, pi). Build with from_degrees, read via .angle_deg / .angle_rad.
  • Indices: Segm coordinates are integer pixel indices; fractional input is rejected. Vertices sit on the integer lattice.
  • Rasterization: pixels are unit squares centered at (col + 0.5, row + 0.5); rings combine under an even-odd rule, so nested rings act as holes regardless of winding order.
  • RLE: COCO-style column-major counts starting with zeros; to_rle(height, width) / from_rle(runs, height, width) round-trip.
  • Immutability: every operation yields a new instance.

Metadata

Release files for annofmt 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for annofmt 0.1.0
File Size Uploaded
annofmt-0.1.0.tar.gz 30.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for annofmt 0.1.0
File Interpreter ABI Platform
annofmt-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 36.2 kB

Release files / annofmt-0.1.0.tar.gz

Download URL annofmt-0.1.0.tar.gz
Size 30.5 kB
Tags Source
SHA-256 checksum
How to use checksums
5b1a9192262ca47a0a003c089b4159e4b96c7bb5d3ee6b607c47ccb52fcd0e5f
BLAKE2b-256 checksum
How to use checksums
17ef51ee88cc9acc0717cc913b604f232bf72ca6f332e7ec074ff18aa6b9615f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.6 {"installer":{"name":"uv","version":"0.12.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / annofmt-0.1.0-py3-none-any.whl

Download URL annofmt-0.1.0-py3-none-any.whl
Size 5.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
41e2ef018db104d29c05c4d112719cd3b3ae20a460d7c45e46477bba5c740333
BLAKE2b-256 checksum
How to use checksums
c03baecac53925f93fff3a9f6fc272d9a345b8cf63a197fefe156191d7f0fce3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.6 {"installer":{"name":"uv","version":"0.12.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

0.2.0

2 release files

This release

0.1.0 This release

2 release 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