0

私はOpenCVを使用してC++でプログラムを実行しています。このプログラムは、カメラの画像を読み取ってから、いくつかの処理を実行します。できるだけ速く動かすだけで、カメラは15FPSで動作します。カメラを使用して、FPSを10FPSなどの選択した数に調整しようとしています。これを行うためにタイマーを使用しています(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)に近い値を出力する必要があります。しかし、コンソールは1秒に1回、奇妙な数値を示します:18446744072800674356。前述のように、カメラの画像コードをコメントアウトすると、タイマーはそれ自体で正常に動作します(それでもその膨大な数値を出力しますが、永久に実行されます)。また、タイマーコードをコメントアウトすると、カメラは15FPSで問題なく動作します。ただし、コードを一緒に実行すると、約3秒後にフリーズします。どんな助けでも大歓迎です!

4

1 に答える 1

0

CLOCK_REALTIMEの代わりに CLOCK_MONOTONIC を使用する必要があります。

これが私のタスクの実装です:

#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 に答える