Skip to content
AI360Xpert
Beta

Bounding Shapes

Wrap every contour in the cheapest box, tightest rotated box, or smallest circle that holds it. Detectors speak boxes, so this is the translation layer.

A 100 by 20 bar at 30 degrees fills a 96.6 by 67.3 upright box of 6,503 pixels but only 2,000 pixels rotated
A 100 by 20 bar at 30 degrees fills a 96.6 by 67.3 upright box of 6,503 pixels but only 2,000 pixels rotated

Why Does This Exist?

Contours are clouds of points, but trackers, detectors, and robot grippers want four numbers: position plus size. Bounding shapes compress any loop into that contract, trading tightness for cost across three options. Every detector output you have ever seen, including modern object detection boxes, descends from the upright variant.

This page covers the upright box, the rotated minimum-area rectangle, and the enclosing circle, with the angle convention that trips up every beginner. Rotation-proof identity rather than fitted geometry is shape matching.

Think of It Like This

Shipping a ladder

Ship a ladder in an axis-aligned crate and you pay for a box nearly as wide as the ladder is long, mostly air. Rotate the crate to lie along the ladder and the box shrinks to the ladder's true footprint. The diagonal crate is the minimum-area rectangle: same ladder, far less air, one extra measurement (the angle).

It stops holding for round cargo. A beach ball ships best in a cylinder, not any rectangle, the same way circular parts want the minimum enclosing circle. Box-shaped answers fit box-shaped questions only.

How It Actually Works

Three fits, three prices

The upright box takes min and max of xx and yy: two passes, four numbers, always axis-aligned. The minimum-area rectangle rotates with the shape, returning center, width, height, and angle; it is the tightest rectangle possible. The minimum enclosing circle returns center and radius via an iterative expansion, and suits round parts where any rectangle wastes the corners.

The rotated-rectangle payoff, in numbers

Take a 100×20100 \times 20 bar rotated 3030 degrees. Its upright box spans 100cos⁡30°+20sin⁡30°=86.6+10=96.6100 \cos 30° + 20 \sin 30° = 86.6 + 10 = 96.6 wide and 100sin⁡30°+20cos⁡30°=50+17.3=67.3100 \sin 30° + 20 \cos 30° = 50 + 17.3 = 67.3 tall, an area of about 6,5036{,}503 against the bar's true 2,0002{,}000. The minimum-area rectangle recovers the true 100×20100 \times 20 and area 2,0002{,}000, over three times tighter. That gap is pure air billed as object, and on a conveyor it decides whether neighbouring parts merge into one detection.

The angle convention trap

OpenCV reports the rotated angle in [−90°,0°)[-90°, 0°) with width and height swapping roles as the box crosses −45°-45° in some versions, so the "width" of an upright bar reads as height plus a −90°-90° angle. Read the angle together with both side lengths, never alone, and normalize to a center-plus-long-axis format before comparing across frames.

Code

Upright versus rotated extents for the fixture bar:

import math
w, h, deg = 100.0, 20.0, 30.0t = math.radians(deg)up_w = w * math.cos(t) + h * math.sin(t)up_h = w * math.sin(t) + h * math.cos(t)print(f"upright {up_w:.1f} x {up_h:.1f} area {up_w * up_h:.0f}, rotated area {w * h:.0f}")# -> upright 96.6 x 67.3 area 6503, rotated area 2000

The upright box wastes 4,5034{,}503 square pixels of air; the rotated fit wastes none.

Watch Out For

Comparing raw OpenCV angles across frames

Symptom: a slowly rotating part shows angle jumps of 90°90° with width and height swapping, breaking Kalman filters and orientation plots. The angle convention wraps and swaps sides near square shapes. Convert every detection to an unwrapped long-axis angle in [0°,180°)[0°, 180°) immediately after fitting, and track that instead.

Letting one outlier size the box

Symptom: a single stray contour point stretches the box across half the image, dwarfing the real part. Min and max listen to extremes by definition. Hull or approximate the contour first, or fit to a high percentile of points, before taking extrema.

The Quick Version

  • The upright box is cheapest; the rotated rectangle is tightest; the enclosing circle suits round parts.
  • A 100×20100 \times 20 bar at 30°30° fills a 6,5036{,}503-pixel upright box but only 2,0002{,}000 rotated pixels.
  • OpenCV angles live in [−90°,0°)[-90°, 0°) with width-height swaps, so normalize to long-axis form before tracking.
  • Outliers stretch min-max boxes, so clean the contour before fitting.
  • Boxes answer where and how big; they never answer which shape, which needs matching instead.