0

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

4

1 回答 1

0

您应该使用 CLOCK_MONOTONIC 而不是 CLOCK_REALTIME 请参阅理解 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;
}
于 2013-03-13T00:21:50.677 回答