Geometry Module¶
The geometry module provides core primitives for working with rotated and oriented bounding boxes.
Overview¶
OrientedDet provides three main geometric primitives:
Polygon- Immutable polygon with validation and geometric operationsQBox- Quadrilateral bounding box (4 corner points)RBox- Rotated bounding box (center, width, height, angle)
Polygon¶
A Polygon is an immutable collection of points that represents a closed shape.
Creating Polygons¶
from oriented_det.geometry import Polygon
# From points
poly = Polygon([(0, 0), (10, 0), (10, 10), (0, 10)])
# Using class method for rectangles
rect = Polygon.rectangle(cx=50, cy=50, width=100, height=80)
Properties¶
area = poly.area # Area of the polygon
centroid = poly.centroid # (cx, cy) tuple
bounds = poly.bounds # (x_min, y_min, x_max, y_max)
is_clockwise = poly.is_clockwise # Orientation check
Operations¶
# Translation
translated = poly.translate(dx=10, dy=20)
# Rotation
rotated = poly.rotate(radians=0.5, origin=(0, 0))
# Ensure orientation
ccw_poly = poly.ensure_orientation(clockwise=False)
RBox (Rotated Bounding Box)¶
An RBox represents a rotated rectangle using center coordinates, dimensions, and angle.
Creating RBoxes¶
from oriented_det.geometry import RBox
from math import radians
# Direct creation
rbox = RBox(cx=100, cy=200, width=50, height=30, angle=radians(45))
# From polygon
rbox = RBox.from_polygon(polygon)
# From QBox
rbox = RBox.from_qbox(qbox)
Properties¶
area = rbox.area # width * height
aspect_ratio = rbox.aspect_ratio # width / height
corners = rbox.corners() # 4 corner points
Conversions¶
QBox (Quadrilateral Box)¶
A QBox represents a quadrilateral using 4 corner points.
Creating QBoxes¶
from oriented_det.geometry import QBox
# From 4 points
qbox = QBox([
(0, 0),
(10, 0),
(10, 10),
(0, 10)
])
Properties¶
center = qbox.center # (cx, cy) tuple
width = qbox.width # Average width
height = qbox.height # Average height
angle = qbox.angle # Orientation angle
edges = qbox.edges # Edge lengths
Transforms¶
The transforms module provides conversion functions between all formats.
Conversions¶
from oriented_det.geometry import transforms
# RBox ↔ QBox
qbox = transforms.rbox_to_qbox(rbox)
rbox = transforms.qbox_to_rbox(qbox)
# RBox ↔ Polygon
polygon = transforms.rbox_to_polygon(rbox)
rbox = transforms.polygon_to_rbox(polygon)
# QBox ↔ Polygon
polygon = transforms.qbox_to_polygon(qbox)
qbox = transforms.polygon_to_qbox(polygon)
Round-trip Conversions¶
All conversions are designed to be lossless (within floating-point precision):
rbox = RBox(100, 200, 50, 30, 0.5)
qbox = transforms.rbox_to_qbox(rbox)
recovered = transforms.qbox_to_rbox(qbox)
assert abs(recovered.cx - rbox.cx) < 1e-6
assert abs(recovered.angle - rbox.angle) < 1e-6
DOTA Polygon Format¶
When working with DOTA dataset annotations, polygons use 8 coordinates:
The corners are ordered sequentially around the polygon perimeter. The loader converts: 1. Polygon → QBox (normalizes point order, ensures counter-clockwise) 2. QBox → RBox (computes center, dimensions, angle)
Best Practices¶
- Use RBox for rotated rectangles - Most efficient representation
- Use Polygon for arbitrary shapes - Most flexible
- Use QBox for quadrilateral conversions - Intermediate format
- Leverage transforms - Centralized conversion logic
- Check orientation - Use
ensure_orientation()when needed
See Also¶
- API Reference - Complete API documentation
- Operations Guide - Using geometry with IoU/NMS