open-mmlab/mmdetection · warning

X2 < X1 value in box. Swap them.

Error message

X2 < X1 value in box. Swap them.

What it means

This warning is emitted by prefilter_boxes inside weighted_boxes_fusion (WBF) in mmdet/models/utils/wbf.py when a detection box has x2 < x1, i.e. the horizontal corners are reversed. WBF requires boxes in strict [x1, y1, x2, y2] format with x1 <= x2; the code auto-corrects the box by swapping the coordinates and continues. It is purely informational — the fusion still proceeds with the corrected box.

Source

Thrown at mmdet/models/utils/wbf.py:165

            print('Error. Length of boxes arrays not equal to '
                  'length of labels array: {} != {}'.format(
                      len(boxes[t]), len(labels[t])))
            exit()

        for j in range(len(boxes[t])):
            score = scores[t][j]
            if score < thr:
                continue
            label = int(labels[t][j])
            box_part = boxes[t][j]
            x1 = float(box_part[0])
            y1 = float(box_part[1])
            x2 = float(box_part[2])
            y2 = float(box_part[3])

            # Box data checks
            if x2 < x1:
                warnings.warn('X2 < X1 value in box. Swap them.')
                x1, x2 = x2, x1
            if y2 < y1:
                warnings.warn('Y2 < Y1 value in box. Swap them.')
                y1, y2 = y2, y1
            if (x2 - x1) * (y2 - y1) == 0.0:
                warnings.warn('Zero area box skipped: {}.'.format(box_part))
                continue

            # [label, score, weight, model index, x1, y1, x2, y2]
            b = [
                int(label),
                float(score) * weights[t], weights[t], t, x1, y1, x2, y2
            ]

            if label not in new_boxes:
                new_boxes[label] = []
            new_boxes[label].append(b)

View on GitHub (pinned to cfd5d3a985)

Solutions

  1. Convert all model outputs to xyxy format before fusion, e.g. mmcv.bbox_xyxy_to_xywh / mmdet.core.bbox_xyxy_to_cxcywh inverse conversions or torchvision.ops.box_convert(..., in_fmt='cxcywh', out_fmt='xyxy').
  2. Sanitize boxes before calling weighted_boxes_fusion: boxes = [np.minimum(b[:, :2], b[:, 2:4]) concatenated with np.maximum(...)] to enforce x1<=x2, y1<=y2.
  3. Check the upstream model's bbox coder (e.g. DeltaXYXYBBoxCoder vs DistancePointBBoxCoder) and test-decoding logic for a sign or axis mix-up.
  4. If the warning is benign and expected, filter it with warnings.filterwarnings('ignore', message='X2 < X1 value in box.*').

Example fix

// before
boxes_list = [model_a_boxes, model_b_boxes]  # model_b emits cxcywh
labels, scores, boxes = weighted_boxes_fusion(boxes_list, labels_list, scores_list)
// after
from torchvision.ops import box_convert
model_b_xyxy = box_convert(torch.tensor(model_b_boxes), in_fmt='cxcywh', out_fmt='xyxy').tolist()
labels, scores, boxes = weighted_boxes_fusion([model_a_boxes, model_b_xyxy], labels_list, scores_list)
Defensive patterns

Strategy: validation

Validate before calling

import numpy as np

def sanitize_xyxy(boxes):
    boxes = np.asarray(boxes, dtype=np.float64)
    x1, y1, x2, y2 = boxes[:, 0], boxes[:, 1], boxes[:, 2], boxes[:, 3]
    boxes[:, 0], boxes[:, 2] = np.minimum(x1, x2), np.maximum(x1, x2)
    boxes[:, 1], boxes[:, 3] = np.minimum(y1, y2), np.maximum(y1, y2)
    return boxes

Type guard

def has_valid_x_order(boxes):
    boxes = np.asarray(boxes)
    return bool((boxes[:, 2] >= boxes[:, 0]).all())

Prevention

When it happens

Trigger: Calling weighted_boxes_fusion() (or prefilter_boxes directly) with a boxes list where some entry has box[2] < box[0]. Typical causes: a model that outputs corners in reverse order, boxes converted from cx/cy/w/h with a sign mistake, or preprocessing that flips/normalizes coordinates incorrectly.

Common situations: Fusing detections from heterogeneous models (some output xyxy, others xywh or cxcywh without conversion); using TTA or ensemble pipelines where one detector's head produces reversed x coordinates; boxes in normalized [0,1] vs pixel coordinates mixed together.

Related errors


AI-assisted analysis of open-mmlab/mmdetection@cfd5d3a985 (2026-08-27). Data as JSON: /api/errors/41fa5d6e0d9de452. Report an issue: GitHub.