2017-05-08 52 views
0

我目前正在開發大腦視覺皮層的刺激提供者,作爲大學項目的一部分。該程序將(最好)用C++編寫,利用visual studio和OpenCV。它應該工作的方式是程序創建了多個線程,相應的不同頻率的數量,每個線程都運行一個定時器來滿足它們各自的頻率。 的代碼看起來像這樣至今:以特定頻率切換圖像C++

void timerThread(void *param) { 
t *args = (t*)param; 
int id = args->data1; 
float freq = args->data2; 
unsigned long period = round((double)1000/(double)freq)-1; 

while (true) { 
    Sleep(period); 
    show[id] = 1; 
    Sleep(period); 
    show[id] = 0; 
} 
} 

這似乎對某些頻率的工作不錯,但其他人有很大不同了很多的幀速率。我嘗試着研究創建自己的定時功能,類似於Arduino的「blinkWithoutDelay」功能,儘管這非常糟糕。另外,我已經嘗試過使用waitKey()函數,這很像現在使用的Sleep()函數。

任何幫助將不勝感激!

+1

您所提供的代碼是不足以說明問題:這是什麼'秀[id]'用於? – Antonio

+0

什麼樣的頻率能夠很好地工作,哪些頻率有問題?你的好壞是什麼? 「show」是什麼類型? – Useless

+0

'(double)1000 /(double)freq' ==>'1000.0/freq' –

回答

0

您應該使用計時器而不是「睡眠」來解決此問題,因爲有時候循環可能需要更多或更少的時間才能完成。

在循環開始時重新啓動定時器,並在復位前取其值 - 這會給你完成循環所用的時間。 如果此時間大於「期間」值,則表示您遲到了,您需要立即執行(甚至會降低下一個循環的週期)。否則,如果它更低,那麼意味着你需要等到它更大。 我個人不喜歡睡覺,而是經常重新啓動計時器,直到它更大。

我建議尋找「固定時間步長」代碼,如下面的代碼。您需要將這段代碼放在每個線程中,使用期間(ns)的不同值,並將代碼放在「doUpdates()」的位置。

如果你需要一個「定時器」庫,由於我不知道OpenCV,我推薦使用SFMLSFML's timer docs)。

下面的代碼是從here

long int start = 0, end = 0; 
double delta = 0; 
double ns = 1000000.0/60.0; // Syncs updates at 60 per second (59 - 61) 
while (!quit) { 
    start = timeAsMicro(); 
    delta+=(double)(start - end)/ns; // You can skip dividing by ns here and do "delta >= ns" below instead // 
    end = start; 

    while (delta >= 1.0) { 
     doUpdates(); 
     delta-=1.0; 
    } 
} 

請介意的事實,在此代碼,計時器永遠不會復位。

(這可能不完全準確,但最好的假設,我可以解決您的問題給你提供的代碼)

+0

感謝您的回答,我會嘗試着看看那個庫! –