我正在寻找一种测量openCV FPS的正确方法。我找到了几种方法。但是他们都不适合我。
我测试的第一个,使用 time_t start和time_t end 。一旦它返回一个转储函数作为fps x时间图(我真的无法想象fps图如何成为转储函数),我认为一个是错误的。
这是该图的图像。
我测试的第二个使用 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方法执行程序!
答案 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