2015-12-29 3 views
1

Я хочу захватить кадр из веб-камеры с заданной максимальной частотой кадров в отдельном потоке выполнения с использованием C++.Qt: Получение прошедшего времени функции члена потока

Для этого я использую OpenCV (для веб-камеры) и Qt (для потоковой передачи).

У меня есть поток CameraThread, который запускается в главном потоке программы, которая запускает камеру, а затем непрерывно вызывает CameraThread::getFrame() через время цикла:

void CameraThread::getFrame(VideoCapture& cap) 
{ 
    QElapsedTimer timer; 
    timer.start(); 

    Mat frame; 
    cap >> frame; 

    // add frame to queue for processing 
    image_queue->add(frame); 

    int elapsed = timer.elapsed(); 

    int min_time = ceil(1000.0/frame_rate); // min_time in ms, frame_rate in fps 
    int time_left = min_time - elapsed; 
    if (time_left > 0) 
     msleep(time_left); 

    cout << "elapsed=" << elapsed << "ms "; 
    cout << "time_left=" << time_left << "ms" << endl; 
} 

Однако, если установить (например) frame_rate в 1 кадров в секунду, то типичный выход выше функции:

elapsed=300ms time_left=700ms 
elapsed=8ms time_left=992ms 
elapsed=7ms time_left=993ms 
elapsed=7ms time_left=993ms 
elapsed=8ms time_left=992ms 
elapsed=7ms time_left=993ms 
elapsed=7ms time_left=993ms 
... etc 

в QElapsedTimer винты вверх после первого вызова CameraThread::getFrame().

Похоже, что виновником является звонок msleep(). Когда я удаляю этот вызов, QElapsedTimer работает нормально (~ 30 мс, что соответствует частоте кадров камеры по умолчанию 30 кадров в секунду). Тем не менее, я требую, чтобы CameraThread спал в течение определенного периода времени, чтобы обеспечить максимальную частоту кадров.

Как решить эту проблему?

+0

Я не вижу никаких проблем. Это выглядит так, как будто первая картина занимает больше времени, чем все последующие, что легко объясняется эффектами кеширования. Как часто функция выводит строку, как в приведенном выше выводе? Я бы ожидал одну такую ​​линию в секунду. –

+1

Помимо того, что вы должны * никогда не называть 'msleep', в чем проблема? Вы пробовали копаться в том, почему первый кадр занимает больше времени? Может быть, если вы не спите, вы застряли в фрейме 'cap >>, ожидающем следующего кадра, а если вы спятите фрейм, он будет готов, поэтому чтение + обработка занимает очень короткое время? – peppe

+0

(Помимо этого: обратите внимание, что 'QElapsedTimer' имеет 64-разрядный API). – peppe

ответ

-1

У меня нет идей, в чем проблема с QElapsedTimer, но может быть, вы можете использовать QTime? Он имеет те же методы

void QTime::start(); 
int QTime::elapsed() const; 
+0

Это очень плохая идея, поскольку 'QTime' не является монотонным вообще. – peppe

+0

Я пробовал это раньше с диагностической точки зрения, однако это привело к той же проблеме. – Josh

0

Вместо msleep вы могли бы создать QTimer снаружи, если ваш метод:

QTimer* timer = new QTimer(this); 
timer->setInterval(ceil(1000.0/frame_rate)); 
connect(timer, &QTimer::timeout, this, [this](){ 
    getFrame(cap); 
}); 
timer->start(); 
Смежные вопросы