import os import random import shutil def split_dataset(image_dir, label_dir, output_dir, split_ratio=0.8): """ 自动将图片和标签划分为训练集和验证集。 Args: image_dir (str): 原始图片文件夹路径。 label_dir (str): 转换后的 YOLO 标签 (.txt) 文件夹路径。 output_dir (str): 整理好的数据集输出根目录 (例如 'weld_dataset')。 split_ratio (float): 训练集所占的比例,例如 0.8 代表 80% 训练, 20% 验证。 """ print("开始划分数据集...") # --- 1. 路径设置和文件夹创建 --- train_img_path = os.path.join(output_dir, 'images', 'train') val_img_path = os.path.join(output_dir, 'images', 'val') train_label_path = os.path.join(output_dir, 'labels', 'train') val_label_path = os.path.join(output_dir, 'labels', 'val') # 创建所有必要的文件夹 os.makedirs(train_img_path, exist_ok=True) os.makedirs(val_img_path, exist_ok=True) os.makedirs(train_label_path, exist_ok=True) os.makedirs(val_label_path, exist_ok=True) # --- 2. 文件匹配 --- # 获取所有标签文件的基础名(不含扩展名) label_files = [os.path.splitext(f)[0] for f in os.listdir(label_dir) if f.endswith('.txt')] # 查找对应的图片文件(支持多种格式) image_files_map = {} supported_formats = ['.jpg', '.jpeg', '.png', '.bmp'] for f in os.listdir(image_dir): base_name, ext = os.path.splitext(f) if ext.lower() in supported_formats: image_files_map[base_name] = f # 找出图片和标签都存在的文件对 valid_files = [base_name for base_name in label_files if base_name in image_files_map] if not valid_files: print(f"错误:在图片目录 '{image_dir}' 和标签目录 '{label_dir}' 之间未找到任何匹配的文件对。") print("请确保图片和标签的文件名(除扩展名外)完全一致。") return print(f"共找到 {len(valid_files)} 个有效的图片-标签对。") # --- 3. 随机划分 --- random.shuffle(valid_files) split_index = int(len(valid_files) * split_ratio) train_files = valid_files[:split_index] val_files = valid_files[split_index:] # --- 4. 复制文件到目标位置 --- def copy_files(file_list, dest_img_path, dest_label_path): for base_name in file_list: # 复制图片 img_name = image_files_map[base_name] shutil.copy(os.path.join(image_dir, img_name), dest_img_path) # 复制标签 label_name = base_name + '.txt' shutil.copy(os.path.join(label_dir, label_name), dest_label_path) print(f"正在复制 {len(train_files)} 个文件到训练集...") copy_files(train_files, train_img_path, train_label_path) print(f"正在复制 {len(val_files)} 个文件到验证集...") copy_files(val_files, val_img_path, val_label_path) print("\n数据集划分完成!") print(f"训练集: {len(train_files)} 张图片 | 验证集: {len(val_files)} 张图片") print(f"数据已整理至 '{output_dir}' 文件夹。") if __name__ == '__main__': # --- 用户需要配置的参数 --- # # 1. 原始图片文件夹路径 # # !! 重要 !!: 请将这里的路径修改为您实际存放图片的文件夹 # # 可能是 'faster-rcnn/JPEGImages' 或其他名称 # ORIGINAL_IMAGE_DIR = '../OpenCV/data_bottom/test3' # # # 2. 转换后的 YOLO 标签文件夹路径 # YOLO_LABEL_DIR = 'data_bottom' # # # 3. 最终输出的数据集文件夹 # OUTPUT_DATASET_DIR = 'train_data' # # # 4. 训练集比例 (0.8 表示 80% 训练, 20% 验证) # SPLIT_RATIO = 0.9 # # # --- 运行主函数 --- # split_dataset(ORIGINAL_IMAGE_DIR, YOLO_LABEL_DIR, OUTPUT_DATASET_DIR, SPLIT_RATIO) # # --- 用户需要配置的参数 --- # 1. 原始图片文件夹路径 # !! 重要 !!: 请将这里的路径修改为您实际存放图片的文件夹 # 可能是 'faster-rcnn/JPEGImages' 或其他名称 ORIGINAL_IMAGE_DIR = '../label/up' # 2. 转换后的 YOLO 标签文件夹路径 YOLO_LABEL_DIR = 'data_up' # 3. 最终输出的数据集文件夹 OUTPUT_DATASET_DIR = 'train_data_up' # 4. 训练集比例 (0.8 表示 80% 训练, 20% 验证) SPLIT_RATIO = 0.9 # --- 运行主函数 --- split_dataset(ORIGINAL_IMAGE_DIR, YOLO_LABEL_DIR, OUTPUT_DATASET_DIR, SPLIT_RATIO)