一、前言
图像分割任务中,分割数据集的转换和表示方式对于模型训练至关重要。目前主要有两种常见的分割结果表示方法:
1. 转化为TXT文件
这种方式通常使用一系列的点(坐标)来表示图像中每个像素的类别标签。每个点通常包含像素的坐标(x, y)和对应的类别标签。这种方式的优点是数据量较小,易于处理,适合于需要快速读取和处理大量数据的场景。
适用场景:
-
适用于YOLO系列的分割模型,因为YOLO模型本身是为实时目标检测设计的,其分割版本(如YOLOv5的分割版本)也需要快速处理图像数据。
-
由于YOLO模型的输入是固定大小的网格,因此使用点坐标表示分割结果可以方便地将这些点映射到网格上。
示例格式: 假设有一个类别标签为1、2、3的分割任务,TXT文件可能包含如下内容:
x1 y1 1
x2 y2 2
x3 y3 3
...
每行代表一个像素点,x
和 y
是该点的坐标,最后的数字是类别标签。
2. 使用分割的伪彩图
这种方式是将分割结果直接以图像的形式保存,每个像素的颜色代表其类别。这种方法直观且易于理解,但数据量较大,因为需要保存整个图像文件。
适用场景:
-
适用于一些专门的分割网络,如mmseg、U-Net、DeepLab和SAM等,这些模型通常需要更精细的分割结果,并且能够处理高分辨率的图像数据。
-
伪彩图可以直接用于可视化分割结果,便于分析和调试。
示例格式: 伪彩图是一个普通的图像文件(如PNG或JPEG),其中每个像素的颜色对应一个类别。例如,类别1可能用红色表示,类别2用绿色表示,等等。
二、伪彩图转化
我们可以使用labelme中提供的一个命令行工具labelme_export_json直接进行转换,因此需要在安装了labelme 的虚拟环境中运行下面代码,其中A文件夹为转化后的保存路径,B文件夹为.json格式文件夹路径。
import os
import shutil
import subprocess
# 确保输出路径存在
output_dir = './image/mask' # 填写A文件夹的输出路径
if not os.path.exists(output_dir):
os.makedirs(output_dir)
# 获取 JSON 文件列表
json_list = os.listdir('./image/labels') # 填写B文件夹文件路径
print("JSON files found:", json_list)
# 遍历 JSON 文件列表
for idx, json_file in enumerate(json_list):
# 构造输入和输出路径
input_path = os.path.join('./image/labels', json_file) # 填写B文件夹文件路径
output_path = os.path.join('./image/mask', json_file.replace('.json', '')) # 填写A文件夹的输出路径
# 如果输出文件夹已存在,删除它
if os.path.exists(output_path):
shutil.rmtree(output_path)
# 打印正在处理的文件和目标路径
print(f"Processing {input_path} -> {output_path}")
# 调用 labelme_export_json 命令并捕获输出
command = f'labelme_export_json -o {output_path} {input_path}'
result = subprocess.run(command, shell=True, capture_output=True, text=True)
print(result.stdout)
print(result.stderr)
# 打印完成信息
print('Done:', idx)
在A文件夹中,每张图片都会有一个文件夹,包含以下内容。
我们需要的主要是label.png文件,以下代码可以批量将A文件夹中每个图片文件夹中的label.png文件保存在一个C文件夹中。
import os
import shutil
def copy_label_png(source_folder, target_folder):
# 确保目标文件夹存在
if not os.path.exists(target_folder):
os.makedirs(target_folder)
# 遍历源文件夹中的所有子文件夹
for root, dirs, files in os.walk(source_folder):
for file in files:
if file == "label.png":
# 获取当前子文件夹的名称
folder_name = os.path.basename(root)
# 构造目标文件的完整路径,文件名以子文件夹的名字命名
target_file_name = f"{folder_name}.png"
target_file_path = os.path.join(target_folder, target_file_name)
# 构造源文件的完整路径
source_file_path = os.path.join(root, file)
# 复制文件
shutil.copy2(source_file_path, target_file_path)
print(f"文件 {source_file_path} 已复制到 {target_file_path}")
# 设置源文件夹和目标文件夹路径
source_folder = "./image/mask" # 替换为你的A文件夹路径
target_folder = "./image/mask/all/" # 替换为你的C文件夹路径
copy_label_png(source_folder, target_folder)
运行后我们将在C文件夹中获取所有图片的伪彩图图像