如何用Python从视频中提取特定序列帧(如每10帧提取一次)
I need to extract specific frames from a video, like every 10th frame (frame_1, frame_10, frame_20...). I used the following code, but it extracts all frames. How can I modify it to achieve my requirement?
import cv2 vidcap = cv2.VideoCapture('big_buck_bunny_720p_5mb.mp4') success,image = vidcap.read() count = 0 success = True while success: cv2.imwrite("frame%d.jpg" % count, image) # save frame as JPEG file success,image = vidcap.read() count += 1
Hey there, the problem with your current code is that it saves every frame as it reads them—no filtering logic to pick only the frames you want. Let's tweak it to extract every 10th frame (or any interval you specify):
Here's the modified code that meets your requirement:
import cv2 # Adjust this number to set how often you want to extract frames (e.g., 10 = every 10th frame) FRAME_INTERVAL = 10 vidcap = cv2.VideoCapture('big_buck_bunny_720p_5mb.mp4') success, image = vidcap.read() count = 0 while success: # Only save the frame if it's a multiple of our interval if count % FRAME_INTERVAL == 0: cv2.imwrite(f"frame{count}.jpg", image) print(f"Saved frame {count}") # Always read the next frame to advance through the video success, image = vidcap.read() count += 1 # Clean up the video capture resource when done vidcap.release()
Let me walk through the key changes:
- Added a
FRAME_INTERVALvariable to make adjusting the extraction frequency super easy—no need to dig through the loop logic later. - Added the condition
if count % FRAME_INTERVAL == 0:: this checks if the current frame number is evenly divisible by your interval. Only when this is true do we save the frame. - Added
vidcap.release()at the end: this is good practice to free up system resources and avoid potential memory leaks. - Switched to an f-string for the filename (
f"frame{count}.jpg") for cleaner, more readable code (your original format string works too, this is just a modern alternative).
If you want to start counting frames from 1 instead of 0 (so you get frame_1, frame_10, frame_20...), just initialize count = 1 instead of 0—the rest of the logic will work exactly as intended.
内容的提问来源于stack exchange,提问作者N.zay

