2013-03-12 43 views
0

我正在C++中运行一个OpenCV程序,该程序读取摄像头图像,然后执行一些操作。如果我让它以最快速度运行,相机将以15 FPS的速度运行。我正在尝试使用相机来调节FPS到我选择的数量,如10 FPS。我正在使用计时器来完成此操作(timepec对象和clock_gettime()函数调用)。自行运行的时钟工作正常,摄像头本身运行良好,但是当我尝试每隔100 ms自行抓取一帧时,程序将运行大约3秒钟,然后完全冻结。这是我的代码中的while循环:OpenCV程序在执行几秒钟后死机

/* 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纳秒)的数据。但是控制台每秒钟给出一个奇怪的数字:18446744072800674356.正如我前面提到的,注释掉相机图像代码,计时器可以自行工作(它仍然会打印出那么大的数字,但它会永远运行)。如果我注释掉计时器代码,摄像机将以15 FPS运行,没有问题。但是,当我将代码一起运行时,约3秒后会冻结。任何帮助表示赞赏!

+0

请问,如果你把'cvWaitKey(90),它的工作'权的if语句之外? (请参阅http://opencv.willowgarage.com/wiki/documentation/c/highgui/WaitKey) – 2013-03-12 17:44:55

+0

不,它的行为与if语句内部或外部的cvWaitKey()相同。 – keithbhunter 2013-03-12 19:28:34

回答

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; 
} 
+0

我试过了。并且相机在几次迭代后仍然冻结。似乎试图通过我自己来调节相机的FPS会导致它冻结。 这里是没有等待功能的终端输出(整个if(delta> 0)注释掉): 在0.0067秒内获得帧。最大FPS:149.93 在0.0067秒内得到帧。最大FPS:150.10 在0.0067秒内获得帧数。最大FPS:150.10 在0.0067秒内获得帧数。最大FPS:149.90 在0.0067秒内得到帧。最大FPS:150.09 在0.0067秒内得到帧。最大FPS:150.19 在0.9067秒获得帧。最大FPS:1.10 – keithbhunter 2013-03-13 13:49:23

+0

上述内容将永久运行,不会出现任何问题,并会打印出该块的重复内容。然而,等待声明中,程序会在几次迭代后冻结,而我的输出如下所示: 在0.9138秒内获得了帧。最大FPS:1.09 在0.0065秒内得到帧。最大FPS:153.34 等待:目标0.0601秒。实际0.0602 在0.0001秒内得到帧。最大FPS:13717.44 等待:目标0.0666秒。实际0.9666 在0.0001秒内得到帧。最大FPS:13854.56 等待:目标0.0666秒。实际0.9666 在0.0001秒内得到帧。最大FPS:12242.85 等待:目标0.0666秒。实际0.0666 – keithbhunter 2013-03-13 13:53:57

+0

这似乎不是捕捉帧本身的问题,但与测量时间或更多可能与等待功能。你试过哪些操作系统?它如何冻结?停止打印消息或只打印“Got frame ...”? – 2013-03-13 15:51:20