Edit:
In short:
cap = cv2.VideoCapture(input_loc);
fps = cap.get(cv2.CAP_PROP_FPS)
returns ZeroDivisionError: float division by zero
starting from the 2nd video in the loop. (works fine on 1st video)
Note: already tried solution in Python OpenCV video.get(cv2.CAP_PROP_FPS) returns 0.0 FPS but didn't solve my issue.
I'm sorry that the title seems very vague since I'm not sure how to describe my issue.
To be short, I guess that OpenCV failed to load the video in started from the second video. Maybe it's because I forgot to reset something?
My goal is to extract frames from multiple videos, so I've implemented a function to do that:
def video_to_frames(input_loc, output_loc, filename, sec):
"""Function to extract frames from input video file
and save them as separate frames in an output directory.
Args:
input_loc: Input video file.
output_loc: Output directory to save the frames.
filename: name of the video file
sec: how many seconds per frame
"""
try:
os.mkdir(output_loc)
except OSError:
pass
# Start capturing the feed
cap = cv2.VideoCapture(input_loc)
# Find the total duration of videos
fps = cap.get(cv2.CAP_PROP_FPS)
frame_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
video_length = frame_count/fps
print("Video Length:", video_length)
count = 1
timepoint = count*sec*1000
# Start converting the video
while cap.isOpened():
# Extract the frame
cap.set(cv2.CAP_PROP_POS_MSEC,(timepoint))
ret, frame = cap.read()
for t in range(-2, 3):
cap.set(cv2.CAP_PROP_POS_MSEC,(timepoint + t*50))
ret, frame = cap.read()
cv2.imwrite("{}{}-{}-{}.png".format(output_loc, filename[:-4], count-1, t+2), frame[:480, :640, :]) # the shape of frame should be consistent
count = count + 1 # jump to the next frame
timepoint = count*sec*1000
# If there are no more frames left
if (timepoint > ((video_length -1 ) *1000)):
# Release the feed
cap.release()
# Print stats
print ("{} frames extracted".format(count-1))
break
return video_length, count
To execute this function, I put it in a loop
frames = 0
extracts = 0
total_frames = 0
for file_name in video_list:
input_path = input_path + "{}".format(f)
print (file_name)
video_to_frames(input_path, output_path, file_name, 2)
cv2.destroyAllWindows()
My issue is that extracting the first file seems fine, but once it moves to the next file, there are some problems so I get an error like this:
---------------------------------------------------------------------------
ZeroDivisionError Traceback (most recent call last)
<ipython-input-55-002937137b8e> in <module>()
7 input_path = input_path + "{}".format(f)
8 print (file_name)
----> 9 video_to_frames(input_path, output_path, file_name, 2)
10
11 cv2.destroyAllWindows()
<ipython-input-52-e4a4392eaa12> in video_to_frames(input_loc, output_loc, filename, sec)
22 fps = cap.get(cv2.CAP_PROP_FPS)
23 frame_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
---> 24 video_length = frame_count/fps
25
26 print("Video Length:", video_length)
ZeroDivisionError: float division by zero
Anyone knows why and how should I deal with this?