Measure OpenCV FPS

后端 未结 4 1252
别那么骄傲
别那么骄傲 2021-02-08 19:32

I\'m looking for a correct way to measure openCV FPS. I\'ve found several ways to do it. but none of them looks right for me.

The first one I\'ve tested, uses ti

相关标签:
4条回答
  • 2021-02-08 20:13

    I would just measure the walltime and simply divide the frames by time elapsed. On linux:

    /*
    * compile with:
    *   g++ -ggdb webcam_fps_example2.cpp -o webcam_fps_example2 `pkg-config --cflags --libs opencv`
    */
    
    #include "opencv2/opencv.hpp"
    #include <time.h>
    #include <sys/time.h>
    
    
    using namespace cv;
    using namespace std;
    
    double get_wall_time(){
        struct timeval time;
        if (gettimeofday(&time,NULL)){
            //  Handle error
            return 0;
        }
        return (double)time.tv_sec + (double)time.tv_usec * .000001;
    }
    
    
    int main(int argc, char** argv)
    {
        VideoCapture cap;
        // open the default camera, use something different from 0 otherwise;
        // Check VideoCapture documentation.
        if(!cap.open(0))
            return 0;
    
        cap.set(CV_CAP_PROP_FRAME_WIDTH,1920);
        cap.set(CV_CAP_PROP_FRAME_HEIGHT,1080);
    
        double wall0 = get_wall_time();
        for(int x = 0; x < 500; x++)
        {
              Mat frame;
              cap >> frame;
              if( frame.empty() ) break; // end of video stream
              //imshow("this is you, smile! :)", frame);
              if( waitKey(10) == 27 ) break; // stop capturing by pressing ESC 
        }
        double wall1 = get_wall_time();
        double fps = 500/(wall1 - wall0);
        cout << "Wall Time = " << wall1 - wall0 << endl;
        cout << "FPS = " << fps << endl;
        // the camera will be closed automatically upon exit
        // cap.close();
        return 0;
    }
    

    Wall Time = 43.9243 FPS = 11.3832

    0 讨论(0)
  • 2021-02-08 20:19

    You can use OpenCV's API to get the original FPS if you are dealing with video files. The following method will not work when capturing from a live stream:

    cv::VideoCapture capture("C:\\video.avi");
    if (!capture.isOpened())
    {
        std::cout  << "!!! Could not open input video" << std::endl;
        return;
    }
    
    std::cout << "FPS: " << capture.get(CV_CAP_PROP_FPS) << std::endl;
    

    To get the actual FPS after the processing, you can try Zaw's method.

    0 讨论(0)
  • 2021-02-08 20:26

    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;
    }    
    
    0 讨论(0)
  • 2021-02-08 20:28

    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;
    }
    
    0 讨论(0)
提交回复
热议问题