Python – cv2. The output of VideoWriter is incorrect. Faster

cv2. The output of VideoWriter is incorrect. Faster… here is a solution to the problem.

cv2. The output of VideoWriter is incorrect. Faster

I’m trying CV2 with OpenCV. VideoWriter to record a video at a specific time. The problem is that the output is incorrect. For example, a 10-second video only gets 2 seconds, and it plays faster like acceleration.
Here is my code. Any suggestions or ideas are welcome. Also, another problem is that the output video is silent. Thank you !!!

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()

Solution

You overlooked two important factors in your code:

Number of frames in a while loop:

You want to write a 10-second video at 20 frames per second (fps). This provides a total of 200 frames for the entire video. To do this, you need to pay attention to the wait time inside the while loop before capturing each frame and writing it to the file. If the waiting period is ignored, 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 example above, you’ll notice that ignoring the wait time, you’ll write thousands of frames to a video file in 10 seconds. Now a 10-second frame of 20 fps will give you 200 frames, and to reach this number of frames, you need to wait 50 milliseconds before writing each frame to a 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)

In the example above, the total number of frames is approximately 200.

VideoCapture::read() is a blocking I/O call:

The cap.read() function performs two operations, VideoCapture::grab() and VideoCapture::retrieve(). This function waits for the next frame to be grabbed, then decodes and returns the image. The waiting time depends on your camera fps.

So, for example, if your camera fps is 6, then you will shoot 10 frames in 60 seconds. You have set 20 fps to the VideoWriter property; Playing 20 frames at 60 fps gives you about 3 seconds of video.

To see how many frames your camera shot 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)

Related Problems and Solutions