测量OpenCV FPS

时间:2014-03-03 14:05:53

标签: c++ opencv

我正在寻找一种测量openCV FPS的正确方法。我找到了几种方法。但是他们都不适合我。

我测试的第一个,使用 time_t start和time_t end 。一旦它返回一个转储函数作为fps x时间图(我真的无法想象fps图如何成为转储函数),我认为一个是错误的。

这是该图的图像。

FPS PLOT

我测试的第二个使用 t =(double)cvGetTickCount()来测量fps。一旦它返回120 fps,这种方式是错误的,但是,对于30秒长度,以120 fps捕获的视频不应该花费超过1分钟来处理。所以这是衡量FPS的错误方法。

有人知道在openCV中测量FPS的另一种方法吗?

聚苯乙烯。我正试图在视频的每一帧中找到圆圈。视频帧尺寸为320x240像素。

更新2 我正在尝试测量FPS的代码。

有(;;)     {

    clock_t start=CLOCK();

    Mat frame, finalFrame;
    capture >> frame; 

    finalFrame = frame;

    cvtColor(frame, frame, CV_BGR2GRAY);

    GaussianBlur(frame, frame, Size(7,7), 1.5, 1.5);
    threshold(frame, frame, 20, 255, CV_THRESH_BINARY);

    dilate(frame, frame, Mat(), Point(-1, -1), 2, 1, 1);
    erode(frame, frame, Mat(), Point(-1, -1), 2, 1, 1);

    Canny(frame, frame, 20, 20*2, 3 );

    vector<Vec3f> circles;

    findContours(frame,_contours,_storage,CV_RETR_CCOMP,CV_CHAIN_APPROX_SIMPLE );

    vector<vector<Point> > contours_poly( _contours.size() );
    vector<Rect> boundRect( _contours.size() );
    vector<Point2f>center( _contours.size() );
    vector<float>radius( _contours.size() );


    int temp = 0;

    for( int i = 0; i < _contours.size(); i++ )
    { 
        if( _contours[i].size() > 100 )
        {
           approxPolyDP( Mat(_contours[i]), contours_poly[i], 3, true );
           boundRect[i] = boundingRect( Mat(_contours[i]) );
           minEnclosingCircle( (Mat)_contours[i], center[i], radius[i] );
           temp = i;
           break;
        }
    }



    double dur = CLOCK()-start;
        printf("avg time per frame %f ms. fps %f. frameno = %d\n",avgdur(dur),avgfps(),frameno++ );

    frameCounter++;

    if(frameCounter == 3600)
    break;

    if(waitKey(1000/120) >= 0) break;
}

更新

使用Zaw Lin方法执行程序! enter image description here

4 个答案:

答案 0 :(得分:8)

我已经发布了一种方法@ Getting current FPS of OpenCV。有必要做一些平均,否则fps会太疯狂。

修改

我在进程中放入了一个Sleep(),它给出了正确的fps和持续时间(+/- 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;
}    

答案 1 :(得分:1)

如果您正在处理视频文件,可以使用OpenCV的API获取原始FPS。从实时流中捕获时,以下方法无效:

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;

要在处理后获得实际的FPS,您可以尝试使用Zaw的方法。

答案 2 :(得分:0)

您可以使用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;
}

答案 3 :(得分:0)

我只需要测量时间,然后简单地将帧数除以经过的时间即可。在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;
}

入墙时间= 43.9243 FPS = 11.3832