Changing FPS in OpenCV

Question:

I have a technical application that needs to capture a few frames per second. Setting the videowriter in the below code to 3 frames per second results in the webcam’s normal framerate of approximately 30 fps being saved.
What are the options to save the recorded 3 frames per second, and let the other 27 or so go? Thanks in advance.

import cv2
import numpy as np
import time
import datetime
import pathlib
import imutils

cap = cv2.VideoCapture(0)

if (cap.isOpened() == False): 
  print("Unable to read camera feed")

capture_duration = 15
frame_per_sec = 3
frame_width = 80
frame_height = 60

out = cv2.VideoWriter('C:\Users\student\Desktop\videoFile.avi',cv2.VideoWriter_fourcc('m','j','p','g'),frame_per_sec, (frame_width,frame_height))

start_time = time.time()
while( int(time.time() - start_time) < capture_duration ):
    ret, frame = cap.read()
    if ret==True:
        frame = imutils.resize(frame, width=frame_width)
        out.write(frame)
        cv2.imshow('frame',frame) 
        if cv2.waitKey(1) & 0xFF == ord('q'):
          break
    else:
        break

cap.release()
out.release()
 
cv2.destroyAllWindows()
Asked By: portsample

||

Answers:

You set the FPS for the output via the VideoWriter,
but you didn’t attempt to set the FPS for the input via the VideoCapture.

In order to do that you can try to call cv2.VideoCapture, with the cv2.CAP_PROP_FPS property after you create cap.
For example:

cap.set(cv2.CAP_PROP_FPS, 3)

However – note that the actual behavior is dependant on the specific capture device you are using. Some support only certain FPSs. See also this post regarding it: change frame rate in opencv 3.4.2.

If it does work you will be able to simplify your code a lot – just capture frames, process them and save (without any manual fps management).

Answered By: wohlstad

This method programmatically sets frames per second. A 6.1mb file was created when frame rate was set for 30fps, and a 0.9mb file when set for 3fps.

#!/usr/bin/env python3

import cv2
import numpy as np
import time
import datetime
import pathlib
import imutils

cap = cv2.VideoCapture(0)

if (cap.isOpened() == False): 
  print("Unable to read camera feed")

capture_duration = 15
frame_per_sec = 30
prev = 0
frame_width = int(cap.get(3))
frame_height = int(cap.get(4))
out = cv2.VideoWriter('C:\videoPy\LZ\'outpout.avi',cv2.VideoWriter_fourcc('m','j','p','g'),frame_per_sec, (frame_width,frame_height))
start_time = time.time()
while( int(time.time() - start_time) < capture_duration ): 
#start fps
  time_elapsed = time.time() - prev
  while(time_elapsed > 1./frame_per_sec):                   
        ret, frame = cap.read()
        if not ret:
            break
        if time_elapsed > 1./frame_per_sec:
          prev = time.time()
#end fps
        if ret==True:
          frame = imutils.resize(frame, width=frame_width)
          out.write(frame)
          cv2.imshow('frame',frame) 
        if cv2.waitKey(1) & 0xFF == ord('q'):
          break
        else:
           break

cap.release()
out.release()
 
cv2.destroyAllWindows()
Answered By: portsample