OpenCV: VideoCapture::get(CV_CAP_PROP_FPS) returns 0 FPS OpenCV: VideoCapture::get(CV_CAP_PROP_FPS) returns 0 FPS windows windows

OpenCV: VideoCapture::get(CV_CAP_PROP_FPS) returns 0 FPS


CV_CAP_PROP_FPS only works on videos as far as I know. If you want to capture video data from a webcam you have to time it correctly yourself. For example use a timer to capture a frame from the webcam every 40ms and then save as 25fps video.


You can use VideoCapture::set(CV_CAP_PROP_FPS) to set the desired FPS for a webcam. However, you can't use get for some reason.

Note that sometimes the driver will choose a different FPS than what you have requested depending on the limitations of the webcam.

My workaround: capture frames during a few seconds (4 is fine in my tests, with 0.5 seconds of initial delay), and estimate the fps the camera outputs.


I've never observed CV_CAP_PROP_FPS to work. I have tried with various flavors of OpenCV 2.4.x (currently 2.4.11) using file inputs.

As a workaround in one scenario, I directly used libavformat (from ffmpeg) to get the frame rate, which I can then use in my other OpenCV code:

static double get_frame_rate(const char *filePath) {    AVFormatContext *gFormatCtx = avformat_alloc_context();    av_register_all();    if (avformat_open_input(&gFormatCtx, filePath, NULL, NULL) != 0) {        return -1;    } else if (avformat_find_stream_info(gFormatCtx, NULL) < 0) {        return -1;    }     for (int i = 0; i < gFormatCtx->nb_streams; i++) {        if (gFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {            AVRational rate = gFormatCtx->streams[i]->avg_frame_rate;            return (double)av_q2d(rate);        }    }    return -1;}

Aside from that, undoubtedly one of the slowest possible (although sure to work) methods to get the average fps, would be to step through each frame and divide the current frame number by the current time:

for (;;) {    currentFrame = cap.get(CV_CAP_PROP_POS_FRAMES);    currentTime = cap.get(CV_CAP_PROP_POS_MSEC);    fps = currentFrame / (currentTime / 1000);    # ... code ...    # stop this loop when you're satisfied ...}

You'd probably only want to do the latter if the other methods of directly finding the fps failed, and further, there were no better way to summarily get overall duration and frame count information.

The example above works on a file -- to adapt to a camera, you could use elapsed wallclock time since beginning of capture, instead of getting CV_CAP_PROP_POS_MSEC. Then the average fps for the session would be the elapsed wall clock time divided by the current frame number.