NWPU VHR-10 dataset数据集给的自带的标签是如下形式:
在yolo模型中要使用这个数据集的话需要将其转换为 类别(编号),x,y,w,h的形式,其中x,y,w,h是目标框相对于图片的框中心点坐标的比例和宽高相对于图像总体尺寸的比例。
一共分两步,第一步,现将其转换为类别(编号),xmin,ymin,xmax,ymax的形式,使用如下脚本即可:
from PIL import Image
import os
import re
# todo:旧标签的路径
old_label_path = r'D:\datasets\small-object-detection-datasets\NWPU VHR-10 dataset\old_labels\\'
# todo:旧的图片数据集的路径
f_path = r'D:\datasets\small-object-detection-datasets\NWPU VHR-10 dataset\image'
# todo:将要存储的labels的路径
new_file_path = r'D:\datasets\small-object-detection-datasets\NWPU VHR-10 dataset\\labels\\'
# 目标类别以及对应的编号
# class_to_index = {'aircraft': 0, 'oiltank': 1, 'overpass': 2, 'playground': 3}
# 获取old_label_path下所有txt文件的文件名列表
txt_files = [file for file in os.listdir(old_label_path) if file.endswith(".txt")]
new_data = [0,0.00,0.00,0.00,0.00]
# 遍历每个txt文件
for txt_file in txt_files:
# 构建txt文件的完整路径
old_label_file_path = os.path.join(old_label_path, txt_file)
print('当前转换的是图片:',old_label_file_path)
i = 0
with open(old_label_file_path, 'r') as file:
#读取该标签对应的图片的宽高数据
new_string = old_label_file_path.replace(".txt",".jpg")
img_path = new_string.replace("old_labels", "image")
# 读取图片的长宽
with Image.open(img_path) as img:
# 获取图片的长宽尺寸
width, height = img.size
print('图片的长为:', height, " ,宽为", width)
new_file_path_concat = new_file_path + txt_file
#读取每一行的标签数据并进行操作
for line in file:
txt_data = line
# 使用正则表达式提取数字
numbers = re.findall(r'\d+', txt_data)
# 将提取的数字转换为整数
data = [int(num) for num in numbers]
if(len(data) == 0):
break
# 获取新的标签类别(原始标签-1)
new_data[0] = data[4]-1
new_data[1] = int(data[0]) / width
new_data[2] = int(data[1]) / height
new_data[3] = int(data[2]) / width
new_data[4] = int(data[3]) / height
print(new_data)
# 将new_data写入新的txt文件
with open(new_file_path_concat, 'a') as new_file:
for item in new_data:
new_file.write(str(item) + ' ')
new_file.write('\n')
print(f"处理完成: {txt_file}")
以下是第二个步骤:
将坐标从左上右下转换为中心+宽高
import os
def convert_coordinates(input_folder, output_folder):
# 确保输出文件夹存在
if not os.path.exists(output_folder):
os.makedirs(output_folder)
# 获取输入文件夹中的所有txt文件
txt_files = [file for file in os.listdir(input_folder) if file.endswith(".txt")]
# 遍历每个txt文件
for txt_file in txt_files:
input_path = os.path.join(input_folder, txt_file)
output_path = os.path.join(output_folder, txt_file)
# 处理每个txt文件
with open(input_path, 'r') as infile, open(output_path, 'w') as outfile:
# 逐行读取并处理数据
for line in infile:
# 将每一行的数据拆分为列表
data = line.strip().split()
if len(data) == 5:
# 提取类别标签和矩形框坐标
category = int(data[0])
x1, y1, x2, y2 = map(float, data[1:5])
# 计算矩形中心坐标和宽高
cx = (x1 + x2) / 2
cy = (y1 + y2) / 2
width = x2 - x1
height = y2 - y1
# 将转换后的数据写入新文件
outfile.write(f"{category} {cx} {cy} {width} {height}\n")
else:
print(f"Ignoring invalid data in {txt_file}: {line.strip()}")
if __name__ == "__main__":
# 指定输入文件夹和输出文件夹路径
input_folder = 'D:\datasets\small-object-detection-datasets/NWPU VHR-10 dataset\左上右下labels'
output_folder = 'D:\datasets\small-object-detection-datasets/NWPU VHR-10 dataset\labels'
# 执行坐标转换
convert_coordinates(input_folder, output_folder)
最终转换完之后是这个形式:
如果你需要将其再转换成COCO形式以便于后期生成APs的小目标指标的话,请参考这一篇博文:
小目标的检测指标APs怎么获得?------数据集Yolo格式生成json文件-CSDN博客