【问题标题】:OpenCV program freezes after several seconds of executionOpenCV 程序在执行几秒钟后冻结
【发布时间】:2013-03-12 17:06:18
【问题描述】:

我正在使用 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 秒后冻结。任何帮助表示赞赏!

【问题讨论】:

标签: image opencv timer


【解决方案1】:

您应该使用 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;
}

【讨论】:

  • 我试过这个。并且经过几次迭代后相机仍然冻结。似乎试图自己调节相机的 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
  • 上面的代码将永远运行没有问题,并将打印出该块的重复。但是,使用等待语句后,程序将在多次迭代后冻结,我的输出如下所示: Got frame in 0.9138 sec。最大 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
  • 看来问题不在于捕获帧本身,而在于测量时间或更可能与等待功能有关。您在哪个操作系统上尝试过该代码?它是如何冻结的?停止打印消息或仅打印“Got frame...”?
  • 它在 Ubuntu 12.something 上运行。当它冻结时,它会完全停止打印消息,如果我使用 imshow() 那么图片也会冻结。我的第二条评论中的打印输出直接来自它冻结的终端。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多