You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何按90°步长旋转YOLO目标检测的边界框?

YOLO标注随图片90/180/270度旋转的坐标计算方法

YOLO的标注是基于原图宽高的归一化值,旋转后图片的宽高可能交换(90/270度时),所以需要先明确坐标变换逻辑,再对应计算新的标注值。

核心变换规则(假设图片顺时针旋转,原图宽W、高H)

先把归一化坐标转成绝对坐标,旋转后再转回新图的归一化坐标:90/270度旋转后新图宽高变为原H、原W,180度时宽高不变。

1. 180度旋转

  • 中心坐标:new_xc = 1 - old_xc,new_yc = 1 - old_yc
  • 宽高:new_w = old_w,new_h = old_h
  • 类别编号不变

2. 90度顺时针旋转

  • 中心坐标:new_xc = old_yc,new_yc = 1 - old_xc
  • 宽高:new_w = old_h,new_h = old_w(旋转后宽高交换)
  • 类别编号不变

3. 270度顺时针旋转(等同于90度逆时针)

  • 中心坐标:new_xc = 1 - old_yc,new_yc = old_xc
  • 宽高:new_w = old_h,new_h = old_w
  • 类别编号不变

Python实现示例

下面的代码可以读取原始标注文件,根据旋转角度生成新的标注内容,可结合图片旋转代码一起使用:

def rotate_yolo_label(old_label_line, angle, img_width, img_height):
    """
    转换单条YOLO标注到旋转后的格式
    :param old_label_line: 原始标注行,格式为 "class xc yc w h"
    :param angle: 旋转角度,仅支持90, 180, 270
    :param img_width: 原始图片宽度
    :param img_height: 原始图片高度
    :return: 旋转后的标注行字符串,角度不合法则返回None
    """
    parts = old_label_line.strip().split()
    if len(parts) != 5:
        return old_label_line  # 跳过格式错误的行
    
    cls = parts[0]
    xc = float(parts[1])
    yc = float(parts[2])
    w = float(parts[3])
    h = float(parts[4])
    
    if angle == 180:
        new_xc = 1 - xc
        new_yc = 1 - yc
        new_w = w
        new_h = h
    elif angle == 90:
        new_xc = yc
        new_yc = 1 - xc
        new_w = h
        new_h = w
    elif angle == 270:
        new_xc = 1 - yc
        new_yc = xc
        new_w = h
        new_h = w
    else:
        return None
    
    # 限制坐标在0-1范围内,避免浮点误差导致越界
    new_xc = max(0.0, min(1.0, new_xc))
    new_yc = max(0.0, min(1.0, new_yc))
    new_w = max(0.0, min(1.0, new_w))
    new_h = max(0.0, min(1.0, new_h))
    
    return f"{cls} {new_xc:.6f} {new_yc:.6f} {new_w:.6f} {new_h:.6f}"

# 批量生成旋转后的标注文件
def generate_rotated_labels(input_label_path, output_label_path, angle, img_w, img_h):
    with open(input_label_path, 'r', encoding='utf-8') as f_in:
        lines = f_in.readlines()
    
    rotated_lines = []
    for line in lines:
        rotated_line = rotate_yolo_label(line, angle, img_w, img_h)
        if rotated_line:
            rotated_lines.append(rotated_line)
    
    with open(output_label_path, 'w', encoding='utf-8') as f_out:
        f_out.write('\n'.join(rotated_lines))

# 调用示例
# generate_rotated_labels("original.txt", "rotated_90.txt", 90, 640, 480)

注意事项

  • 旋转图片时要和标注的旋转角度完全一致(比如都是顺时针90度),否则标注会错位
  • 若你的图片旋转是逆时针方向,可对应调整角度逻辑(比如逆时针90度等同于顺时针270度)

内容的提问来源于stack exchange,提问作者Matthias

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 04:15:26