What is a bounding box, and how is it mathematically represented?
A bounding box is the axis-aligned rectangle a detector draws around an object. It's represented by four numbers, in one of two common formats: corner form (x1, y1, x2, y2) or center form (cx, cy, width, height). YOLO uses center form, usually normalized to 0-1 so the values don't depend on image size.
Four numbers fully describe an axis-aligned rectangle, and there are two conventions for which four:
- Corner / xyxy: top-left (x1, y1) and bottom-right (x2, y2). Easy to draw and to compute overlap with.
- Center / xywh: center (cx, cy) plus width and height. This is YOLO's native format, and it's normalized by the image size so a box is 0-1 regardless of resolution.
You'll constantly convert between the two. Here's the exact conversion:
def xywh_to_xyxy(cx, cy, w, h, img_w, img_h):
"""Center form (normalized 0-1) -> pixel corners."""
x1 = (cx - w / 2) * img_w
y1 = (cy - h / 2) * img_h
x2 = (cx + w / 2) * img_w
y2 = (cy + h / 2) * img_h
return x1, y1, x2, y2
def xyxy_to_xywh(x1, y1, x2, y2, img_w, img_h):
"""Pixel corners -> center form, normalized 0-1 (YOLO label format)."""
cx = ((x1 + x2) / 2) / img_w
cy = ((y1 + y2) / 2) / img_h
w = (x2 - x1) / img_w
h = (y2 - y1) / img_h
return cx, cy, w, hA YOLO label file stores one line per object as 'class cx cy w h', all normalized. Getting this format wrong (pixels instead of 0-1, or corners instead of center) is a classic reason a custom training run produces nonsense.
Related questions
Stuck on this in a real project?
Book a free call and I’ll give you a straight answer on your specific case.
Book a consultation