roLabelImg标注数据转YOLOv8-OBB全流程:从XML解析到模型训练实战
当你用roLabelImg标注完旋转目标后,看着满屏的XML文件却不知如何喂给YOLOv8-OBB训练时,我完全理解那种抓狂的感觉。去年做遥感图像检测项目时,我花了整整三天才摸清这套转换流程。现在,我把所有踩过的坑和验证过的解决方案打包成这份指南,让你半小时内走完我三天的探索之路。
1. 理解数据格式的演变路径
roLabelImg生成的XML文件就像一本加密日记,YOLOv8-OBB根本读不懂。要让它们对话,需要经过两次"翻译":
-
roLabelImg XML → DOTA格式XML
将旋转框的中心点坐标(cx,cy)、宽高(w,h)和旋转角度(angle)转换为四个角点坐标(x1,y1,x2,y2,x3,y3,x4,y4) -
DOTA XML → DOTA TXT
将XML结构扁平化为每行一个对象的文本格式,包含四个角点+类别 -
DOTA TXT → YOLOv8-OBB TXT
最终转换为归一化的多边形坐标+类别索引格式
# 典型YOLOv8-OBB标签格式示例
# 类别索引 x1 y1 x2 y2 x3 y3 x4 y4
1 0.512 0.634 0.723 0.634 0.723 0.812 0.512 0.812
关键点:YOLOv8-OBB要求坐标是归一化的多边形顶点(顺时针或逆时针顺序),而非旋转矩形参数
2. 从roLabelImg XML到DOTA格式的完整转换
下面这个增强版脚本解决了原始方案中的三个典型问题:负坐标处理、角度方向统一和类别映射混乱。新建convert_roLabelImg_to_dota.py:
import os
import xml.etree.ElementTree as ET
import math
from tqdm import tqdm
def validate_coordinates(coords, img_width, img_height):
"""确保坐标不越界且有效"""
x0, y0, x1, y1, x2, y2, x3, y3 = coords
coords = [
max(0, min(x0, img_width)),
max(0, min(y0, img_height)),
max(0, min(x1, img_width)),
max(0, min(y1, img_height)),
max(0, min(x2, img_width)),
max(0, min(y2, img_height)),
max(0, min(x3, img_width)),
max(0, min(y3, img_height))
]
return coords
def rotatePoint(xc, yc, xp, yp, theta):
"""考虑roLabelImg角度定义(顺时针为正)"""
xoff = xp - xc
yoff = yp - yc
cosTheta = math.cos(theta)
sinTheta = math.sin(theta)
pResx = cosTheta * xoff - sinTheta * yoff # 注意符号调整
pResy = sinTheta * xoff + cosTheta * yoff
return xc




778

被折叠的 条评论
为什么被折叠?



