Reputation: 45
I'm trying to use opencv's cv2.VideoWriter to record a video for certain time. The problem is the output is incorrect. For example, the video for 10 seconds only got 2 seconds, and it plays faster like speed up. Here's my code. Any suggestions or ideas are welcome. Also, another problem is that the output video is silence. Thanks !!!
Host: Raspberry Pi
Language: Python
import numpy as np
import cv2
import time
# Define the duration (in seconds) of the video capture here
capture_duration = 10
cap = cv2.VideoCapture(0)
# Define the codec and create VideoWriter object
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('output3.avi',fourcc, 20.0, (640,480))
start_time = time.time()
while( int(time.time() - start_time) < capture_duration ):
ret, frame = cap.read()
if ret==True:
frame = cv2.flip(frame,0)
# write the flipped frame
out.write(frame)
else:
break
# Release everything if job is finished
cap.release()
out.release()
cv2.destroyAllWindows()
Upvotes: 3
Views: 11637
Reputation: 6468
You're ignoring two important factors in your code:
Frame count in the while loop:
You want to write 10 seconds of video at 20 frames per second (fps). This gives you a total of 200 frames for the whole video. For this to happen, you'd need to be conscious of the waiting time inside the while loop before each frame is captured and written to file. If you ignore the waiting period, then:
frameCount = 0
while( int(time.time() - start_time) < capture_duration ):
# we assume that all the operations inside the loop take 0 seconds to accomplish.
frameCount = frameCount+1
print('Total frames: ',frameCount)
In the above example, you'll notice that by ignoring waiting time, you'd be writing thousands of frames to video file in 10 seconds. Now 10 seconds of frames at 20 fps would give you 200 frames, to achieve this number of frames you'd need 50 milliseconds of waiting period before each frame is written to the file.
frameCount = 0
while( int(time.time() - start_time) < capture_duration ):
# wait 50 milliseconds before each frame is written.
cv2.waitKey(50)
frameCount = frameCount+1
print('Total frames: ',frameCount)
The total number of frames would be about 200 in the above example.
VideoCapture::read()
is a blocking I/O call:
The cap.read()
function performs two operations, namely VideoCapture::grab()
and VideoCapture::retrieve()
. This function waits for next frame to be grabbed, then decodes and returns the image. The waiting period depends on your camera fps.
So for example if your camera fps is 6, then in 10 secs you'd have captured 60 frames. You've set 20 fps as your VideoWriter
property; 60 frames played as 20 fps gives you about 3 seconds of video.
To see how many frames are captured by your camera in 10 seconds:
frameCount = 0
while( int(time.time() - start_time) < capture_duration ):
# wait for camera to grab next frame
ret, frame = cap.read()
# count number of frames
frameCount = frameCount+1
print('Total frames: ',frameCount)
Upvotes: 3