2017-05-08 2 views
0

Je développe actuellement un stimuli pour le cortex visuel du cerveau dans le cadre d'un projet universitaire. Le programme doit (de préférence) être écrit en C++, en utilisant Visual Studio et OpenCV. La façon dont il est censé fonctionner est que le programme crée un certain nombre de threads, en fonction de la quantité de fréquences différentes, chacune exécutant une minuterie pour leur fréquence respective. Le code ressemble à ceci jusqu'à présent:Commutation d'une image à des fréquences spécifiques 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; 
} 
} 

Il semble fonctionner très bien pour certaines des fréquences, mais d'autres varient beaucoup dans le taux de trame. J'ai essayé de créer ma propre fonction de synchronisation, similaire à celle de la fonction "blinkWithoutDelay" d'Arduino, même si cela a très mal fonctionné. En outre, j'ai essayé avec la fonction waitKey(), cela a fonctionné tout comme la fonction Sleep() utilisée maintenant.

Toute aide serait grandement appréciée!

+1

Le code que vous fournissez est insuffisant pour décrire le problème: quel est ce spectacle ' [id] 'utilisé pour? – Antonio

+0

Et pour quelles sortes de fréquences cela fonctionne-t-il bien, et quelles fréquences ont des problèmes? Et quels sont vos taux de trame bons et mauvais? Et quel type est 'show'? – Useless

+0

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

Répondre

0

Vous devez utiliser des temporisateurs au lieu de «sleep» pour résoudre ce problème, car la boucle peut prendre plus ou moins de temps à se terminer.

Redémarrez la minuterie au début de la boucle et prenez sa valeur juste avant la réinitialisation, ce qui vous donnera le temps nécessaire pour terminer la boucle. Si cette durée est supérieure à la valeur "period", cela signifie que vous êtes en retard et que vous devez l'exécuter immédiatement (et même réduire la période de la prochaine boucle). Sinon, si c'est plus bas, cela signifie que vous devez attendre jusqu'à ce qu'il soit plus grand. Personnellement, je n'aime pas dormir, et au lieu de redémarrer constamment le minuteur jusqu'à ce qu'il soit plus grand.

Je suggère de regarder dans le "temps fixe" code, tel que celui ci-dessous. Vous aurez besoin de mettre cet extrait de code sur chaque thread avec des valeurs variables pour la période (ns) et mettez votre code où "doUpdates()" est. Si vous avez besoin d'une bibliothèque "timer", puisque je ne connais pas OpenCV, je recommande SFML (SFML's timer docs).

Le code suivant est de 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; 
    } 
} 

S'il vous plaît l'esprit le fait que dans ce code, la minuterie est jamais remis à zéro.

(Cela peut ne pas être tout à fait exact, mais est la meilleure hypothèse que je peux faire pour résoudre votre problème étant donné le code que vous avez présenté)

+0

Merci pour la réponse, je vais essayer de regarder dans cette bibliothèque! –