2015-12-29 32 views
1

我希望在使用C++的單獨執行線程內以指定的最大幀速率從網絡攝像機獲取幀。Qt:獲取線程的成員函數的消逝時間

爲此,我使用OpenCV(用於攝像頭)和Qt(用於線程)。

我有一個線程CameraThread這是該程序的主線程中啓動啓動相機,然後通過while循環不斷呼籲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似乎按預期工作(約30ms,這對應於30fps的相機的默認幀速率)。但是,我要求CameraThread在指定的時間段內休眠以確保遵守最大幀速率。

如何解決此問題?

+0

我看不出有什麼問題。它看起來好像第一張照片比後面的所有照片都要花費更長的時間,這很容易用緩存效果來解釋。函數多長時間輸出一行,如上面引用的輸出一樣?我希望每秒鐘有一行這樣的行。 –

+1

除了你應該*永遠不*調用'msleep'這個事實之外,實際的問題是什麼?你有沒有嘗試挖掘爲什麼第一幀需要更長的時間?也許如果你不睡覺,你會陷入'cap >> frame'等待下一幀,而如果你睡了一幀就立即準備好,所以讀取+處理它需要很短的時間? – 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();