- 时序动作定位任务取 thumos 14 官方数据集的验证集当训练集,测试集当验证集
- 各有21个标注文件,Ambiguous_val.txt 文件记录了难以判断是否为动作的时间段,这些片段不参与评估。
根据标签文件把时序动作任务用到的视频移到同一个文件夹里(两个,一个val,一个test)
import shutil
from pathlib import Path
annotations_dir = Path('/hy-tmp/mmaction2-main/data/thumos14/annotations_val')
video_dir = Path('/hy-tmp/123/validation')
target_dir = Path('/hy-tmp/val_videos')
target_dir.mkdir(exist_ok=True)
video_names = set()
for txt in annotations_dir.glob('*.txt'):with open(txt, 'r') as f:for line in f:if line.strip():video_names.add(line.strip().split()[0])
moved_count = 0
not_found_count = 0for v in sorted(video_names):src = video_dir / f'{v}.mp4'dst = target_dir / f'{v}.mp4'if src.exists():shutil.move(str(src), str(dst)) print(f'已移动: {src} -> {dst}')moved_count += 1else:print(f'未找到视频文件: {src}')not_found_count += 1print(f'\n共移动视频数: {moved_count}')
print(f'共未找到视频数: {not_found_count}')
将thumos14的标注文件处理成时序动作定位可使用的标注格式
import json
import os
from pathlib import Path
import cv2 def get_video_duration_and_fps(video_path):"""使用 OpenCV 获取视频时长和FPS。你需要根据实际视频文件路径来调用此函数。这是一个示例,实际使用时可能需要更健壮的错误处理。"""try:cap = cv2.VideoCapture(str(video_path))if not cap.isOpened():print(f"错误:无法打开视频 {video_path}")return None, Nonefps = cap.get(cv2.CAP_PROP_FPS)frame_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))if fps > 0:duration_second = frame_count / fpselse:print(f"错误:视频 {video_path} 的FPS为 {fps}。无法计算时长。")cap.release()return None, Nonecap.release()return duration_second, fpsexcept Exception as e:print(f"使用OpenCV处理视频 {video_path} 时出错: {e}")if 'cap' in locals() and cap.isOpened():cap.release()return None, Nonedef convert_thumos_to_hacs(thumos_ann_dir, output_json_path, thumos_video_dir=None, default_fps=30.0):"""将 THUMOS14 格式的标注文件转换为 HACS JSON 格式。Args:thumos_ann_dir (str): THUMOS14 标注文件所在目录 (e.g., '.../annotations_val/').output_json_path (str): 输出的 HACS 格式 JSON 文件路径。thumos_video_dir (str, optional): THUMOS14 视频文件所在目录。如果提供,会尝试读取视频真实时长和FPS。default_fps (float): 如果无法从视频文件获取FPS,则使用的默认FPS。"""hacs_data = {}thumos_ann_path = Path(thumos_ann_dir)if not thumos_ann_path.is_dir():print(f"错误:找不到标注目录 '{thumos_ann_dir}'。")returnfor ann_file in thumos_ann_path.glob('*_val.txt'): action_label = ann_file.stem.replace('_val', '').replace('_test', '') print(f"正在处理类别: {action_label},来自文件: {ann_file.name}")with open(ann_file, 'r') as f:for line in f:parts = line.strip().split()if len(parts) != 3:print(f"警告:跳过 {ann_file.name} 中的格式错误行: {line.strip()}")continuevideo_name = parts[0]try:start_time = float(parts[1])end_time = float(parts[2])except ValueError:print(f"警告:跳过 {ann_file.name} 中时间无效的行: {line.strip()}")continueif video_name not in hacs_data:actual_duration_s = Nonecurrent_video_fps = default_fps if thumos_video_dir:potential_video_path = Path(thumos_video_dir) / f"{video_name}.mp4" if potential_video_path.exists():res_duration, res_fps = get_video_duration_and_fps(potential_video_path)if res_duration is not None and res_fps is not None and res_fps > 0:actual_duration_s = res_durationcurrent_video_fps = res_fps else:print(f"警告:无法从视频文件获取 {video_name} 的有效元数据。使用估算时长和默认FPS ({default_fps})。")else:print(f"警告:在 {potential_video_path} 未找到 {video_name} 的视频文件。使用估算时长和默认FPS ({default_fps})。")hacs_data[video_name] = {"duration_second": actual_duration_s if actual_duration_s is not None else 0.0,"duration_frame": 0, "feature_frame": 0, "_fps_temp": current_video_fps, "annotations": []}annotation_entry = {"label": action_label,"segment": [start_time, end_time]}hacs_data[video_name]["annotations"].append(annotation_entry)if hacs_data[video_name]["duration_second"] == 0.0:hacs_data[video_name]["duration_second"] = max(hacs_data[video_name].get("duration_second", 0.0), end_time)for video_name in hacs_data:video_info = hacs_data[video_name]temp_fps = video_info.get("_fps_temp", default_fps)if video_info["duration_second"] > 0 and temp_fps > 0:video_info["duration_frame"] = int(video_info["duration_second"] * temp_fps)else:video_info["duration_frame"] = 0 video_info["feature_frame"] = video_info["duration_frame"] if "_fps_temp" in video_info:del video_info["_fps_temp"] with open(output_json_path, 'w') as f:json.dump(hacs_data, f, indent=4)print(f"转换完成。输出已保存到 {output_json_path}")if __name__ == '__main__':thumos_annotations_dir = r'/hy-tmp/456/annotions_val' thumos_videos_base_dir = r'/hy-tmp/456/789' output_hacs_json = r'/hy-tmp/thumos14_val_for_hacs.json'fps_default = 30.0Path(output_hacs_json).parent.mkdir(parents=True, exist_ok=True)convert_thumos_to_hacs(thumos_annotations_dir,output_hacs_json,thumos_video_dir=thumos_videos_base_dir, default_fps=fps_default)