很简单的,很容易的代码,
1.以时间命名图片
2.多线程处理
3.tqdm进度条可视化
import cv2
import os
from pathlib import Path
import concurrent.futures
from tqdm import tqdm
def video_to_images(video_path, output_dir='frames', frame_interval=1, workers=4, use_time_name=True):
"""
使用多线程和tqdm进度条将视频转换为图片序列
参数:
video_path (str): 输入视频的路径
output_dir (str): 输出图片的目录
frame_interval (int): 每隔多少帧提取一帧
workers (int): 线程池大小
use_time_name (bool): 是否使用时间作为文件名
"""
# 确保输出目录存在
Path(output_dir).mkdir(parents=True, exist_ok=True)
# 打开视频获取基本信息
cap = cv2.VideoCapture(video_path)
if not cap.isOpened():
print(f"错误:无法打开视频文件 {video_path}")
return
fps = cap.get(cv2.CAP_PROP_FPS)
total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
duration = total_frames / fps # 视频总时长(秒)
cap.release()
# 计算需要处理的帧索引
frame_indices = list(range(0, total_frames, frame_interval))
print(f"视频信息: {fps:.2f} FPS, 共 {total_frames} 帧, 时长 {duration:.2f} 秒, 将提取 {len(frame_indices)} 帧")
def frame_to_timecode(frame_idx, fps):
"""将帧索引转换为时分秒格式"""
total_seconds = frame_idx / fps
hours = int(total_seconds // 3600)
minutes = int((total_seconds % 3600) // 60)
seconds = total_seconds % 60
return hours, minutes, seconds
def process_frame(index):
cap = cv2.VideoCapture(video_path)
cap.set(cv2.CAP_PROP_POS_FRAMES, index)
ret, frame = cap.read()
cap.release()
if ret:
if use_time_name:
# 生成时间格式文件名: time_时_分_秒_毫秒.jpg
h, m, s = frame_to_timecode(index, fps)
ms = int((s - int(s)) * 1000) # 毫秒部分
output_path = os.path.join(output_dir, f"time_{h:02d}_{m:02d}_{int(s):02d}_{ms:03d}.jpg")
else:
# 原始的帧索引命名
output_path = os.path.join(output_dir, f"frame_{index:06d}.jpg")
cv2.imwrite(output_path, frame)
return True
return False
# 使用线程池并行处理帧,并添加tqdm进度条
with concurrent.futures.ThreadPoolExecutor(max_workers=workers) as executor:
results = list(tqdm(executor.map(process_frame, frame_indices),
total=len(frame_indices),
desc="处理进度",
unit="帧"))
success_count = sum(results)
print(f"视频转图片完成!成功生成 {success_count} 张图片,保存在 {output_dir} 目录下")
if __name__ == "__main__":
# 使用示例 - 按时间命名
video_file = "2.mp4" # 替换为你的视频文件路径
video_to_images(
video_file,
output_dir="output_frames",
frame_interval=25, # 每秒提取一帧(假设视频为25fps)
workers=4, # 根据CPU核心数调整
use_time_name=True # 使用时间命名
)
#时间格式:time_时_分_秒_毫秒.jpg(例如:time_00_01_53_000.jpg表示 1 分 53 秒整)