Setting a frame rate doesn't always work like you expect. It depends on two things:

  1. What your camera is capable of outputting.
  2. Whether the current capture backend you're using supports changing frame rates.

So point (1). Your camera will have a list of formats which it is capable of delivering to a capture device (e.g. your computer). This might be 1920x1080 @ 30 fps or 1920x1080 @ 60 fps and it also specifies a pixel format. The vast majority of consumer cameras do not let you change their frame rates with any more granularity than that. And most capture libraries will refuse to change to a capture format that the camera isn't advertising.

Even machine vision cameras, which allow you much more control, typically only offer a selection of frame rates (e.g. 1, 2, 5, 10, 15, 25, 30, etc). If you want a non-supported frame rate at a hardware level, usually the only way to do it is to use hardware triggering.

And point (2). When you use cv.VideoCapture you're really calling a platform-specific library like DirectShow or V4L2. We call this a backend. You can specify exactly which backend is in use by using something like:

cv2.VideoCapture(0 + cv2.CAP_DSHOW)

There are lots of CAP_X's defined, but only some will apply to your platform (e.g CAP_V4L2 is for Linux only). On Windows, forcing the system to use DirectShow is a pretty good bet. However as above, if your camera only reports it can output 30fps and 60fps, requesting 10fps will be meaningless. Worse, a lot of settings simply report True in OpenCV when they're not actually implemented. You've seen that most of the time reading parameters will give you sensible results though, however if the parameter isn't implemented (e.g exposure is a common one that isn't) then you might get nonsense.

You're better off waiting for a period of time and then reading the last image.

Be careful with this strategy. Don't do this:

while capturing:
    res, image = cap.read()
    time.sleep(1)

you need to make sure you're continually purging the camera's frame buffer otherwise you will start to see lag in your videos. Something like the following should work:

frame_rate = 10
prev = 0

while capturing:

    time_elapsed = time.time() - prev
    res, image = cap.read()

    if time_elapsed > 1./frame_rate:
        prev = time.time()

        # Do something with your image here.
        process_image()

For an application like a hand detector, what works well is to have a thread capturing images and the detector running in another thread (which also controls the GUI). Your detector pulls the last image captured, runs and display the results (you may need to lock access to the image buffer while you're reading/writing it). That way your bottleneck is the detector, not the performance of the camera.

Answer from Josh on Stack Overflow
🌐
LearnOpenCV
learnopencv.com › home › find frame rate (frames per second-fps) in opencv (python/c++)
Find frame rate (frames per second-fps) in OpenCV (Python/C++)
July 31, 2026 - The following narrow update supplies the current runnable path for the correction identified by the audit: Use current CAP_PROP_FPS, monotonic timing, warm-up, successful-frame counting, and invalid-metadata handling. OpenCV’s VideoCapture interface reads from cameras, video files, streams, and image sequences. The active backend determines how capture properties are obtained and what they mean. Calling video.get(cv2.CAP_PROP_FPS) in Python or video.get(cv::CAP_PROP_FPS) in C++ asks the backend for its FPS property.
Discussions

python 3.x - change frame rate in opencv 3.4.2 - Stack Overflow
How do you measure frame rate of camera? I think that you are setting only capture properties (VideoCapture type) instead of real camera settings. After set(cv2.CAP_PROP_FPS, 10) you get frames in 10 rate but camera still work in hight rate. More on stackoverflow.com
🌐 stackoverflow.com
Capture speed / framerate of cv2.VideoCapture - Python - OpenCV
Hi all, I’ve been playing around with python, opencv, a raspberry 4 and a “pi hq cam”. The thing is, the time it takes to capture is really long. The pi cam could, in theory, do 1920x1080@30fps. I’m not aiming for that but what I’m getting is more like 2-3 fps when using videocapture. More on forum.opencv.org
🌐 forum.opencv.org
0
October 16, 2021
Speeding up frame capture in opencv
You're creating a new thread with every single frame. Just creating the threads, let alone doing something in them, is going to be enough to prevent you from getting to 60 fps. Capture frames in one thread, do your processing / motion detection / etc on another. Don't create them as data is coming in, they should be setup and running when you're pulling frames. More on reddit.com
🌐 r/computervision
17
2
January 15, 2020
cv2.VideoCapture() dropping 2 frames per second
Crashes with a None frame error as no more frames arrive. audio, fps, width, height = getVideoMetaData(in_file) print(audio, fps, width, height) cap = cv2.VideoCapture(in_file) frame_num = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) fourcc = cv2.VideoWriter_fourcc(*'mp4v') out = cv2.VideoWriter... More on github.com
🌐 github.com
10
April 19, 2021
🌐
PyImageSearch
pyimagesearch.com › home › blog › faster video file fps with cv2.videocapture and opencv
Faster video file FPS with cv2.VideoCapture and OpenCV - PyImageSearch
April 17, 2021 - Line 15 opens a pointer to the --video file using the cv2.VideoCapture class while Line 16 starts a timer that we can use to measure FPS, or more specifically, the throughput rate of our video processing pipeline. With cv2.VideoCapture instantiated, we can start reading frames from the video file and processing them one-by-one:
Top answer
1 of 6
47

Setting a frame rate doesn't always work like you expect. It depends on two things:

  1. What your camera is capable of outputting.
  2. Whether the current capture backend you're using supports changing frame rates.

So point (1). Your camera will have a list of formats which it is capable of delivering to a capture device (e.g. your computer). This might be 1920x1080 @ 30 fps or 1920x1080 @ 60 fps and it also specifies a pixel format. The vast majority of consumer cameras do not let you change their frame rates with any more granularity than that. And most capture libraries will refuse to change to a capture format that the camera isn't advertising.

Even machine vision cameras, which allow you much more control, typically only offer a selection of frame rates (e.g. 1, 2, 5, 10, 15, 25, 30, etc). If you want a non-supported frame rate at a hardware level, usually the only way to do it is to use hardware triggering.

And point (2). When you use cv.VideoCapture you're really calling a platform-specific library like DirectShow or V4L2. We call this a backend. You can specify exactly which backend is in use by using something like:

cv2.VideoCapture(0 + cv2.CAP_DSHOW)

There are lots of CAP_X's defined, but only some will apply to your platform (e.g CAP_V4L2 is for Linux only). On Windows, forcing the system to use DirectShow is a pretty good bet. However as above, if your camera only reports it can output 30fps and 60fps, requesting 10fps will be meaningless. Worse, a lot of settings simply report True in OpenCV when they're not actually implemented. You've seen that most of the time reading parameters will give you sensible results though, however if the parameter isn't implemented (e.g exposure is a common one that isn't) then you might get nonsense.

You're better off waiting for a period of time and then reading the last image.

Be careful with this strategy. Don't do this:

while capturing:
    res, image = cap.read()
    time.sleep(1)

you need to make sure you're continually purging the camera's frame buffer otherwise you will start to see lag in your videos. Something like the following should work:

frame_rate = 10
prev = 0

while capturing:

    time_elapsed = time.time() - prev
    res, image = cap.read()

    if time_elapsed > 1./frame_rate:
        prev = time.time()

        # Do something with your image here.
        process_image()

For an application like a hand detector, what works well is to have a thread capturing images and the detector running in another thread (which also controls the GUI). Your detector pulls the last image captured, runs and display the results (you may need to lock access to the image buffer while you're reading/writing it). That way your bottleneck is the detector, not the performance of the camera.

2 of 6
7

I could not set the FPS for my camera so I manage to limit the FPS based on time so that only 1 frame per second made it into the rest of my code. It is not exact, but I do not need exact, just a limiter instead of 30fps. HTH

import time

fpsLimit = 1 # throttle limit
startTime = time.time()
cv = cv2.VideoCapture(0)
While True:
    frame = cv.read
    nowTime = time.time()
    if (int(nowTime - startTime)) > fpsLimit:
        # do other cv2 stuff....
        startTime = time.time() # reset time
🌐
OpenCV Q&A Forum
answers.opencv.org › question › 214375 › changing-the-fps-of-a-video
changing the fps of a video? - OpenCV Q&A Forum
You are using two different flags cv2.CV_CAP_PROP_FPS and cv2.CAP_PROP_FPS. The correct flag is cv2.CAP_PROP_FPS and change it to so when setting your cap. ... Read this to understand how FPS works. One way of achieving what you want is to simply add a delay in your loop that reads the frames using ...
🌐
OpenCV
forum.opencv.org › python
Capture speed / framerate of cv2.VideoCapture - Python - OpenCV
October 16, 2021 - Hi all, I’ve been playing around ... theory, do 1920x1080@30fps. I’m not aiming for that but what I’m getting is more like 2-3 fps when using videocapture....
🌐
ProgramCreek
programcreek.com › python › example › 89372 › cv2.CAP_PROP_FPS
Python Examples of cv2.CAP_PROP_FPS
:param cap: OpenCV capture :param time: delta time from launch to skip to :return: index of requested frame """ if thresh is None: thresh = self.extractor.image_dict[key][2] number_of_frames = int(cap.get(cv2.CAP_PROP_FPS) * time) + self.search_switch(cap, key, thresh) number_of_frames = max(number_of_frames, 0) number_of_frames = min(number_of_frames, cap.get(cv2.CAP_PROP_FRAME_COUNT)) cap.set(cv2.CAP_PROP_POS_FRAMES, number_of_frames) return number_of_frames ... def __init__(self, video_source, video_width, video_height, video_fps, queue_size=1): self.video_fps = video_fps vc = cv2.VideoCapt
Find elsewhere
🌐
Quora
quora.com › How-do-I-decrease-the-frames-per-second-in-OpenCV-python
How to decrease the frames per second in OpenCV python - Quora
You just increase the time for which you display each frame. You can do this by increasing the value of the parameter in cv2.WaitKey() ... I want to make a slow motion video using openCV which has the same frame rate as the original speed of 24 FPS.
🌐
Reddit
reddit.com › r/computervision › speeding up frame capture in opencv
r/computervision on Reddit: Speeding up frame capture in opencv
January 15, 2020 -

I'm working on an application in python using opencv for use in athletic coaching. I'd like it to run at 60fps, but I can't seem to get it to that speed. I've determined that the part that is slowing everything down is the capture process; frames aren't getting from the camera to the cpu fast enough. All testing I've done so far indicates that the processing and the rendering are not the bottleneck; it's specifically the video input that is slowing everything down.

Now, I know it is possible for the camera to run at 60fps, because when I open up the same camera in guvcview (at the same resolution), I can get a full 60fps.

I don't want to share my entire project, but here's the part that manages frame capture: https://pastebin.com/nnx32rQK. My main app calls the get_frame() function in its own thread. I'm running this on an intel NUC6CAYH (celeron CPU, 2.3 ghz), running linux.

Any help would be welcome!

EDIT: I went into more detail below, but it looks like having the cap.read() within the Feed class is a whole lot slower than just accessing cap.read() directly..... and I have no idea why

🌐
GeeksforGeeks
geeksforgeeks.org › faster-video-file-fps-with-cv2-videocapture-and-opencv
Faster video file FPS with cv2.VideoCapture and OpenCV - GeeksforGeeks
April 28, 2025 - cap = cv2.VideoCapture('path_of_input_video_file') ... The get() function is used to retrieve the current frames per second (FPS) of the video.
🌐
GeeksforGeeks
geeksforgeeks.org › python-displaying-real-time-fps-at-which-webcam-video-file-is-processed-using-opencv
Python - Displaying real time FPS at which webcam/video file is processed using OpenCV - GeeksforGeeks
January 4, 2023 - Now with the help cv2.putText() method we will be printing the FPS on this frame and then displaying this frame with the help of cv2.imshow() function . Code: Python code implementation of the above mentioned approach ... import numpy as np import cv2 import time # creating the videocapture object # and reading from the input file # Change it to 0 if reading from webcam cap = cv2.VideoCapture('vid.mp4') # used to record the time when we processed last frame prev_frame_time = 0 # used to record the time at which we processed current frame new_frame_time = 0 # Reading the video file until finish
🌐
TutorialsPoint
tutorialspoint.com › get-video-duration-using-opencv-python
Get video duration using OpenCV Python
May 31, 2023 - The library uses NumPy to represent video frames and images as ndarray objects. In this article, we will explore different methods to get video duration using OpenCV Python by leveraging the VideoCapture.get() method with specific property flags. The OpenCV VideoCapture.get() method retrieves specified properties of a video by passing property identifier flags ? ... import cv2 # Create a sample video file path (replace with your video) video_path = 'sample_video.mp4' # Create video capture object cap = cv2.VideoCapture(video_path) # Get video properties fps = cap.get(cv2.CAP_PROP_FPS) total_frames = cap.get(cv2.CAP_PROP_FRAME_COUNT) # Calculate duration in seconds duration_seconds = total_frames / fps print(f"Video Duration: {duration_seconds:.2f} seconds") print(f"Total Frames: {total_frames}") print(f"FPS: {fps}") # Release the video capture object cap.release()
🌐
GitHub
github.com › opencv › opencv › issues › 19930
cv2.VideoCapture() dropping 2 frames per second · Issue #19930 · opencv/opencv
April 19, 2021 - Crashes with a None frame error as no more frames arrive. audio, fps, width, height = getVideoMetaData(in_file) print(audio, fps, width, height) cap = cv2.VideoCapture(in_file) frame_num = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) fourcc = cv2.VideoWriter_fourcc(*'mp4v') out = cv2.VideoWriter...
Author: opencv
🌐
OpenCV
forum.opencv.org › python
When cap.read() is not as fast as the FPS of a camera - Python - OpenCV
October 12, 2021 - Suppose that we have the following code import cv2 import time cap = cv2.VideoCapture('/dev/video0', cv2.V4L2) cap.set(cv2.CAP_PROP_FPS, 30.0) while True: ret, frame = cap.read() time.sleep(0.1) My question is that, what is actually happening ...
🌐
PyImageSearch
pyimagesearch.com › home › blog › increasing webcam fps with python and opencv
Increasing webcam FPS with Python and OpenCV - PyImageSearch
February 20, 2023 - The “secret” to obtaining higher FPS when processing video streams with OpenCV is to move the I/O (i.e., the reading of frames from the camera sensor) to a separate thread. You see, accessing your webcam/USB camera using the cv2.VideoCapture function and the .read() method is a blocking operation.
Top answer
1 of 1
13

You need to know how "video" works. I'll simplify somewhat, relative to some codecs that complicate things.

Video consists of keyframes and P/B-frames. Keyframes are complete images on their own. To decode a P/B-frame, preceding frames need to be decoded first. Some video files consist only of keyframes ("intra"). Some video files consist of a keyframe every ~0.1-10 seconds, and only P/B-frames in between.

You can skip around in a video, but you can only directly skip to keyframes. If you wanted to skip to a non-keyframe, you'd have to first skip to the preceding keyframe, and then decode each following frame, until you're at the destination.

Ideas I would recommend that you not follow:

  • ffmpeg -i INPUT -r 3 OUTPUT would read the entire video, and duplicate/drop frames as needed to achieve 3 frames per second, while maintaining the "speed" of what you see in the video. It would also have to re-encode the result. That's only a sensible option if you need to read the same video repeatedly in that frame rate.

  • Involving GNU Parallel with ffmpeg would be pointless because ffmpeg itself runs its decoding and encoding in parallel (for most codecs), using all available CPU.

Here is what you can do:

use the methods grab and retrieve of VideoCapture. Call grab repeatedly. This does the minimal work to decode a frame and advance in the video. Call retrieve for the frame you actually want. This does the rest of the work and it will give you that frame as an array.

You would have to check the video's fps value using vidcap.get(cv.CAP_PROP_FPS) and then count along and decide if you only need to grab, or both grab and retrieve.

import numpy as np
import cv2 as cv

vidcap = cv2.VideoCapture('/content/2017_08_31_0121.mp4')
assert vidcap.isOpened()

fps_in = vidcap.get(cv.CAP_PROP_FPS)
fps_out = 3

index_in = -1
index_out = -1

while True:
    success = vidcap.grab()
    if not success: break
    index_in += 1

    out_due = int(index_in / fps_in * fps_out)
    if out_due > index_out:
        success, frame = vidcap.retrieve()
        if not success: break
        index_out += 1

        # do something with `frame`

🌐
GitHub
github.com › opencv › opencv-python › issues › 281
set property of cv2.VideoCapture is returning false for cv2.CAP_PROP_FPS · Issue #281 · opencv/opencv-python
January 6, 2020 - if fps rate of a video file is 25 ,i need to read only 10 frames per second so i set fps as 10 using set property cv2.CAP_PROP_FPS , after setting capture.read() only return 10 frames per second · Write here what went wrong. while using ...
Author: opencv
🌐
GitHub
github.com › opencv › opencv › issues › 16844
opencv with the camera framerate 120 FPS · Issue #16844 · opencv/opencv
March 18, 2020 - video.set(cv::CAP_PROP_FOURCC, ... the following instead for OpenCV 3 // double fps = video.get(CAP_PROP_FPS); cout << "Frames per second using video.get(CV_CAP_PROP_FPS) : " << fps << endl; // Number of frames to capture int ...
Author: opencv