bounding box conversion
YOLO format
computer vision
object detection
coordinate transformation

How to convert bounding box x1, y1, x2, y2 to YOLO Style X, Y, W, H

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Object-detection annotations often arrive as corner coordinates x1, y1, x2, y2, but YOLO training files use normalized center coordinates x, y, w, h. The math is straightforward, yet a small misunderstanding about image size, coordinate order, or normalization can ruin an entire dataset.

Understand the Two Formats First

The x1, y1, x2, y2 format stores the top-left and bottom-right corners of the box. YOLO stores the same box differently:

  • 'x is the center x-coordinate divided by image width'
  • 'y is the center y-coordinate divided by image height'
  • 'w is the box width divided by image width'
  • 'h is the box height divided by image height'

That means the target values are usually between 0 and 1. If your output contains large pixel-sized numbers, the labels are probably not normalized yet.

Apply the Conversion Formula

Start by computing the width, height, and center in pixel space:

  • 'box_w = x2 - x1'
  • 'box_h = y2 - y1'
  • 'center_x = x1 + box_w / 2'
  • 'center_y = y1 + box_h / 2'

Then normalize by the image dimensions:

  • 'x = center_x / img_w'
  • 'y = center_y / img_h'
  • 'w = box_w / img_w'
  • 'h = box_h / img_h'

Those are the only calculations required. The rest of the work is validation.

Convert in Python

This helper converts one box and checks the most common failure conditions:

python
1def xyxy_to_yolo(x1, y1, x2, y2, img_w, img_h):
2    if img_w <= 0 or img_h <= 0:
3        raise ValueError("image dimensions must be positive")
4
5    if x2 <= x1 or y2 <= y1:
6        raise ValueError("invalid box geometry")
7
8    box_w = x2 - x1
9    box_h = y2 - y1
10    center_x = x1 + box_w / 2.0
11    center_y = y1 + box_h / 2.0
12
13    x = center_x / img_w
14    y = center_y / img_h
15    w = box_w / img_w
16    h = box_h / img_h
17    return x, y, w, h
18
19
20print(xyxy_to_yolo(50, 100, 200, 300, 500, 400))

For this example, the result is 0.25, 0.5, 0.3, 0.5. That means the box center sits at one quarter of the image width and half of the image height.

Verify by Converting Back

A fast way to catch bad assumptions is to convert back to the original format and compare the result:

python
1def yolo_to_xyxy(x, y, w, h, img_w, img_h):
2    box_w = w * img_w
3    box_h = h * img_h
4    center_x = x * img_w
5    center_y = y * img_h
6
7    x1 = center_x - box_w / 2.0
8    y1 = center_y - box_h / 2.0
9    x2 = center_x + box_w / 2.0
10    y2 = center_y + box_h / 2.0
11    return x1, y1, x2, y2
12
13
14original = (50, 100, 200, 300)
15converted = xyxy_to_yolo(*original, 500, 400)
16restored = yolo_to_xyxy(*converted, 500, 400)
17
18print(tuple(round(v, 2) for v in restored))

If the restored values are far from the original, the issue is usually width-versus-height normalization or a mismatched coordinate convention.

Prepare Output for YOLO Label Files

YOLO label files usually store one object per line as:

class_id x y w h

You can format one line like this:

python
1def to_yolo_label_line(class_id, x, y, w, h):
2    return f"{class_id} {x:.6f} {y:.6f} {w:.6f} {h:.6f}"
3
4
5x, y, w, h = xyxy_to_yolo(50, 100, 200, 300, 500, 400)
6print(to_yolo_label_line(2, x, y, w, h))

Using fixed decimal precision helps keep generated files consistent across runs.

Common Pitfalls

The most frequent mistake is forgetting to normalize and writing raw pixel coordinates into a YOLO label file. Another common problem is dividing x-values by image height or y-values by image width, which quietly distorts every box.

You also need to know whether the source tool treats x2, y2 as inclusive or exclusive. Different annotation systems do not always agree, and that can create off-by-one box sizes.

Out-of-bounds annotations are another source of trouble. If a box extends beyond the image edges, clamp or reject it before conversion, then validate that width and height are still positive.

Finally, always spot-check converted labels visually on a few images. A quick overlay can catch a dataset-wide bug much faster than waiting for a poor training run.

Summary

  • Convert x1, y1, x2, y2 to YOLO by computing center coordinates and box size first.
  • Normalize the center and size by image width and height.
  • Validate image dimensions and reject boxes with non-positive width or height.
  • Use a reverse conversion or visual overlay to verify the labels.
  • Write YOLO labels with the expected class_id x y w h format and consistent precision.

Course illustration
Course illustration

All Rights Reserved.