当前位置: 首页 > news >正文

yolov11 obb数据集准备说明

文章目录

  • 一. OBB说明
  • 二. yolo obb数据标签定义
  • 三. yolo obb检测结果输出
  • 四. anylabeling中的多边形标签转换yolo obb标签方法
    • (一) 通过x-anylabeling进行转换
    • (二) 通过脚本文件进行转换

一. OBB说明

OBB 全称Oriented Bounding Box(定向旋转边界框),在传统水平框(x,y,w,h)基础上增加旋转角度 θ,用 5 个参数精准贴合任意倾斜角度的目标,避免水平框框入大量背景、密集目标 IoU 失真漏检的问题。

方式 1:OpenCV 定义(最常用,DOTA、YOLOv8/11 OBB 默认)

  • 角度范围:θ ∈ [-90°, 0°]
  • 规则:以矩形最短底边为基准,从 X 轴水平方向顺时针旋转到该底边的角度;w、h 不强制区分长边短边,可互换。

方式 2:长边定义法(YOLO 系列主流)

  • 规则:固定w 为矩形长边、h 为短边,θ 是长边与 X 轴正方向逆时针夹角,彻底避免角度周期性歧义。

二. yolo obb数据标签定义

由于一个 OBB 及其 180° 旋转是相同的,因此旋转定义为模 180°,且该框没有方向性。在内部,角度以弧度存储并归一化为 [-π/4, 3π/4) ([-45°, 135°)),边框宽度 w 被视为较长的一边,角度定义为从正 x 轴到 w 方向的顺时针角度。[0°, 90°) 形式是正则化的 DOTA 风格惯例,在训练或推理过程中并不适用。

  • YOLO OBB 格式通过其四个角点的坐标来指定边框,这些坐标按照此结构在 0 到 1 之间进行归一化
    class_index x1 y1 x2 y2 x3 y3 x4 y4
  • 在内部,YOLO 以 xywhr 格式处理损失和输出,该格式表示 边界框 的中心点 (xy)、宽度、高度和旋转角度

三. yolo obb检测结果输出

旋转边框检测为每张图像返回一个 Results 对象。主要的预测字段是 result.obb,其中包含每个检测到物体的旋转边框、类别 ID 和置信度分数。

属性类型形状描述
result.obbOBB(N)旋转边界框。
result.obb.datatorch.float32(N,7/8)包含置信度/类别的原始旋转框。
result.obb.xywhrtorch.float32(N,5)xywhr旋转框。
result.obb.xyxyxyxytorch.float32(N,4,2)四个角点。
result.obb.conftorch.float32(N,)置信度得分。

四. anylabeling中的多边形标签转换yolo obb标签方法

(一) 通过x-anylabeling进行转换

  1. 将多边形标签转换为有向边界框
  2. 将有向边界框转为yolo obb标签

(二) 通过脚本文件进行转换

importosimportjsonimportrandomimportshutilfrompathlibimportPathfromPILimportImagedefget_image_size(img_path):"""获取图片宽高"""withImage.open(img_path)asimg:returnimg.width,img.heightdefanylabeling_json_to_obb_txt(json_path,img_w,img_h,save_txt_path):""" AnyLabeling JSON 转 YOLO OBB 标签txt OBB格式:class_id x1 y1 x2 y2 x3 y3 x4 y4 (全部归一化0~1) """withopen(json_path,"r",encoding="utf-8")asf:data=json.load(f)lines=[]forshapeindata.get("shapes",[]):label=shape.get("label")iflabelnotinCLASS_MAP:print(f"警告:未定义类别{label},跳过该目标")continuecls_id=CLASS_MAP[label]points=shape.get("points")iflen(points)!=4:print(f"警告:非4点旋转框,跳过{json_path}中的该标注")continue# 4个点归一化norm_points=[]forx,yinpoints:nx=x/img_w ny=y/img_h norm_points.append(f"{nx:.6f}{ny:.6f}")line=f"{cls_id}{' '.join(norm_points)}"lines.append(line)# 写入标签文件withopen(save_txt_path,"w",encoding="utf-8")asf:f.write("\n".join(lines))definit_folder():"""初始化输出文件夹结构"""img_dir=Path(OUTPUT_DIR)/"images"label_dir=Path(OUTPUT_DIR)/"labels"forsplitin["train","val","test"]:(img_dir/split).mkdir(parents=True,exist_ok=True)(label_dir/split).mkdir(parents=True,exist_ok=True)defgenerate_yaml():"""生成YOLO数据集yaml配置文件"""yaml_path=Path(OUTPUT_DIR)/"dataset.yaml"class_names=[kfork,vinsorted(CLASS_MAP.items(),key=lambdax:x[1])]yaml_content=f"""path:{os.path.abspath(OUTPUT_DIR)}train: images/train val: images/val test: images/test names:{chr(10).join([f"{i}:{name}"fori,nameinenumerate(class_names)])}"""withopen(yaml_path,"w",encoding="utf-8")asf:f.write(yaml_content)print(f"✅ 数据集配置文件已生成:{yaml_path}")defcollect_all_samples():"""递归遍历指定子文件夹,收集(图片,json)配对样本"""samples=[]root_path=Path(ROOT_DIR)# 如果指定了目标子文件夹,只遍历这些文件夹ifTARGET_SUB_FOLDERS:forsub_nameinTARGET_SUB_FOLDERS:sub_dir=root_path/sub_nameifnotsub_dir.exists():print(f"⚠️ 子文件夹{sub_name}不存在,跳过")continue# 在当前子文件夹下递归查找所有jsonforjson_fileinsub_dir.rglob("*.json"):img_path=NoneforsuffixinIMG_SUFFIX:temp_img=json_file.with_suffix(suffix)iftemp_img.exists():img_path=temp_imgbreakifimg_pathisNone:print(f"⚠️ 未找到{json_file.name}对应的图片,跳过")continuesamples.append((img_path,json_file))else:# 未指定子文件夹,遍历根目录下所有子文件夹forjson_fileinroot_path.rglob("*.json"):img_path=NoneforsuffixinIMG_SUFFIX:temp_img=json_file.with_suffix(suffix)iftemp_img.exists():img_path=temp_imgbreakifimg_pathisNone:print(f"⚠️ 未找到{json_file.name}对应的图片,跳过")continuesamples.append((img_path,json_file))print(f"📦 总共收集到有效样本数量:{len(samples)}")returnsamplesdefsplit_dataset(samples):"""按8:1:1随机划分数据集"""random.shuffle(samples)total=len(samples)train_num=int(total*TRAIN_RATIO)val_num=int(total*VAL_RATIO)train_samples=samples[:train_num]val_samples=samples[train_num:train_num+val_num]test_samples=samples[train_num+val_num:]print(f"📊 划分结果:")print(f"训练集:{len(train_samples)}张")print(f"验证集:{len(val_samples)}张")print(f"测试集:{len(test_samples)}张")return{"train":train_samples,"val":val_samples,"test":test_samples}defcopy_and_convert(split_name,sample_list):"""复制图片+转换json到obb标签并保存到对应数据集文件夹"""img_out_base=Path(OUTPUT_DIR)/"images"/split_name label_out_base=Path(OUTPUT_DIR)/"labels"/split_nameforimg_path,json_pathinsample_list:img_w,img_h=get_image_size(img_path)stem=img_path.stem# 复制图片dst_img=img_out_base/img_path.name shutil.copy2(img_path,dst_img)# 转换并保存obb标签dst_label=label_out_base/f"{stem}.txt"anylabeling_json_to_obb_txt(json_path,img_w,img_h,dst_label)defmain():random.seed(RANDOM_SEED)ifnotPath(ROOT_DIR).exists():print(f"❌ 错误:根文件夹不存在{ROOT_DIR}")returninit_folder()all_samples=collect_all_samples()ifnotall_samples:print("❌ 未找到任何图片+json配对样本,程序退出")returnsplit_data=split_dataset(all_samples)forsplit,samplesinsplit_data.items():copy_and_convert(split,samples)print(f"✅{split}集处理完成")generate_yaml()print("\n🎉 全部任务执行完成!")print(f"数据集输出目录:{os.path.abspath(OUTPUT_DIR)}")if__name__=="__main__":# ===================== 所有配置参数放在此处:if __name__下、main()调用前 =====================ROOT_DIR=r"D:\\test\\"OUTPUT_DIR=r"D:\\train\\"TRAIN_RATIO=0.8VAL_RATIO=0.1TEST_RATIO=0.1RANDOM_SEED=42IMG_SUFFIX=(".jpg",".jpeg",".png",".bmp")# 新增:需要处理的子文件夹列表,为空列表则处理全部子文件夹# 示例:TARGET_SUB_FOLDERS = ["folder1", "folder2", "folder3"]TARGET_SUB_FOLDERS=[]# 类别映射:标签名:类别ID(从0开始)CLASS_MAP={"rect3_1":0,}# =====================================================================================main()
http://www.jsqmd.com/news/1036911/

相关文章:

  • 东营换轮胎怎么选?本地市场盘点、轮胎选购避坑+门店筛选完整指南 - 国麟测评
  • Python 练习题讲解 3 · 字符串
  • 2026年无锡名表回收实测:添加收高端手表回收变现首选门店 - 薛定谔的梨花猫
  • 石门县黄金回收避坑指南! - 衡金阁
  • 换季整理翻出旧翡翠?成都回收攻略来了,禹竞名奢汇报价最实在 - 奢品小当家
  • 2026 年 6 月最新|涂胶设备实测排名:汽车涂胶设备 / 3C涂胶设备 / 新能源涂胶设备靠谱厂家权威榜单汇总 - 商业新知
  • 证件照处理全流程:从像素尺寸到抠图技巧,掌握合规制作核心方法
  • Element Plus 组件库 + 美化页面
  • 2026济南格拉芙首饰回收横评:七家里谁最懂“钻石之王”?添价收用专业说话 - 薛定谔的梨花猫
  • 上海澳洲留学社科类文书中介:精选案例客观评估 - 虚拟星辰
  • 微信支付AI卡,充多少花多少
  • 星盘接口开发文档:年运语料接口指南
  • 英雄联盟Akari助手:从青铜到王者的终极游戏效率提升指南
  • 记一次 .NET 某卷绕信息追溯系统 内存暴涨分析
  • 深入解析CodeWarrior DSP56800x项目向导:从配置原理到实战应用
  • 2026网站设计公司有哪些?高端网站建设公司哪家好?权威榜单出炉 - FaiscoJeff
  • 2026海淀卡地亚回收别乱选!多家探店实测避坑 - 逸程
  • 怕结算拖延、隐形扣费?沈阳合规回收机构推荐 - 开心测评
  • 2026 成都高端奢侈手表回收 理查德米勒江诗丹顿实测门店 - 开心测评
  • 2026常州个人黄金变现干货,全程无隐形消费交易无忧 - 奢侈品回收测评
  • 2026佛山万国手表回收实测排名:7家本地机构横向测评,闲置名表变现避坑指南 - 薛定谔的梨花猫
  • 如何快速掌握机器学习降维算法:从PCA到t-SNE实战完整指南
  • NSO集团的安全漏洞源于一张印有品牌标识的垫子上放着一个杯子的照片
  • 手机拍照算热量:食物图像分割与体积重建技术实践
  • 国内热重分析仪十大厂家综合实力排行盘点 - 起跑123
  • 国产化紫外成像替代背景下,Knight UV系列相机半导体研发平台使用心得
  • 【教程】 Reset Release IP 的介绍与使用
  • ZooKeeper Java API实战:从核心概念到生产级避坑指南
  • 结婚启事登报怎么办理?线下线上全流程办理指南 - 叮咚办真方便
  • 2026年小批量电路板定制深度选型指南:如何匹配适合的工厂方案? - 热点速览