视频提取图片帧,图片合成视频

张开发
2026/4/20 5:08:12 15 分钟阅读

分享文章

视频提取图片帧,图片合成视频
写了两个脚本。一个用于将视频按帧率一次转为图片另一个将图片合成的为视频的脚本。一、环境配置安装opencv2用到了os库、cv2、globpip install opencv-contrib-python二、代码1.首先是第一个视频转为图片的代码可以按需修改最后几行的代码。输入视频路径和输出图片的路径一定要改输出照片的格式默认是jpg按需改成png啥的都可以保存帧数默认是0就是将所有的帧数都提取出来但是这样就会有很多相似的照片反正按需求来吧设置30帧提取一帧都可以。video_pathD:\\data\\1080p.mp4, #输入转换的视频output_dirD:\\data\\1080p, #输出图片的文件夹frame_formatpng, #输出照片的格式skip_frames9 # 0保存所有帧1每2帧保存1帧依此类推import cv2 import os def video_to_frames(video_path, output_dir, frame_formatjpg, skip_frames0): 将视频逐帧提取为图片 参数: video_path: 输入视频的路径如 test.mp4 output_dir: 输出图片的文件夹路径 frame_format: 保存图片的格式可选 jpg 或 png skip_frames: 跳帧间隔0表示不跳帧1表示每2帧取1帧以此类推 # 创建输出文件夹如果不存在 if not os.path.exists(output_dir): os.makedirs(output_dir) # 打开视频文件 cap cv2.VideoCapture(video_path) if not cap.isOpened(): raise ValueError(f无法打开视频文件: {video_path}) frame_count 0 # 总帧数计数器 saved_count 0 # 保存的帧数计数器 # 逐帧读取视频 while True: # 读取一帧 ret, frame cap.read() # ret 为 False 表示读取完毕到视频末尾 if not ret: break # 跳帧处理按需保存 if frame_count % (skip_frames 1) 0: # 定义图片文件名格式frame_0001.jpg frame_filename fframe_{saved_count:04d}.{frame_format} frame_path os.path.join(output_dir, frame_filename) # 保存帧为图片 cv2.imwrite(frame_path, frame) saved_count 1 frame_count 1 # 释放视频资源 cap.release() print(f视频帧提取完成) print(f总帧数: {frame_count}, 保存的帧数: {saved_count}) print(f图片保存路径: {os.path.abspath(output_dir)}) # ------------------- 示例调用 ------------------- if __name__ __main__: # 替换为你的视频路径和输出文件夹路径 video_to_frames( video_pathD:\\data\\1080p.mp4, #输入转换的视频 output_dirD:\\data\\1080p, #输出图片的文件夹 frame_formatjpg, #输出照片的格式 skip_frames0 # 0保存所有帧1每2帧保存1帧依此类推 )2.图片依次转换为视频的代码逻辑基本上差不多调整的参数frames_dirFRAMES_DIR #替换为你的图片文件夹路径output_video_pathOUTPUT_VIDEO, #替换为你预计保存视频的路径fps25, # 帧率根据原视频调整比如原视频是25FPS就设为25frame_formatjpg # 图片格式和之前保存的一致import cv2 import os import glob def frames_to_video(frames_dir, output_video_path, fps30, frame_formatjpg): 将按顺序命名的图片帧合并为视频 参数: frames_dir: 存放图片帧的文件夹路径 output_video_path: 输出视频的路径如 output_video.mp4 fps: 输出视频的帧率默认30帧/秒可根据原视频调整 frame_format: 图片帧的格式如 jpg、png # 检查输入文件夹是否存在 if not os.path.exists(frames_dir): raise ValueError(f图片文件夹不存在: {frames_dir}) # 获取所有图片帧的路径并按文件名排序保证帧顺序 frame_paths glob.glob(os.path.join(frames_dir, f*.{frame_format})) if not frame_paths: raise ValueError(f在 {frames_dir} 中未找到 {frame_format} 格式的图片) # 按文件名排序关键确保帧顺序正确 frame_paths.sort(keylambda x: int(os.path.splitext(os.path.basename(x))[0].split(_)[1])) # 读取第一张图片获取视频分辨率 first_frame cv2.imread(frame_paths[0]) if first_frame is None: raise ValueError(f无法读取第一张图片: {frame_paths[0]}) height, width first_frame.shape[:2] # 设置视频编码格式和写入对象 # MP4格式推荐使用 mp4v 编码兼容性更好 fourcc cv2.VideoWriter_fourcc(*mp4v) video_writer cv2.VideoWriter( output_video_path, fourcc, fps, (width, height) # 视频分辨率宽, 高 ) if not video_writer.isOpened(): raise ValueError(f无法创建视频写入对象请检查输出路径和编码格式) # 逐帧写入视频 total_frames len(frame_paths) for i, frame_path in enumerate(frame_paths): # 读取图片帧 frame cv2.imread(frame_path) if frame is None: print(f警告跳过损坏的图片 {frame_path}) continue # 确保图片尺寸和视频分辨率一致防止尺寸不匹配报错 if frame.shape[:2] ! (height, width): frame cv2.resize(frame, (width, height)) # 写入视频 video_writer.write(frame) # 打印进度可选 if (i 1) % 100 0 or (i 1) total_frames: print(f已处理 {i 1}/{total_frames} 帧) # 释放资源 video_writer.release() print(f\n视频生成完成) print(f输出视频路径: {os.path.abspath(output_video_path)}) print(f视频参数分辨率 {width}x{height}帧率 {fps} FPS) if __name__ __main__: # 替换为你的图片文件夹路径和输出视频路径 FRAMES_DIR D:/data/img # 存放图片帧的文件夹和之前转帧的输出路径一致 OUTPUT_VIDEO D:/data/img.mp4 # 输出视频文件名 # 调用函数帧率建议和原视频一致通常为24/30 FPS frames_to_video( frames_dirFRAMES_DIR, output_video_pathOUTPUT_VIDEO, fps25, # 帧率根据原视频调整比如原视频是25FPS就设为25 frame_formatjpg # 图片格式和之前保存的一致 )

更多文章