I am trying to get the fps from my camera so that I can pass it to the VideoWriter
for outputting the video. However, I am getting 0 fps by calling VideoC
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.