如何用OpenCV Python按5fps提取30fps MP4视频的298帧?
如何用OpenCV Python按5fps提取视频帧(附适配你需求的代码)
首先直接给你答案:完全可以用OpenCV Python实现按5fps提取视频帧。你现在的代码只是简单抓取了前298帧,没有按照帧率控制的逻辑来采样,接下来我会帮你修正代码,同时兼顾你“总帧数298”的特殊需求。
先理清楚核心逻辑
你的原视频是30fps、时长297秒,总共有 297×30=8910 帧。要实现5fps的提取,本质上就是每6帧(30÷5=6)从原视频中取一帧,这样每秒就能得到5帧。不过你提到需要总帧数为298,这和297秒按5fps提取的理论帧数(297×5=1485帧)有差距,我会在代码里同时支持两种逻辑:既保证接近5fps的采样密度,又能满足你要298帧的要求。
修正后的可运行代码
import cv2 import os # 配置路径 video_path = "/content/Dataset/video.mp4" output_dir = '/content/data' # 创建输出文件夹 try: if not os.path.exists(output_dir): os.makedirs(output_dir) except OSError as e: print(f'出错了:创建目录失败 - {e}') # 打开视频 vid = cv2.VideoCapture(video_path) if not vid.isOpened(): print("Error:打不开视频文件,请检查路径是否正确") exit() # 获取视频基础参数 original_fps = vid.get(cv2.CAP_PROP_FPS) # 原视频帧率,这里是30 total_video_frames = int(vid.get(cv2.CAP_PROP_FRAME_COUNT)) # 设置采样规则 target_fps = 5 # 你要的5fps frame_sample_interval = int(round(original_fps / target_fps)) # 每6帧取一帧 target_total_frames = 298 # 你指定的总帧数 current_frame_idx = 0 saved_frame_count = 0 # 循环采样帧 while saved_frame_count < target_total_frames: ret, frame = vid.read() if not ret: print("提示:视频已经读完了,没凑够298帧") break # 按间隔采样,或者最后几帧直接保存以凑够数量 if current_frame_idx % frame_sample_interval == 0 or saved_frame_count >= target_total_frames - 1: save_path = f"{output_dir}/frame{saved_frame_count}.jpg" cv2.imwrite(save_path, frame) saved_frame_count += 1 current_frame_idx += 1 # 释放资源 vid.release() cv2.destroyAllWindows() print(f"搞定!一共保存了{saved_frame_count}帧")
代码里的关键细节
- 采样间隔计算:
frame_sample_interval是核心,它帮我们算出原视频每多少帧取一帧才能达到目标帧率,30fps转5fps就是每6帧取一帧。 - 强制凑够298帧:循环直到保存的帧数达到298,就算视频没读完也会停止;如果视频提前读完,会给你提示。
- 边界处理:最后加入的
saved_frame_count >= target_total_frames -1判断,是为了避免最后几帧因为间隔问题凑不够298,直接把剩下需要的帧补上。
可选调整:如果不需要强制298帧
要是你只是想严格按5fps提取,不需要固定298帧,只需要修改两处:
- 把循环条件改成
current_frame_idx < total_video_frames - 去掉判断里的
saved_frame_count >= target_total_frames -1
这样提取的总帧数会是视频时长×5,也就是约1485帧,完全符合5fps的要求。
内容的提问来源于stack exchange,提问作者Ebad
相关产品推荐
相关产品推荐

