Reputation: 35
I am trying to extract frames from multiple video files in a for loop, using OpenCV. I have found several ways online to do frame extraction from a single video, however I am struggling to run the frame extraction within a for loop.
The working code for frame extraction from a single video (video variable) is:
cap=cv2.VideoCapture(video)
i=0
while (cap.isOpened()): #
ret, frame=cap.read()
if ret == False:
break
cv2.imwrite(str(i) + '.jpg', frame)
i+=1
cap.release()
cv2.destroyAllWindows()
I would like to extend this to include a for loop so that I can iterate through several videos (paths in videos variable) and extract all the frames. I would like the frame number from the video paths to run one after the other- i.e. if Video 1 has 30 frames extracted, Video 2 frames will be saved as 31, 32, 33 etc.
I tried to put the above code into a for loop, but it seems to run eternally and not save anything:
i=0 #place i outside of for-loop so it doesn't reset each iteration
for v in videos:
cap=cv2.VideoCapture(v)
while (cap.isOpened()): #
ret, frame=cap.read()
if ret == False:
break
cv2.imwrite(str(i) + '.jpg', frame)
i+=1
cap.release()
cv2.destroyAllWindows()
Is anyone able to help? Thankyou!
Upvotes: 1
Views: 4064
Reputation: 32094
Iterating few video files is not so different from your implementation:
cap = cv2.VideoCapture(intput_filename)
at the beginning of each "video file iteration".
As you did.cap.release()
at the end of each "video file iteration".cap.release()
at the wrong place.I am not sure about your code:
if ret == False:
break
It looks like the break is not indented correctly.
I created a "self contained" code sample which:
Here is the code:
import numpy as np
import cv2
import os
intput_filename1 = 'input_vid1.avi'
intput_filename2 = 'input_vid2.avi'
# List of video file names
intput_filenames = [intput_filename1, intput_filename2]
# Generate two synthetic video files to be used as input:
###############################################################################
width, height, n_frames = 640, 480, 30 # 30 frames, resolution 640x480
# Use motion JPEG codec (for testing)
synthetic_out = cv2.VideoWriter(intput_filename1, cv2.VideoWriter_fourcc(*'MJPG'), 25, (width, height))
for i in range(n_frames):
img = np.full((height, width, 3), 60, np.uint8)
cv2.putText(img, str(i+1), (width//2-100*len(str(i+1)), height//2+100), cv2.FONT_HERSHEY_DUPLEX, 10, (30, 255, 30), 20) # Green number
synthetic_out.write(img)
synthetic_out.release()
width, height, n_frames = 320, 240, 20 # 20 frames, resolution 320x240
synthetic_out = cv2.VideoWriter(intput_filename2, cv2.VideoWriter_fourcc(*'MJPG'), 25, (width, height))
for i in range(n_frames):
img = np.full((height, width, 3), 60, np.uint8)
cv2.putText(img, str(i+1), (width//2-50*len(str(i+1)), height//2+50), cv2.FONT_HERSHEY_DUPLEX, 5, (255, 30, 30), 10) # Blue number
synthetic_out.write(img)
synthetic_out.release()
###############################################################################
i = 1 # Images file counter
# Iterate file names:
for intput_filename in intput_filenames:
cap = cv2.VideoCapture(intput_filename)
# Keep iterating break
while True:
ret, frame = cap.read() # Read frame from first video
if ret:
cv2.imwrite(str(i) + '.jpg', frame) # Write frame to JPEG file (1.jpg, 2.jpg, ...)
cv2.imshow('frame', frame) # Display frame for testing
i += 1 # Advance file counter
else:
# Break the internal loop when res status is False.
break
cv2.waitKey(100) #Wait 100msec (for debugging)
cap.release() #Release must be inside the outer loop
cv2.destroyAllWindows()
Put this into a function:
def extract_multiple_videos(intput_filenames):
"""Extract video files into sequence of images.
Intput_filenames is a list for video file names"""
i = 1 # Counter of first video
# Iterate file names:
for intput_filename in intput_filenames:
cap = cv2.VideoCapture(intput_filename)
# Keep iterating break
while True:
ret, frame = cap.read() # Read frame from first video
if ret:
cv2.imwrite(str(i) + '.jpg', frame) # Write frame to JPEG file (1.jpg, 2.jpg, ...)
cv2.imshow('frame', frame) # Display frame for testing
i += 1 # Advance file counter
else:
# Break the interal loop when res status is False.
break
cv2.waitKey(100) #Wait 100msec (for debugging)
cap.release() #Release must be inside the outer loop
Upvotes: 2