HMDB51数据集划分

112 阅读2分钟

生成训练集、验证集和测试集

每个split文件应该包含:

  • 训练集(id=1): 70个视频
  • 测试集(id=2): 30个视频
  • 未使用(id=0): 剩余视频 这是一个70/30的训练/测试分割比例。标记为0的视频被排除在当前实验之外。
  • 实际上训练集(id=1),验证集(id=2),测试集(id=0),测试集和验证集可以互换
import os
import glob
from pathlib import Path

# 设置数据处理的路径
SPLIT_DIR = r"C:/Users/yanho/Desktop/testTrainMulti_7030_splits"  # split文件所在目录
OUTPUT_DIR = r"C:/Users/yanho/Desktop/hmdb51_annotations"  # 输出目录

def process_split_file(split_file, action_class):
    """处理单个split文件并生成训练、验证和测试列表"""
    train_videos = []
    val_videos = []
    test_videos = []
    
    with open(split_file, 'r') as f:
        for line in f:
            video_name, label = line.strip().split()
            # 为每个视频添加类别标签(action_class)
            video_info = f'{video_name} {action_class}\n'
            if label == '1':
                train_videos.append(video_info)
            elif label == '2':
                val_videos.append(video_info)
            elif label == '0':
                test_videos.append(video_info)
    
    return train_videos, val_videos, test_videos

def main():
    # 创建输出目录
    output_dir = Path(OUTPUT_DIR)
    output_dir.mkdir(parents=True, exist_ok=True)
    
    # 用于收集所有训练、验证和测试样本
    all_train_videos = []
    all_val_videos = []
    all_test_videos = []
    
    # 处理所有split1文件
    split_files = glob.glob(os.path.join(SPLIT_DIR, '*_test_split1.txt'))
    
    for split_file in split_files:
        # 从文件名中提取动作类别
        action_class = Path(split_file).stem.split('_test_split1')[0]
        # 获取当前类别的动作类别索引
        class_idx = split_files.index(split_file)
        
        print(f'处理类别: {action_class} (索引: {class_idx})')
        
        # 处理当前split文件
        train_videos, val_videos, test_videos = process_split_file(split_file, class_idx)
        all_train_videos.extend(train_videos)
        all_val_videos.extend(val_videos)
        all_test_videos.extend(test_videos)
    
    # 写入训练集文件
    train_file = output_dir / 'train_split1.txt'
    with open(train_file, 'w') as f:
        f.writelines(all_train_videos)
    
    # 写入验证集文件
    val_file = output_dir / 'val_split1.txt'
    with open(val_file, 'w') as f:
        f.writelines(all_val_videos)
    
    # 写入测试集文件
    test_file = output_dir / 'test_split1.txt'
    with open(test_file, 'w') as f:
        f.writelines(all_test_videos)
    
    print(f'\n处理完成!')
    print(f'训练集样本数: {len(all_train_videos)}')
    print(f'验证集样本数: {len(all_val_videos)}')
    print(f'测试集样本数: {len(all_test_videos)}')
    print(f'文件保存在: {output_dir}')

if __name__ == '__main__':
    main()

合并视频到统一目录

import os
import shutil
from pathlib import Path

def merge_videos(src_dir, dst_dir):
    """
    合并所有视频到统一目录
    
    Args:
        src_dir: 源视频目录
        dst_dir: 目标目录
    """
    
    # 创建目标目录
    Path(dst_dir).mkdir(parents=True, exist_ok=True)
    
    # 遍历源目录
    for root, dirs, files in os.walk(src_dir):
        for file in files:
            if file.endswith('.avi'):  # 只处理视频文件
                # 获取类别名称
                category = os.path.basename(os.path.dirname(root))
                
                # 创建类别子目录
                category_dir = os.path.join(dst_dir, category)
                Path(category_dir).mkdir(exist_ok=True)
                
                # 源文件和目标文件路径
                src_path = os.path.join(root, file)
                dst_path = os.path.join(category_dir, file)
                
                # 复制文件
                shutil.copy2(src_path, dst_path)
                print(f"Copied {src_path} -> {dst_path}")

if __name__ == "__main__":
    src_dir = "videos_src"  # 源视频目录
    dst_dir = "data/hmdb51/videos"  # 目标目录
    merge_videos(src_dir, dst_dir)  # 合并视频到统一目录,一共6766个视频