I have posted a way to do that @ Getting current FPS of OpenCV. It is necessary to do a bit of averaging otherwise the fps will be too jumpy.
edit
I have put a Sleep inside process() and it gives correct fps and duration(+/- 1ms).
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <opencv/cv.h>
#include <sys/timeb.h>
using namespace cv;
#if defined(_MSC_VER) || defined(WIN32) || defined(_WIN32) || defined(__WIN32__) \
|| defined(WIN64) || defined(_WIN64) || defined(__WIN64__)
#include <windows.h>
bool _qpcInited=false;
double PCFreq = 0.0;
__int64 CounterStart = 0;
void InitCounter()
{
LARGE_INTEGER li;
if(!QueryPerformanceFrequency(&li))
{
std::cout << "QueryPerformanceFrequency failed!\n";
}
PCFreq = double(li.QuadPart)/1000.0f;
_qpcInited=true;
}
double CLOCK()
{
if(!_qpcInited) InitCounter();
LARGE_INTEGER li;
QueryPerformanceCounter(&li);
return double(li.QuadPart)/PCFreq;
}
#endif
#if defined(unix) || defined(__unix) || defined(__unix__) \
|| defined(linux) || defined(__linux) || defined(__linux__) \
|| defined(sun) || defined(__sun) \
|| defined(BSD) || defined(__OpenBSD__) || defined(__NetBSD__) \
|| defined(__FreeBSD__) || defined __DragonFly__ \
|| defined(sgi) || defined(__sgi) \
|| defined(__MACOSX__) || defined(__APPLE__) \
|| defined(__CYGWIN__)
double CLOCK()
{
struct timespec t;
clock_gettime(CLOCK_MONOTONIC, &t);
return (t.tv_sec * 1000)+(t.tv_nsec*1e-6);
}
#endif
double _avgdur=0;
double _fpsstart=0;
double _avgfps=0;
double _fps1sec=0;
double avgdur(double newdur)
{
_avgdur=0.98*_avgdur+0.02*newdur;
return _avgdur;
}
double avgfps()
{
if(CLOCK()-_fpsstart>1000)
{
_fpsstart=CLOCK();
_avgfps=0.7*_avgfps+0.3*_fps1sec;
_fps1sec=0;
}
_fps1sec++;
return _avgfps;
}
void process(Mat& frame)
{
Sleep(3);
}
int main(int argc, char** argv)
{
int frameno=0;
cv::Mat frame;
cv::VideoCapture cap(0);
for(;;)
{
//cap>>frame;
double start=CLOCK();
process(frame);
double dur = CLOCK()-start;
printf("avg time per frame %f ms. fps %f. frameno = %d\n",avgdur(dur),avgfps(),frameno++ );
if(waitKey(1)==27)
exit(0);
}
return 0;
}
Answer from Zaw Lin on Stack OverflowI have posted a way to do that @ Getting current FPS of OpenCV. It is necessary to do a bit of averaging otherwise the fps will be too jumpy.
edit
I have put a Sleep inside process() and it gives correct fps and duration(+/- 1ms).
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <opencv/cv.h>
#include <sys/timeb.h>
using namespace cv;
#if defined(_MSC_VER) || defined(WIN32) || defined(_WIN32) || defined(__WIN32__) \
|| defined(WIN64) || defined(_WIN64) || defined(__WIN64__)
#include <windows.h>
bool _qpcInited=false;
double PCFreq = 0.0;
__int64 CounterStart = 0;
void InitCounter()
{
LARGE_INTEGER li;
if(!QueryPerformanceFrequency(&li))
{
std::cout << "QueryPerformanceFrequency failed!\n";
}
PCFreq = double(li.QuadPart)/1000.0f;
_qpcInited=true;
}
double CLOCK()
{
if(!_qpcInited) InitCounter();
LARGE_INTEGER li;
QueryPerformanceCounter(&li);
return double(li.QuadPart)/PCFreq;
}
#endif
#if defined(unix) || defined(__unix) || defined(__unix__) \
|| defined(linux) || defined(__linux) || defined(__linux__) \
|| defined(sun) || defined(__sun) \
|| defined(BSD) || defined(__OpenBSD__) || defined(__NetBSD__) \
|| defined(__FreeBSD__) || defined __DragonFly__ \
|| defined(sgi) || defined(__sgi) \
|| defined(__MACOSX__) || defined(__APPLE__) \
|| defined(__CYGWIN__)
double CLOCK()
{
struct timespec t;
clock_gettime(CLOCK_MONOTONIC, &t);
return (t.tv_sec * 1000)+(t.tv_nsec*1e-6);
}
#endif
double _avgdur=0;
double _fpsstart=0;
double _avgfps=0;
double _fps1sec=0;
double avgdur(double newdur)
{
_avgdur=0.98*_avgdur+0.02*newdur;
return _avgdur;
}
double avgfps()
{
if(CLOCK()-_fpsstart>1000)
{
_fpsstart=CLOCK();
_avgfps=0.7*_avgfps+0.3*_fps1sec;
_fps1sec=0;
}
_fps1sec++;
return _avgfps;
}
void process(Mat& frame)
{
Sleep(3);
}
int main(int argc, char** argv)
{
int frameno=0;
cv::Mat frame;
cv::VideoCapture cap(0);
for(;;)
{
//cap>>frame;
double start=CLOCK();
process(frame);
double dur = CLOCK()-start;
printf("avg time per frame %f ms. fps %f. frameno = %d\n",avgdur(dur),avgfps(),frameno++ );
if(waitKey(1)==27)
exit(0);
}
return 0;
}
You can use opencv helper cv::getTickCount()
#include <iostream>
#include <string>
#include "opencv2/core.hpp"
#include "opencv2/core/utility.hpp"
#include "opencv2/video.hpp"
#include "opencv2/highgui.hpp"
using namespace cv;
int main(int ac, char** av) {
VideoCapture capture(0);
Mat frame;
for (;;) {
int64 start = cv::getTickCount();
capture >> frame;
if (frame.empty())
break;
/* do some image processing here */
char key = (char)waitKey(1);
double fps = cv::getTickFrequency() / (cv::getTickCount() - start);
std::cout << "FPS : " << fps << std::endl;
}
return 0;
}
c++ - How to calculate Frame Per Second in opencv? - Stack Overflow
c++ - How to calculate FPS of a live video stream using Chrono and OpenCV? - Stack Overflow
c++ - How to calculate the fps of a video (with processing) using opencv - Stack Overflow
algorithm - How to find framerate of video using c++ opencv 2.4.10? - Stack Overflow
Something like this may help.
#include <iostream>
#include <opencv2/opencv.hpp> //for opencv3
#include <opencv/cv.hpp> //for opencv2
int main(int argc, const char * argv[]) {
cv::VideoCapture video("video.mp4");
double fps = video.get(cv::CAP_PROP_FPS);
std::cout << "Frames per second : " << fps << std::endl;
video.release();
return 0;
}
You must have a loop in your code where you are doing all the video processing.
Let's say you have something similar to this pseudocode:
//code initialization
cv::VideoCapture cap("some-video-uri");
//video capture/processing loop
while (1)
{
//here we take the timestamp
auto start = std::chrono::system_clock::now();
//capture the frame
cap >> frame;
//do whatever frame processing you are doing...
do_frame_processing();
//measure timestamp again
auto end = std::chrono::system_clock::now();
//end - start is the time taken to process 1 frame, output it:
std::chrono::duration<double> diff = end-start;
std::cout << "Time to process last frame (seconds): " << diff.count()
<< " FPS: " << 1.0 / diff.count() << "\n";
}
thats it ... take into account that calculating FPS in a frame-per-frame basis will likely produce a highly variant result. You should average this result for several frames in order to get a less variant FPS.