我正在使用OpenCV在C ++中运行一个程序,它读取摄像机图像,然后执行一些操作。如果我让它以尽可能快的速度运行,相机的运行速度为15 FPS。我正在尝试使用相机将FPS调节到我选择的数量,例如10 FPS。我正在使用计时器来执行此操作(timespec对象和clock_gettime()函数调用)。单独运行的时钟工作正常,相机本身运行正常,但是当我尝试每100毫秒自己抓一帧时,程序将运行大约3秒钟,然后完全冻结。这是我的代码中的while循环:
/* Start the timer */
clock_gettime(CLOCK_REALTIME, &ts);
startBit = ts.tv_nsec;
/* Show the image captured from the camera in the window and repeat */
while (1) { // main while loop
clock_gettime(CLOCK_REALTIME, &ts);
endBit = ts.tv_nsec;
if (endBit-startBit >= 100000000) { // > 100 ms
fprintf(stderr, "%lu\n", endBit-startBit);
clock_gettime(CLOCK_REALTIME, &ts);
startBit = ts.tv_nsec; // reset timer
IplImage* frame = cvQueryFrame(capture); // Get one frame
Mat limage(frame); // convert IplImage to Mat
if (!frame) {
fprintf(stderr, "ERROR: frame is null...\n");
getchar();
break;
}
cvWaitKey(90);
}
}
程序将在控制台上打印已经过去的时间。它现在的设置方式应该始终打印接近100毫秒(100000000 ns)的东西。但是控制台每秒钟给出一个奇怪的数字:18446744072800674356.正如我之前提到的,评论出相机图像代码,计时器本身可以正常工作(它仍会打印出那么大的数字,但它会永远运行)。如果我注释掉定时器代码,相机将以15 FPS运行,没有任何问题。但是,当我一起运行代码时,它会在大约3秒钟后冻结。任何帮助表示赞赏!
答案 0 :(得分:0)
您应该使用CLOCK_MONOTONIC代替CLOCK_REALTIME,请参阅Problem of understanding clock_gettime。
以下是我执行的任务:
#include <opencv2/opencv.hpp>
#include <time.h>
int wait(double time) {
timespec ts;
ts.tv_sec = int(time);
ts.tv_nsec = int(10e+9*time);
nanosleep(&ts, (struct timespec *)NULL);
}
double getclock() {
timespec ts;
clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
return ts.tv_sec + double(ts.tv_nsec)/10e+9;
}
int main() {
//cv::VideoCapture capture(0);
cv::VideoCapture capture("video.mp4");
double fps = 30.0;
cv::Mat frame;
while (1) {
double const c1 = getclock();
capture >> frame;
double const frame_time = getclock()-c1;
fprintf(stderr, "Got frame in %.4f sec. max FPS: %.2f\n", frame_time, 1/frame_time);
double const delta = 1.0/fps - frame_time;
double wait_time = 0;
if (delta > 0) {
double const c2 = getclock();
wait(delta);
wait_time = getclock()-c2;
fprintf(stderr, "wait: target %.4fsec. actual %.4f\n", delta, wait_time);
}
double const while_time = wait_time + frame_time;
fprintf(stderr, "Show frame in %.4f sec. FPS: %.2f.\n\n", while_time, 1/while_time);
}
return 0;
}