使用场景
需要训练的Box标注数据集中包含了部分分隔标注的数据,需要将分隔标注的数据转化为Box标注
教程内容
1.了解Box标注和分隔标注
2.查找yolo的box标注数据集中存在的分隔标注标签
3.将分隔标注转化为Box标注
1.了解Box标注和分隔标注
Box标注:
也就是方框矩形的标注形式,格式为如下
索引 左上角点x坐标 左上角点y坐标 宽度 高度
比如下方这个Box标注标签内容,可以看到内容为固定的5个内容,也就是对应着上边我说的格式
Box标注的图为如下,可以看到是方框形式的标注
分隔标注:
也就是多边形的标注形式,格式为如下
索引 点位1x坐标 点位1y坐标 点位2x坐标 点位2y坐标 .............................
比如下方这个分隔标注标签内容,可以看到除了索引有8个元素,也就是有4个点位,当然,分隔标注对点位数量没有限制,毕竟是多边形
分隔标注的图为如下,如图可以看到为多边形
2.查找yolo的box标注数据集中存在的分隔标注标签
为了演示,我这里将我的数据集中的某一条Box标注改为了分隔标注格式,如图
先附上查找分隔标注的脚本
import os
def check_labels_for_segmentation(labels_dir):
"""
检查标签目录中的每个标签文件是否包含分割标注格式。
Args:
labels_dir (str): 标签文件所在的目录路径。
Returns:
list: 包含分割标注格式的文件路径。
"""
segmentation_files = [] # 用于存储包含分割标注的文件
for filename in os.listdir(labels_dir):
# 构建完整的标签文件路径
filepath = os.path.join(labels_dir, filename)
if not filepath.endswith('.txt'):
continue # 跳过非文本文件
with open(filepath, 'r') as f:
lines = f.readlines()
for line in lines:
parts = line.strip().split() # 分割每一行
if len(parts) > 5: # 分割标注通常会有多边形点集,字段数大于5
# 检查是否含有多边形点集
try:
floats = [float(x) for x in parts[5:]] # 从第6个字段开始应为多边形点坐标
if len(floats) % 2 == 0: # 检查点集是否为偶数对 (x, y)
segmentation_files.append(filepath)
break # 当前文件已经确定为分割标注格式,无需再检查其余行
except ValueError:
pass # 如果无法转换为浮点数,跳过该行
return segmentation_files
# 使用示例
if __name__ == "__main__":
labels_directory = r"D:\A01PythonProjects3123\labelImg-master\标签文件批量处理\slope.v1i.yolov8\train\labels" # 替换为你的 labels 文件夹路径
segmentation_files = check_labels_for_segmentation(labels_directory)
if segmentation_files:
print("以下文件包含分割标注格式:")
for file in segmentation_files:
print(file)
else:
print("未找到包含分割标注格式的文件。")
在脚本中,我传入了需要检测分隔标注标签的所在目录,也就是数据集的labels目录,执行后结果如下
3.将分隔标注转化为Box标注
如果我们的数据集中只有一条因为失误将box标注做成了分隔标注,手动改还好,要是多了可就不好改了,因此下面我提供批量将分隔标注转化为Box标注的脚本。
import os
def convert_segmentation_to_box(labels_dir):
"""
将分割标注文件转换为框标注文件,并覆盖原文件。
Args:
labels_dir (str): 分割标注文件的目录路径。
Returns:
None
"""
for filename in os.listdir(labels_dir):
input_path = os.path.join(labels_dir, filename)
if not filename.endswith('.txt'):
continue # 跳过非文本文件
with open(input_path, 'r') as infile:
lines = infile.readlines()
with open(input_path, 'w') as outfile:
for line in lines:
parts = line.strip().split()
if len(parts) <= 5:
# 如果不是分割标注格式,则直接写入原内容
outfile.write(line)
continue
class_id = parts[0]
polygon_points = list(map(float, parts[5:]))
x_coords = polygon_points[::2] # 偶数索引为x坐标
y_coords = polygon_points[1::2] # 奇数索引为y坐标
# 计算外接矩形
x_min, x_max = min(x_coords), max(x_coords)
y_min, y_max = min(y_coords), 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
# 转换为框标注格式
box_annotation = f"{class_id} {x_center:.6f} {y_center:.6f} {width:.6f} {height:.6f}\n"
outfile.write(box_annotation)
print(f"转换完成,原标签文件已更新。")
# 使用示例
if __name__ == "__main__":
labels_directory = r"D:\A01PythonProjects3123\labelImg-master\标签文件批量处理\slope.v1i.yolov8\train\labels" # 替换为你的分割标注目录路径
convert_segmentation_to_box(labels_directory)
在这个脚本中,我们还是传入了labels目录,将labels目录中的分隔标注全部转化为box标注,执行脚本,看看前后结果,如图可以看多边形的分隔标注转化为了外界的矩形标注形式
结语
以上是幽络源的利用Python脚本检测分隔标注并转化为Box标注的教程,感兴趣的小伙伴可加群交流
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END
暂无评论内容