这段代码的功能是根据XML文件中前缀的信息,从对应的视频文件中提取指定的帧,并将这些帧保存为图像文件。具体步骤包括读取XML文件路径,查找对应的视频文件,设置视频捕获对象,读取指定帧,并将帧保存到指定目录中。该代码处理支持多种视频文件后缀,并为每个视频文件创建单独的输出目录。
import os
import cv2
import glob
# 指定包含XML文件的文件夹路径
annotations_folder = "C:\\Users\\29269\\Desktop\\video\\Annotations"
# 指定包含视频文件的文件夹路径
videos_folder = "C:\\Users\\29269\\Desktop\\video\\Videos"
# 支持的视频文件后缀
video_extensions = ['.mp4', '.avi', '.mov', '.mkv']
# 获取文件夹中所有XML文件的路径
xml_files = glob.glob(os.path.join(annotations_folder, "*.xml"))
output_dir = "C:\\Users\\29269\\Desktop\\video\\ExtractedFrames"
# 创建输出目录(如果不存在)
if not os.path.exists(output_dir):
os.makedirs(output_dir)
for xml_file in xml_files:
# 提取文件名并分割前缀和帧数
file_name = os.path.basename(xml_file)
file_name_no_ext = os.path.splitext(file_name)[0]
prefix, frame_number = file_name_no_ext.rsplit('--', 1)
frame_number = int(frame_number)
# 查找对应的视频文件
video_file = None
for ext in video_extensions:
potential_video_file = os.path.join(videos_folder, prefix + ext)
if os.path.exists(potential_video_file):
video_file = potential_video_file
break
if not video_file:
print(f"未找到前缀为 {prefix} 的视频文件.")
continue
# 创建视频捕获对象
cap = cv2.VideoCapture(video_file)
# 检查是否成功打开视频文件
if not cap.isOpened():
print(f"无法打开视频文件 {video_file}.")
continue
# 设置捕获对象读取的帧位置
cap.set(cv2.CAP_PROP_POS_FRAMES, frame_number)
# 读取指定帧
ret, frame = cap.read()
if ret:
# 创建输出目录(按视频前缀名)
video_output_dir = os.path.join(output_dir, prefix)
if not os.path.exists(video_output_dir):
os.makedirs(video_output_dir)
# 保存帧为图像,前缀与XML文件前缀相同
frame_output_path = os.path.join(video_output_dir, f"{file_name_no_ext}.jpg")
cv2.imwrite(frame_output_path, frame)
print(f"帧 {frame_number} 已保存到 {frame_output_path}")
else:
print(f"无法读取视频文件 {video_file} 的帧 {frame_number}.")
# 释放视频捕获对象
cap.release()
整体架构图:
视频Videos结构图:
xml文件结构图:
运行结果: