YOLOv11 实例分割标注转成目标检测框教程(附完整代码)
本文介绍了一种高效的Python脚本方案,可以将实例分割标注数据快速转换为YOLOv11目标检测模型所需的边界框格式。通过自动计算分割多边形的最小外接矩形,实现一键格式转换,避免了手动重标数据的繁琐过程。文章详细讲解了转换原理(三点式流程:读取坐标、计算外接矩形、归一化格式),提供了完整可复用的代码,并给出简单易懂的两步使用说明。这套方案能大幅提升数据预处理效率,特别适合已有分割数据但需要训练检测
当你辛辛苦苦搞了一堆实例分割的标注数据,比如用 LabelMe、CVAT 或者 COCO 格式标了一堆多边形轮廓,结果回头想拿这些数据去训个 YOLOv11 的目标检测模型,发现格式对不上?😭
因为 YOLO 只要边界框(Bounding Box),而你的标注是分割轮廓(Segmentation),这不就尴尬了?
别慌!今天这篇博客就是来救场的!
👉 教你用一段 Python 脚本,一键把实例分割标注转成 YOLOv11 能吃的检测框格式!
全程无痛,代码我都给你写好了,你只需要改个路径,就能跑起来,直接省下几天手动重标的功夫!
🧠 为啥要做这个转换?
先说清楚:实例分割 vs 目标检测,差在哪?
- 实例分割:不仅要框出物体,还要标出它的精确轮廓(一堆点连成的多边形)。
- 目标检测:只需要一个矩形框 + 类别,简单粗暴。
所以,如果你已经有分割数据,但只想做检测任务,没必要重新标一遍!
我们只需要从多边形里“挤”出一个最小外接矩形,再转成 YOLO 的归一化格式,完事儿!
✅ 一句话总结:多边形 → 外接矩形 → YOLO 格式
🔧 转换思路(超简单)
咱们的转换逻辑就三步:
- 读:读取 txt 文件里的 所有坐标点。
- 算:找出这些点的
x_min, x_max, y_min, y_max,得到外接矩形。 - 转:把矩形转成 YOLO 要的格式:
class_id center_x center_y width height(全部归一化到 0~1)。
是不是特别简单?根本不用深度学习,纯数学计算!
💻 完整代码来了!(直接复制可用)
下面这段代码,我亲测好用,支持从 YOLOv11 格式的实例分割标注 直接生成 YOLOv11 目标检测训练所需的检测框标注文件。
你只需要把路径改一下,就能跑!
import os
import glob
import shutil
def convert_segmentation_to_bbox(seg_txt_path, bbox_txt_path):
"""
将实例分割标注转换为目标检测标注(外接矩形)
Args:
seg_txt_path: 输入的分割标注文件路径
bbox_txt_path: 输出的目标检测标注文件路径
"""
with open(seg_txt_path, 'r') as f:
lines = f.readlines()
bbox_lines = []
for line in lines:
parts = line.strip().split()
if len(parts) < 2:
continue
# 第一个值是类别ID
class_id = parts[0]
# 剩余的是分割点的坐标 (归一化的 x1, y1, x2, y2, ...)
points = list(map(float, parts[1:]))
if len(points) < 6: # 至少需要3个点(6个坐标值)才能形成多边形
continue
# 找到所有x坐标和y坐标
x_coords = points[0::2] # 所有x坐标
y_coords = points[1::2] # 所有y坐标
# 计算外接矩形
x_min = min(x_coords)
x_max = max(x_coords)
y_min = min(y_coords)
y_max = max(y_coords)
# 计算中心点坐标和宽高
x_center = (x_min + x_max) / 2
y_center = (y_min + y_max) / 2
width = x_max - x_min
height = y_max - y_min
# 确保坐标在[0,1]范围内
x_center = max(0, min(1, x_center))
y_center = max(0, min(1, y_center))
width = max(0, min(1, width))
height = max(0, min(1, height))
# 格式: class_id x_center y_center width height
bbox_line = f"{class_id} {x_center:.6f} {y_center:.6f} {width:.6f} {height:.6f}\n"
bbox_lines.append(bbox_line)
# 写入新的标注文件
with open(bbox_txt_path, 'w') as f:
f.writelines(bbox_lines)
def copy_image_and_convert_annotation(seg_file, output_folder):
"""
复制图片文件并转换对应的标注文件
Args:
seg_file: 分割标注文件路径
output_folder: 输出文件夹路径
"""
# 获取文件名(不含扩展名)
base_name = os.path.splitext(os.path.basename(seg_file))[0]
# 查找对应的图片文件
img_extensions = ['.jpg', '.jpeg', '.png', '.bmp', '.JPG', '.JPEG', '.PNG', '.BMP']
img_path = None
for ext in img_extensions:
potential_img_path = os.path.join(os.path.dirname(seg_file), base_name + ext)
if os.path.exists(potential_img_path):
img_path = potential_img_path
break
if img_path is None:
print(f"警告: 未找到 {base_name} 对应的图片文件")
return False
try:
# 复制图片文件到输出路径
img_output_path = os.path.join(output_folder, os.path.basename(img_path))
shutil.copy2(img_path, img_output_path)
# 转换标注文件到输出路径
bbox_output_path = os.path.join(output_folder, base_name + ".txt")
convert_segmentation_to_bbox(seg_file, bbox_output_path)
print(f"处理完成: {os.path.basename(seg_file)} -> 图片和标注已保存到输出路径")
return True
except Exception as e:
print(f"错误: 处理 {base_name} 时发生异常: {str(e)}")
return False
def batch_convert_with_output(input_folder, output_folder):
"""
批量转换文件夹中的所有分割标注文件,并复制图片到指定输出路径
Args:
input_folder: 输入文件夹路径(包含图片和标注文件)
output_folder: 输出文件夹路径
"""
# 创建输出文件夹(如果不存在)
if not os.path.exists(output_folder):
os.makedirs(output_folder)
print(f"创建输出文件夹: {output_folder}")
# 查找所有的分割标注文件
seg_files = glob.glob(os.path.join(input_folder, "*.txt"))
converted_count = 0
total_files = len(seg_files)
print(f"找到 {total_files} 个标注文件,开始处理...")
for i, seg_file in enumerate(seg_files):
print(f"处理进度: {i+1}/{total_files}", end='\r')
if copy_image_and_convert_annotation(seg_file, output_folder):
converted_count += 1
print(f"\n\n转换完成!共成功处理了 {converted_count} 个文件。")
print(f"输出路径: {output_folder}")
print(f"包含: {converted_count} 个图片文件和 {converted_count} 个标注文件")
if __name__ == "__main__":
# 输入文件夹路径(包含所有实例分割标注文件和图片的目录)
input_folder = 'path/to/your/dataset'
# 输出文件夹路径
output_folder = 'path/to/your/output'
if not os.path.exists(input_folder):
print("输入文件夹不存在,请检查路径!")
else:
batch_convert_with_output(input_folder, output_folder)
🛠️ 使用方法(两步搞定)
-
修改两个路径
input_folder:你所有的实例分割标注和对应的图片文件路径output_folder:转换后的检测框标注和对应图片的保存路径
-
运行脚本
python labels_segmentation_to_detection.py
运行完,你的 output_folder里就会生成一堆 .txt 文件,同时还有对应的图片,格式长这样:
0 0.456250 0.321875 0.234375 0.187500
1 0.789062 0.654375 0.123438 0.109375
完美适配 YOLOv11 训练!
🎁 总结
已有分割数据 + 一段脚本 = 直接上 YOLO 检测任务
再也不用手动重标了,效率拉满!
如果你也在做 YOLO 相关项目,或者经常处理标注数据,赶紧把这段代码收藏起来,以后遇到类似需求,直接复制粘贴,分分钟搞定!
💬 互动时间
- 你在标注转换时还遇到过哪些坑?
- 有没有人需要 OBB 转换的支持?评论区告诉我,我下次安排!
- 觉得有用的话,点赞 + 收藏 + 关注,三连支持一下!你的支持是我更新的最大动力!
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)