当前代码适用的是images文件夹里全为图片且annotations中每一个txt文件对应每一个图片的信息。请问如果我的images文件夹里包含多个文件夹,annotations中每一个txt包含多条信息,对应每一个文件夹里的每一张图片的信息,该如何修改以下代码呢?
from PIL import Image
import os
from os import walk
# 指定图片目录 - 根据需要更改为训练集(train)、验证集(val)和测试集(test-dev)的路径
image_dir = "VisDrone2019-VID-val/sequences/"
annot_dir = "VisDrone2019-VID-val/annotations/"
output_dir = "

VisDrone2019-VID-val/labels/"
remove_ignored = True # 是否移除被标记为忽略的标注
# 如果输出目录不存在,则创建该目录
if not os.path.exists(output_dir):
os.makedirs(output_dir)
def convert_annotation(img_size, bbox):
"""
将VisDrone的边界框格式转换为YOLO的边界框格式(中心点坐标+宽高)
参数:
- img_size: 图像的尺寸,格式为(width, height)
- bbox: VisDrone的边界框,格式为[x_min, y_min, width, height]
返回:
- 转换后的YOLO格式边界框,格式为[x_center, y_center, width, height],值被归一化
"""
width_div = 1.0 / img_size[0]
height_div = 1.0 / img_size[1]
return [(bbox[0] + bbox[2] / 2) * width_div, (bbox[1] + bbox[3] / 2) * height_div, bbox[2] * width_div,
bbox[3] * height_div]
# 遍历标注目录中的所有文件
for annot_file in os.listdir(annot_dir):
annot_path = os.path.join(annot_dir, annot_file)
if not os.path.isfile(annot_path):
continue
base_name = os.path.splitext(annot_file)[0]
image_folder_path = os.path.join(image_dir, base_name)
if not os.path.exists(image_folder_path):
print(f"Image folder not found: {image_folder_path}")
continue
# 获取图像文件列表,并按文件名排序
image_files = sorted([f for f in os.listdir(image_folder_path) if f.lower().endswith('.jpg')])
# 创建输出目录(如果不存在)
output_folder = os.path.join(output_dir, base_name)
if not os.path.exists(output_folder):
os.makedirs(output_folder)
with open(annot_path, 'r', encoding='utf8') as f:
for index, line in enumerate(f):
data = line.strip().split(',')
if len(data) < 6:
continue
# 获取图像文件名
if index < len(image_files):
image_file = image_files[index]
else:
print(f"Not enough images for annotation file: {annot_path}")
continue
image_path = os.path.join(image_folder_path, image_file)
output_path = os.path.join(output_folder, f"{os.path.splitext(image_file)[0]}.txt")
print(f"Processing image file: {image_path}")
if not os.path.exists(image_path):
print(f"Image file not found: {image_path}")
continue
img = Image.open(image_path)
class_label = int(data[5]) - 1 # 假设YOLO的类别范围为0-9,0表示行人,9表示摩托车
if remove_ignored:
considered = data[4] # 如果需要移除被忽略的标注,则检查当前标注是否被考虑
else:
considered = 1 # 如果不移除被忽略的标注,则考虑所有标注
if considered != str(0) and (class_label >= 0) and (class_label <= 9): # 检查是否为有效类别
bounding_box_visdrone = [float(x) for x in data[1:5]]
yolo_bounding_box = convert_annotation(img.size, bounding_box_visdrone)
bounding_box_string = " ".join([str(x) for x in yolo_bounding_box]) # 创建要写入的标注字符串
with open(output_path, 'w', encoding='utf-8') as output_file:
output_file.write(f"{class_label} {bounding_box_string}\n") # 以YOLO格式写入转换后的标注和类别

