Laurent MANEVILLE
Christophe PERSON
INTERFACE CERVEAU-MACHINE
Nous tenons à remercier toutes les personnes qui nous ont apporté leur aide dans ce projet.
Nous remercions tout d'abord nos tuteurs, Valérie Louis-Dorr et Radu Ranta, pour leur
disponibilité et pour avoir su nous conseiller tout au long de l'avancement de ce projet.
Nous remercions également le docteur Louis Maillard ainsi que les membres de son
équipe du service de neurologie de l'Hôpital Central de Nancy pour nous avoir permis de réaliser
des mesures grâce à leurs équipements.
Résumé
Ce projet vise à créer, détecter et utiliser des événements particuliers dans le signal EEG. La
plupart des méthodes actuelles provoquent des événements (appelés potentiels évoqués) par des
stimuli extérieurs (son, image, flash, toucher). D’autres méthodes demandent au volontaire de créer
lui-même l’événement à détecter (contraction musculaire, mouvement des yeux ou des paupières,
voire même un mouvement imaginaire). L'objectif de ce projet est de tester la réponse de l’EEG à ces
différents types de stimuli connus des neurologues.
Abstract
Last several years, numerous research teams in the world have been interested in the
realization of brain – computer interfaces (BCI). The possible applications are various like
helping the heavily handicapped persons or video games. It can also be used in virtual reality or
to control real objects.
The electroencephalogram (EEG) is the most used means to constitute the first element of
the system of measure and treatment of a brain – computer interface. This electrophysiological
signal, obtained thanks to electrodes placed on the head, is able to record the changes of cerebral
electric activity in real-time.
This project's purpose is to create, detect and use particular events in the EEG signal.
Most of the current methods provoke events (called potential evoked) while using outside stimuli
(sound, image, flash, touch). With other methods the volunteer is asked to create the event to be
detected (muscular contraction, movement of eyes or eyelids, even imaginary movements). The
objective of this project is to test EEG'S answer to these various types of stimuli known by
neurologists.
Sommaire
1. Introduction.........................................................................................................3
1.1. Contexte............................................................................................................................. 3
1.2. Objectifs.............................................................................................................................3
5.1. Présentation......................................................................................................................35
5.2. Choix du matériel utilisé..................................................................................................36
5.2.1 Choix du système d'exploitation................................................................................ 36
5.2.2 Choix du langage de programmation.........................................................................36
5.2.3 Choix de la librairie graphique.................................................................................. 37
5.3. La communication avec Matlab.......................................................................................38
5.4. Les programmes réalisés..................................................................................................40
5.4.1 Mise en place de la SDL............................................................................................ 40
5.4.2 Programme de prise de mesures................................................................................ 43
5.4.3 Programme de tracé de signaux................................................................................. 44
6. Conclusion........................................................................................................ 48
7. Bibliographie.....................................................................................................49
ANNEXE.............................................................................................................. 52
Les parties 1 à 3 ont été rédigées par Christophe Person, la partie 4 par Victor Braz, et la
partie 5 par Laurent Maneville.
1.1. Contexte
1.2. Objectifs
Le but de ce projet est de créer des évènements particuliers dans
l’électroencéphalogramme (EEG), de les détecter et de les utiliser dans le but d’interagir avec
un ordinateur.
Ce projet est mené en équipe de 3 étudiants, qui sont chargés de l’acquisition de
l’activité cérébrale, du traitement du signal, et de la mise en œuvre d’une interface graphique.
Un diagramme montrant l'organisation de ces différentes parties est représenté sur la figure 1
de la page suivante.
Nous chercherons les événements caractéristiques et détectables dans les EEG, afin de
décider s'il est préférable de provoquer des événements au moyen de stimuli extérieurs (des
images défilant rapidement sur un écran par exemple), appelés potentiels évoqués, ou s'il est
plus intéressant que le sujet provoque lui-même les évènements à détecter (par contraction
d’un muscle).
Un objectif important sera de parvenir à différencier plusieurs événements : par
exemple, on pourrait tenter de distinguer des événements selon qu’ils proviennent de
l’hémisphère gauche ou de l’hémisphère droit du cerveau.
Il faudrait aussi s’interroger sur l’interface graphique à réaliser : une version simple
serait d’allumer une LED rouge lorsqu’un événement a été détecté dans la partie gauche du
cerveau, et d’allumer une LED verte lorsqu’il a été détecté dans la partie droite.
Le premier prototype intégrant un système BCI est attendu pour fin 2008, et les
difficultés majeures consistent pour l’instant à miniaturiser l’équipement. Il faudra une petite
semaine d’entraînement à la personne pour arriver à utiliser des commandes simples comme
droite, gauche, en avant, ou stop. L’équipe espagnole travaille à une combinaison de systèmes
mêlant pensées et logiciel de cartographie, ce qui permettrait au système de comprendre des
injonctions plus compliquées comme “va à la cuisine”.
Les chercheurs de l'institut Fraunhofer de Berlin ont conçu un système utilisant 128
électrodes afin de traduire les pensées de l'utilisateur en mouvements de curseur sur un écran
d’ordinateur. Le système doit encore être amélioré, la durée nécessaire pour saisir une simple
phrase pouvant atteindre plusieurs minutes. La mise en place des électrodes est également très
complexe. Mais les scientifiques comptent développer un casque sans contact qui remplacera
toutes ces électrodes. Le logiciel apprend en même temps que l’utilisateur, ce qui permet aux
personnes totalement handicapées, mais dont le cerveau est intact, de retranscrire leurs pensées
sur un écran d’ordinateur, comme par télépathie.
Pour déplacer le curseur sur les différentes lettres à l'écran, il faut imaginer des
mouvements de mains ou de pieds. Cela ne demande qu'une vingtaine de minutes
d'entraînement pour parvenir à configurer un nouveau profil, puis on peut parvenir à écrire 5 à
7 mots à la minute.
On est donc encore loin de pouvoir écrire directement un texte sur son ordinateur
simplement en pensant aux mots que l'on voudrait voir s'afficher, puisqu'il faut épeler chaque
mot, même s'il existe des programmes de reconnaissance de mots qui permettent d'accélérer
légèrement l'écriture.
D'autres chercheurs, de l'université de l'Illinois, utilisent les ondes P300 pour écrire des
mots. Un clavier virtuel en forme de tableau est présent à l'écran, les lignes et les colonnes
clignotant successivement. Lorsque la lettre à sélectionner par l'utilisateur apparaît au
croisement de la ligne et de la colonne clignotantes, le simple fait de vouloir la sélectionner
entraîne un pic d'activité 300 millisecondes après l'évènement qui devient donc facilement
détectable. Ce procédé permet actuellement de saisir 8 lettres par minute et demande beaucoup
d'entraînement, suite auquel on peut parvenir à saisir les lettres plus rapidement.
Cela fait déjà plusieurs années que la société IBVA (Interactive Brainwave Visual
Analyzer) travaille sur un système permettant de contrôler différents appareils par la pensée,
comme une télévision ou un lecteur CD par exemple. Ils sont aussi parvenus à envoyer des
messages par internet en contrôlant un ordinateur par des ondes cérébrales.
Ces technologies ont elles aussi pour principal objectif de venir en aide à des personnes
handicapées, en leur apportant des outils permettant de pallier leur handicap.
A l’université de Pittsburgh, des chercheurs ont mis au point un bras robotisé contrôlé
par la pensée. Ce bras reproduirait les gestes d’un humain grâce à un système de sondes et de
capteurs directement insérés dans le cerveau. Lors d’une expérience menée sur des singes, le
bras robotisé suit les directives imposées par la pensée ou la volonté du singe.
Une autre équipe de scientifiques du CHU de Duke (en Caroline du Nord) a entraîné
des singes à manœuvrer un bras mécanique par la pensée. Elle a annoncé en 2005 que les
premiers tests sur 11 personnes atteintes de la maladie de Parkinson prouvaient la viabilité de
ce protocole d’utilisation d’une BCI sur les humains. Des électrodes implantées dans le
cerveau transforment les impulsions en signaux capables de télécommander les mouvements
d’une prothèse robotisée ou d’un fauteuil électrique. Les espoirs sont très grands, notamment
chez les amputés et les tétraplégiques.
Combiner un BCI non invasif avec les technologies de réalité virtuelle offre la
possibilité de réaliser une interface «naturelle» pour se déplacer par la pensée (en imaginant
des mouvements) et en temps réel dans un environnement virtuel. Dans ce cadre, une étape très
importante a été présentée en 2004 par un groupe de scientifiques travaillant avec la société
autrichienne g.tec (Guger Technologies).
Le participant, assis sur un siège et la tête recouverte d'un casque (EEG) et de lunettes
spéciales est placé dans un environnement virtuel, lui donnant l'illusion d'être physiquement
dans une rue. Il lui suffit d'imaginer mentalement le mouvement de ses pieds, pour progresser
en avant ou en arrière dans cet environnement, et le mouvement de sa main droite pour arrêter
la progression.
Sony a déposé un brevet en 2005 pour une technologie visant à transmettre directement
des informations sensorielles au cerveau. Aucune chirurgie invasive n'est nécessaire et cette
technologie pourrait être utilisée pour créer des jeux vidéo dans lesquels il deviendrait possible
de sentir ou de goûter. Des pulsations ultrasoniques sont envoyées à des zones spécifiques du
cerveau afin d'induire des expériences sensorielles telles que des odeurs, des sons ou des
images. On pourrait alors même espérer ouvrir de nouvelles voies pour aider les sourds ou les
aveugles, le spécialiste en neurologie à l'université de Tübingen en Allemagne Niels Birbaumer
ayant estimé ce brevet plausible.
L’EEG est le moyen le plus utilisé pour la réalisation d’une BCI. Ce signal est la
mesure de l’activité bioélectrique cérébrale ; il est obtenu à l’aide d’électrodes placées sur le
cuir chevelu, les électrodes étant soit autocollantes et à usage unique, soit fixées sur un casque.
Les courants recueillis sont surtout ceux générés au niveau des dendrites des neurones
pyramidaux que l'on retrouve massivement dans le cortex et qui ont une orientation parallèle,
ce qui amplifie le signal de leur activité commune. Le développement de l’EEG en clinique
date de l’apparition des amplificateurs différentiels au début des années 1960. Les EEG sont
actuellement utilisés afin de diagnostiquer des foyers épileptiques, des tumeurs cérébrales, des
lésions. Ils permettent aussi de trouver l'origine de migraines, de problèmes d'étourdissements,
ou encore de somnolence.
L’activité bioélectrique cérébrale correspond à des différences de potentiel électrique
entre deux électrodes. Un montage EEG correspond donc à une combinaison de couples
d’électrodes. Il existe des montages bipolaires et des montages référentiels (ou monopolaires).
Dans un montage bipolaire, le signal mesuré est la différence entre un pôle positif et un pôle
négatif, alors que dans un montage référentiel, le signal mesuré ne provient que d'un pôle, le
pôle opposé étant commun à tous les couples d'électrodes. En fait, cette électrode neutre n’est
jamais véritablement nulle et il existe donc plusieurs choix possibles pour l’origine des
potentiels.
L’emplacement des électrodes est standardisé par une nomenclature internationale
appelée système 10/20. Chaque électrode porte un nom précis (F : frontale, P : pariétale, Fp :
Fronto-pariétale, T : temporale, O : occipitale, C : centrale), les électrodes de la ligne médiane
reçoivent le suffixe « z » pour zéro, les chiffres pairs indiquent le côté droit et les chiffres
impairs le côté gauche.
Plusieurs difficultés existent lors de l'acquisition d'un signal EEG avec des électrodes
de surface :
la faible amplitude du signal mesuré (de 10 à 100 μV),
le bruit de mesure, dû à l’éloignement des sources ; la qualité du signal EEG recueilli
est testée en mesurant l'impédance de l'ensemble constitué par chaque électrode et son
câble, qui doit être inférieure à 10 kΩ, voire à 5 kΩ pour que les signaux soient
interprétables.
la présence d’artefacts :
ils peuvent être d’origine corporelle, c'est-à-dire dus à des mouvements
oculaires, aux activités musculaire, respiratoire et cardiaque, au mâchonnement,
à la déglutition, à la toux…
De plus, il ne faut pas oublier qu’il existe des pensées parasites qu’il est difficile
de contrôler.
Les artefacts peuvent aussi être d’origine extra-corporelle ; ils peuvent être
induits par l'environnement immédiat, dépendre de l'isolement électrique…
Dans le cas des techniques non invasives, le problème d'une mauvaise résolution du
signal à cause de son atténuation par les tissus et os crâniens a souvent été souligné. La forme
ronde du crâne vient également entraîner une dispersion et un brouillage des ondes
électromagnétiques créées par les neurones. Ainsi, même si les ondes peuvent tout de même
être détectées, il est plus difficile, par rapport aux méthodes invasives, de déterminer le secteur
du cerveau qui les a créées ou les actions générées par différents neurones, d’autant plus que
plusieurs régions différentes du cerveau peuvent réagir au même événement. Par ailleurs, la
méthode non invasive nécessite un entraînement intensif du sujet à la maîtrise de cette
technologie.
Parmi les distributeurs de tels dispositifs d'acquisition EEG, on peut citer la société
russe Neurosoft qui propose le « Neurospectrum » dont la particularité est qu'il se connecte au
port USB d'un ordinateur. Il s'agit donc d'un système relativement simple d'utilisation,
comportant tout l'équipement d'acquisition de signaux EEG, d'autant plus qu'il est livré avec un
logiciel complet d'acquisition et d'analyse, pour un prix abordable (environ 10 000 € pour le
modèle à 16 électrodes). Cependant, le « Neurospectrum » semble davantage destiné à une
utilisation clinique plutôt que du domaine de la recherche scientifique.
Le « Neurospectrum » comporte une boîte d'entrée facile d'utilisation, ainsi que divers
accessoires personnalisables de stimulations auditives ou visuelles :
figure 8 : Le Neurospectrum
[NEUROSOFT]
Lorsqu’on s’intéresse aux événements caractéristiques et détectables dans les EEG, une
première solution consiste à provoquer des événements au moyen de stimuli extérieurs (des
images défilant rapidement par exemple) : il s'agit des potentiels évoqués (PE) que l'on peut
définir comme des réponses électrophysiologiques à des stimulations sensorielles. Nous nous
intéresserons plus particulièrement aux PE visuels qui sont plus amples, donc plus faciles à
extraire.
Il existe plusieurs types de PE, par exemple l’onde « P300 » qui est une onde positive
qui survient lorsqu’un sujet a détecté un stimulus attendu et imprévisible. Le « P » signifie que
le signal est positif et « 300 » précise que le pic est obtenu 300 ms après l’événement. De
même on utilise la lettre « N » pour des pics négatifs.
La MMN, ou négativité de discordance (mismatch negativity), est observée lorsqu'un
stimulus déviant est inséré au sein d'une série régulière de stimuli identiques.
La N400 est liée au traitement linguistique, au contenu ou représentation sémantique.
Elle reflète la force de l'association à laquelle un concept est relié dans un contexte sémantique.
L’onde P300 est souvent utilisée dans les BCI pour détecter des événements. Il s’agit
d’un signal électrique produit par le cerveau en réponse à une stimulation ; plus
particulièrement, le fait qu'il s’agisse d’un potentiel positif culminant à 300 ms après la
stimulation la rend facilement détectable. Le montage C de la figure 9 précédente est utilisé
pour mesurer ces P300.
On présente à l’utilisateur plusieurs choix (par exemple plusieurs images), et lorsque
celui qui lui convient apparaît, le simple fait de vouloir le sélectionner augmente la tension
électrique du cerveau d’une manière plus facilement mesurable que son activité habituelle ne le
permet.
Le sujet peut provoquer lui-même les évènements à détecter (par contraction d’un
muscle, ou par mouvements imaginaires). L'intérêt des stimuli intérieurs est que le sujet va
pouvoir agir par lui-même et à tout moment sur une commande, contrairement aux potentiels
évoqués où il ne fait que réagir à un stimulus.
Une difficulté dans l'utilisation des stimuli intérieurs est de différencier plusieurs
évènements : il est difficile de contracter un seul muscle en relâchant tous les autres, et la
réalisation d'un mouvement sollicite en général plusieurs muscles. Le simple fait de se tenir
assis ou de maintenir sa tête droite entraîne la contraction de multiples muscles. De plus, de
nombreux artefacts oculaires dégradent le signal, étant donné qu'il est très difficile, voire
impossible de contrôler ses clignements des yeux.
Il faut donc utiliser des mouvements relativement simples afin d'espérer pouvoir les
détecter. Il est aussi possible de travailler avec des mouvements imaginaires, ce qui peut être
intéressant pour l'utilisation par des personnes handicapées. Cela demande beaucoup
d'entraînement, mais des résultats encourageants ont déjà été obtenus, en particulier par la
société autrichienne g.tec.
Les stimuli intérieurs semblent donc être un moyen efficace pour détecter plusieurs
évènements différents, c'est pourquoi nous avons choisi de les exploiter dans nos mesures
expérimentales.
Le signal est ensuite à nouveau amplifié, le gain étant réglable et ayant une valeur
comprise entre 1 et 10. Le gain total peut donc atteindre 10 6 en considérant les deux
amplifications ; à partir d'un signal de quelques μV, on obtient donc un signal de l'ordre du
Volt.
Un filtrage passe-bas, servant aussi de filtre anti-repliement, est finalement utilisé afin
d'obtenir un signal qui pourra être utilisé en entrée d'un convertisseur analogique-numérique.
Nous avons commencé par tenter de détecter des mouvements, c'est-à-dire d'utiliser des
stimuli intérieurs. Pour cela, nous avons utilisé un programme en langage C qui affichait des
instructions à l'écran d'un ordinateur, et qui écrivait dans un fichier l'instant auquel l'instruction
avait été donnée.
Les instructions étaient de cligner de l'œil gauche, de l'œil droit, de bouger le bras droit,
puis le gauche. Ces différentes instructions étaient tout d'abord répétées dans un ordre défini,
puis elles étaient données aléatoirement.
On pouvait ainsi espérer détecter des évènements dans l'hémisphère droit du cerveau
lorsque l'on demandait un mouvement de la partie gauche du corps, et inversement.
Nous avons ensuite tenté d'exploiter des potentiels évoqués. L'expérience consistait à
afficher aléatoirement différentes lettres à l'écran, et il fallait compter le nombre d'apparitions
d'une lettre cible. On espérait ainsi observer un phénomène comparable aux P300.
La première difficulté pour exploiter nos enregistrements EEG a été de les synchroniser
avec les instructions données. Ainsi, au début de chaque acquisition, on demande de cligner
trois fois des yeux, ce qui a pour effet de produire un événement facilement détectable sur la
plupart des voies :
150
100
50
-5 0
Les données obtenues sont sous forme ASCII, donc facilement exploitables avec
MATLAB. Nos mesures ont été effectuées avec une fréquence d'échantillonnage de 256 Hz,
avec un montage référentiel constitué de 19 voies (la vingtième voie étant utilisée comme
référence).
Le fichier contenant les données comportait l'heure d'enregistrement au début des lignes
correspondant à chaque nouvelle seconde, soit toutes les 256 lignes. Afin de pouvoir exploiter
ce fichier avec MATLAB, il a fallu supprimer ces affichages d'heures pour obtenir un fichier
ne contenant que les données, sans aucune autre information. Nous avons donc écrit un
programme en langage C uniquement afin de générer un fichier directement exploitable avec
MATLAB, puisqu'il aurait été extrêmement laborieux de modifier nous-mêmes le fichier
manuellement. En effet, ces fichiers de données sont relativement volumineux, puisqu'un
enregistrement de deux minutes correspond à environ 7 Mo (il faut donc utiliser des disques
durs de grande capacité si l'on souhaite stocker des enregistrements EEG, ce qui est le cas à
l'hôpital).
Dans les différentes études sur les BCI, plusieurs méthodes ont été utilisées pour
réaliser ces deux parties que ce soit dans le domaine du prétraitement du signal ou dans les
algorithmes de classification des événements.
4.1.1. Filtrage
Pour éliminer le bruit, la méthode la plus utilisée est un filtre passe-bande dont les
fréquences de coupures sont déterminées selon les domaines de fréquence de l'activité
cérébrale. Les filtres linéaires sont aussi utilisés, notamment la moyenne glissante où
l'échantillon n du signal est remplacé par la moyenne de ses points voisins permettant ainsi de
lisser le signal.
Les mouvements des yeux ou des muscles peuvent provoquer des larges amplitudes du
signal EEG, afin de réduire l'effet de ces artefacts, on peut placer des bornes supérieures et
inférieures au signal, toute valeur au-dessus (resp. en-dessous) de la borne supérieure (resp.
inférieure) sera remplacée par la valeur de la borne. Les bornes sont déterminées à partir des
échantillons, on prend les valeurs telles que 10% des échantillons soient en dessous et 90% des
échantillons soient au-dessus. [HOFFMAN]
L'ACP cherche à séparer le signal en sources non corrélées(en utilisant des statistiques
du deuxième ordre). Cette méthode utilise la matrice d'observation X (n*p) ,que l'on a centrée
et réduite afin de s'affranchir de l'hétérogénéité des variables tant en moyenne qu'en dispersion,
pour déterminer les composantes principales définies par C=XtV où V est la matrice des
vecteurs propres de XXt (matrice de corrélation entre les variables). Ces composantes
principales peuvent être considérées comme de nouvelles variables non corrélées entre elles.
L'ACI cherche à séparer le signal en sources indépendantes (en utilisant des statistiques
d'ordre supérieur). A partir de la matrice d'observation X, on cherche la matrice de mélange des
signaux A de façon à avoir X=A*Y et où les lignes de la matrice Y représentent les signaux qui
doivent être indépendants entre eux. Plusieurs algorithmes existent pour réaliser l'ACI,
notamment le fastICA qui après un blanchiment des données, maximise un contraste basé sur
la néguentropie et extrait les composantes indépendantes une à une
([KACHENOURA],[UNGUREANU]). La néguentropie est définie par la différence entre
l'entropie d'un vecteur x et de l'entropie d'un vecteur gaussien ayant la même matrice de
corrélation que x.[LAFAYE DE MICHEAUX]
L'ACI est peu utilisée pour le moment dans les BCI, mais les quelques applications qui
en ont été faites, ont permis d'améliorer le taux de classification des évènements.
D'autres méthodes de traitement des signaux EEG existent pour détecter les activités
cérébrales, notamment pour les protocoles de détection des P300 où l'on peut utiliser la
connaissance des instants des stimuli qui engendrent les potentiels évoqués pour réhausser le
signal des P300 et estimer un sous-espace des signaux P300. [RIVET]
Les classificateurs linéaires sont les algorithmes les plus utilisés pour les BCI, ils
permettent de distinguer des classes en utilisant des fonctions linéaires.
P(A|B)=P(B|A)P(A)/P(B),
on obtient :
f x 0⋮y=i P Y =i
P(Y=i | X= x 0 )= i∈[1, g ]
f x0
g
1
K= ∑ ∑
n i =1 j∈ I
X j−mi X j−mit
Et les droites séparant les classes sont déterminées par les relations d'égalités entre les
probabilités conditionnelles :
P(Y=i | X= x 0 )= P(Y=j | X= x 0 )
Cette méthode d'analyse discriminante est basée sur les différences entre les moyennes
et les variances des classes. Pour avoir de bons résultats, il faut que les lois que suivent les
données des différentes classes aient des paramètres distincts, sinon les probabilités
conditionnelles P(Y=i | X= x 0 ) auraient sensiblement la même valeur, d'autant plus que les
probabilités a priori des différentes classes P(Y=i) sont généralement égales.
wt S b w
J w=
wt S w w
1
mi = ∑X
ni j ∈ I j
w=S −1
w m1−m 2
Un des problèmes de cette méthode est que si le nombre de caractéristiques devient plus
important que le nombre d'échantillons utilisés pour l'apprentissage, la matrice Sw n'est plus
régulière et donc son inverse n'est plus définie, il faut alors la remplacer par sa pseudo-inverse.
[HOFFMAN]
Lorsque l'hyperplan qui sépare les classes est déterminé, on peut faire la classification
des données en regardant le signe du produit scalaire entre w et le vecteur de données. Lorsque
l'on utilise cette méthode pour des BCI multiclasses, on applique la stratégie « One Versus the
Rest »(OVR) pour déterminer chaque hyperplan séparant une classe de toutes les autres.
Tout comme l'analyse discriminante linéaire, les séparateurs à vastes marges cherchent
un hyperplan séparant les classes, mais ici, cet hyperplan doit aussi maximiser la distance avec
les points les plus proches de chaque classe.
On doit alors maximiser la marge 1/||w||, ce qui revient à minimiser ||w||^2/2 sous la
contrainte : yk (< w ; xk > −0) ≥ +1, ∀k ∈ {1, . . . , n}. On doit alors chercher un point selle du
n
Lagrangien : L(w, , )=||w||^2/2- ∑ k y k 〈 w∣x k 〉 − −1 où alpha représente les
k =1
coefficients de Lagrange.
Cette méthode est valable lorsque les classes sont linéairement séparables, si ce n'est
pas le cas, on peut utiliser les SVM non linéaires en employant une fonction Φ qui transforme
les données afin de pouvoir appliquer les méthodes linéaires. On a alors :
〈 x∣x k 〉 〈 x ∣ x k 〉=K x , x k
où K x , x k est un noyau reproduisant (kernel function).
Pour les SVM non linéaires utilisés dans le domaine des BCI, on emploie généralement
un kernel gaussien : K(x,y)=exp(-||x-y||^2/(2*sigma)) .
Comme pour l'analyse discriminante linéaire, on utilise la stratégie OVR pour les
applications multiclasses. Les séparateurs à vastes marges sont eux aussi fortement utilisés
pour les BCI avec de bons résultats.
La distance de Mahalanobis convient bien pour les problèmes multiclasses et elle donne
de bons résultats, cependant elle est peu utilisée dans les applications sur les BCI.
Cette méthode consiste à déterminer dans la base d'apprentissage les k vecteurs les plus
proches du vecteur X de caractéristiques que l'on souhaite classer en calculant les distances
entre eux, puis lorsque ces k éléments sont trouvés, on affecte le vecteur X à une classe en
fonction de l'appartenance de ces k points.
Cette technique est peu utilisée dans la recherche sur les BCI car elle est sensible au
problème de la « malédiction de la dimension », mais elle est efficace pour les vecteurs de
caractéristiques de faible dimension [LOTTE].
Les réseaux de neurones sont des outils qui sont fréquemment utilisés dans le domaine
de la classification automatique. Un neurone réalise une fonction de transfert entre ses entrées
et la sortie dont la valeur dépend de paramètres appelés poids. Les réseaux de neurones se
caractérisent par leur architecture : nombre de neurones, nombres de couches, agencement des
neurones les uns par rapport aux autres, ainsi que par les fonctions utilisées.
x1
a1
x2 a2
S n F y
a3
x3
b
figure 19 : Neurone à entrées multiples
S F y1
b21
x1 S F
S F y2
x2 b11
x3 S b22
F
S F y3
b12
b23
Pour faire de la classification à l'aide des réseaux de neurones, il faut déterminer les
paramètres A et b afin d'optimiser le critère :
N
=∑ y m , k − y k 2
k=1
Les différences des réseaux de neurones proviennent des fonctions F choisies. Les
réseaux les plus répandus dans le domaine des BCI sont les MultiLayer Perceptron (MLP) où
un perceptron est un neurone multi-entrées dans lequel on utilise une fonction à commutation:
y=0 si AX+b<0 ou y=1 si AX+b>=0
Parmi les autres réseaux de neurones que l'on peut trouver dans les BCI, il y a ceux
utilisant des fonctions de discrimination gaussienne ainsi que d'autres architectures de réseaux
dont l'utilisation dans ce domaine est plus rare [LOTTE].
Les algorithmes de classification dans les BCI sont dominés par les méthodes utilisant
les LDA, les SVM ou les MLP et chacun de ces procédés marche bien. Mais des techniques
pas utilisées ou très peu apparaissent pour la conception des interfaces cerveau-machines,
notamment les systèmes à inférence floue qui consistent à déterminer des règles d'appartenance
« si-alors » floues. Le principe est de diviser les données de chaque classe en paquets
(« clusters »), puis pour chacun de ces groupes, on génère la règle floue :
Si X1 est Aj1 et si X2 est Aj2 et ... alors la classe est Ci
où Xk est la k-ième composante du vecteur de caractéristiques et Ajk est une fonction
d'appartenance floue gaussienne décrivant la forme du groupe :
−1 X k − x jk
2
A jk X k =exp
2 jk
avec xjk le k-ième élément représentant le centre du groupe et σjk une constante positive
Les paramètres de cette fonction d'appartenance sont ensuite optimisés à l'aide d'une
méthode de la descente du gradient sur une mesure de l'erreur de classification.[OPEN VIBE]
Dans certaines études des BCI, des combinaisons de classifications sont utilisées afin
d'essayer d'améliorer le taux d'éléments bien classés. On considère qu'une méthode donne de
bons résultats si son taux de bien classés atteint les 80%.
Le signal dû à un clignement d'oeil est facilement repérable dans les mesure EEG, donc
on peut isoler cette partie du signal et en faire un modèle pour ensuite repérer tous les autres
signaux similaires par corrélation au modèle.
Pour cela, on cherche à approximer le vecteur des données s correspondant à un clignement
n
P t k =∑ ai .t k
i
d'oeil par un polynôme P de degré n :
i =0
[ ]
1 t 1 t 12 ⋯ t 1 n
1 t 2 t 22 t 2n
X= ⋮ ⋮ , les valeurs de s ayant été mesurées aux instants t1, t2,..., tP.
⋮ ⋮
1 t P tP ⋯ tPn
2
On utilise ensuite ce modèle polynomial pour calculer la corrélation avec les différentes
voies en se plaçant sur plusieurs échelles temporelles. Une corrélation importante indiquera
qu'un clignement d'oeil a eu lieu sur l'échelle temporelle correspondante.
100
50
-5 0
1 .4 1 .6 1 .8 2 2 .2 2 .4 2 .6 2 .8 3 3 .2
En effectuant des tests sur le signal avec 3 clignements d'oeil, on a les résultats suivant :
La méthode qui consiste à corréler les mesures des électrodes à un modèle n'est pas
utilisée dans le domaine de la BCI, car généralement, on cherche à détecter d'autres
évènements que les clignements des yeux, et déterminer un modèle de P300 par exemple est
très difficile compte tenu du fait que ce type de potentiel peut varier selon le temps et la
concentration de la personne qui effectue l'expérience.
Le signal dû aux clignements des yeux est généralement de plus forte amplitude que les
signaux dus à d'autres activités. De ce fait, on peut mettre en place un programme qui compare
la valeur de l'amplitude du signal à un seuil que l'on a fixé à partir de l'observation de mesures
de clignement d'oeil.
En plaçant un seuil à 100 μV sur le même signal que la partie précédente, on arrive à
détecter les trois pics des clignements sur plusieurs voies, et on n'a aucune fausse détection.
On détecte le pic 1 sur les voies 1, 3, 4, 5, 7, 8, 10, 11, 12, 14, 15, 18, 19.
On détecte le pic 2 sur les voies 1, 5, 7, 8, 7, 8, 11, 18, 19.
On détecte le pic 3 sur les voies 1, 3, 4, 5, 7, 8, 10, 11, 12, 15, 18, 19.
Cette technique de seuil est aussi peu utilisée dans les interfaces cerveau-machines car
les potentiels que l'on cherche à extraire ont généralement une faible amplitude qui peut varier
selon les sessions d'acquisition des signaux et selon la présence du bruit dans le signal. Cette
méthode donnerait donc pour des signaux autres que les clignements des yeux (qui ont une
forte amplitude) de nombreuses fausses et/ou non détections.
Une autre méthode que nous avons utilisé pour détecter le clignement des yeux est
l'analyse discriminante linéaire, une méthode qui est largement utilisée dans le domaine des
BCI. A partir d'une base d'apprentissage composée de dix clignements des yeux, nous avons
déterminé les échantillons correspondant aux différents évènements que l'on voulait détecter.
Puis, à l'aide du logiciel Matlab, nous avons fait la classification d'une session de mesures ( qui
doit aussi comporter dix clignements des yeux ) à partir des données de la base d'apprentissage.
L'un des problèmes des signaux EEG qui peut affecter la qualité de détection des
évènements est le bruit. Plus le rapport signal sur bruit diminue, plus le nombre de fausses
détections augmente.
Nous avons pu voir que pour les échantillons se situant aux alentours de 300 ms après
le stimulus, les valeurs des amplitudes des signaux sur certaines électrodes étaient différentes,
notamment sur Cz, Pz, P3, P4, C3, C4. Cependant, lorsque nous avons essayé d'utiliser ces
points pour faire des algorithmes de classifications tels que des réseaux de neurones ou des
méthodes d'analyse discriminante linéaire, nous avons eu de mauvais résultats. Sur un
ensemble de cent stimuli dont seize étaient cibles, nous avons eu très peu de bonnes détections
et beaucoup de fausses détections. La cause de ces mauvais résultats est notamment due au fait
que le signal de chaque fenêtre d'observation d'un stimulus cible ou non est bruité, qu'il
contient des artefacts et qu'il varie entre deux fenêtres d'observation. Ainsi, les caractéristiques
que l'on a choisies sur les moyennes peuvent fortement varier selon les différentes périodes
d'observations.
figure 28 : Moyenne des stimuli cibles (bleu) et moyenne des stimuli non cibles (rouge) sur la
voie P4
On voit donc que faire une classification des potentiels P300 à l'aide d'une seule fenêtre
d'observation ne donnera que très peu de bons résultats compte tenu de la différence entre les
caractéristiques des signaux. Il faudrait plutôt utiliser une moyenne de plusieurs fenêtres
d'observations afin d'enlever le bruit en faisant un moyennage, ce qui permettrait de faire une
meilleure classification, comme c'est le cas dans certaines BCI utilisant le protocole du « P300
speller » qui atteignent un taux de bien classé de 100% après 4,5 ou 6 répétitions du stimulus
cible [LOTTE].Cependant, pour cela il faut une plus grande quantité de signaux résultants des
stimuli cibles que celle dont nous disposons.
Le programme gérant l'interface graphique doit pouvoir récupérer le signal traité par
Matlab et réagir à ce signal. Il doit également gérer le temps en se synchronisant avec la prise
de mesures. Pour des applications qui doivent réagir rapidement aux signaux de l'utilisateur
telles qu'une machine à écrire virtuelle, cette gestion du temps est primordiale au bon
fonctionnement du programme. Dans l'idéal, la prise de mesures, le traitement de celles-ci et
leur utilisation doivent se faire en temps réel. Dans un premier temps et pour des raisons de
simplicité, il est possible d'effectuer du temps décalé en stockant les mesures dans un buffer.
Cela ne sera pas visible pour l'utilisateur et permettra tout de même de détecter les événements
à temps : si la période d'échantillonnage est faible (4ms), l'apparition d'un signal est plus lente
(par exemple un P300 survient 300ms après un stimulus visuel). Ceci nous offre une plus
grande souplesse vis à vis du temps.
Les programmes que nous pouvons réaliser sont variés et peuvent soit invoquer des
potentiels évoqués (par exemple un logiciel d'écriture de texte) ou des stimuli intérieurs (par
exemple un jeu de ping pong). Il est également possible de créer des programmes uniquement
destinés à étudier les signaux EEG mais qui ne les utilisent pas à proprement parler. On peut si
besoin écrire dans un fichier les actions réalisées durant le déroulement du programme.
Nous avons décidé de ne pas nous soucier du temps réel dans le projet (mais en
n'excluant pas son utilisation à terme). De plus, nos applications ne pouvaient être testées
durant une prise de mesures. Elles ont donc été réalisées dans le but d'utiliser des signaux
enregistrés dans un fichier ASCII. Nous avons cependant essayé de faire en sorte que les
programmes puissent facilement être modifiés pour être utilisés en direct. La principale
difficulté restante est la communication avec Matlab. Nous verrons plus loin comment cette
communication peut être réalisée.
Le schéma suivant montre les liens entre le programme gérant l'interface graphique et
les différentes parties du système dans le cas ou le programme appelle la machine Matlab :
Interface
graphique
figure 30 : Diagramme du programme gérant l'interface graphique
Le choix de l'OS est très important lorsque les applications à réaliser ont des contraintes
de temps. Ainsi, si l'on souhaite effectuer du temps réel, il faudrait utiliser un OS temps réel tel
que QNX.
Cependant, nous avions convenu de laisser de coté cette partie et de se limiter à du temps
différé. Nous avons donc plus de souplesse au niveau de l'OS. Le choix s'est donc porté sur un
linux tel que Ubuntu, ou sur Windows. Bien que les performances puissent être meilleures sur
un linux, nous avons choisi d'utiliser Windows que nous connaissons plus et qui est déjà
installé sur nos machines personnelles.
Matlab : Il est possible de réaliser une interface graphique en Matlab. L’avantage serait
alors de pouvoir effectuer le traitement des données et l’interface graphique dans le même
langage. Cependant les possibilités offertes par cette interface sont limitées. On ne pourra
réaliser de clavier virtuel avec ce langage par exemple.
Java : Java est un langage de haut niveau puissant. De plus il est très simple de réaliser
des interfaces graphiques évoluées grâce aux composants swing. Cette option est donc la plus
facile à mettre en œuvre. Cependant, il est possible que Java devienne trop limité lorsqu’il
s’agira de prendre les mesures en temps réel.
C++ : Le langage C++ est une amélioration du C. Ce langage est aussi puissant que le C
avec en plus les avantages de la programmation orientée objet comme Java. Il existe en C++
des librairies graphiques offrant les même possibilités qu’en Java et donc simple à mettre en
œuvre que le C.
-SDL : cette bibliothèque est de bas niveau, d’un point de vue graphique elle permet de
modifier la valeur d’un pixel, de tracer des rectangles et d’y inclure des images ! Il faut ensuite
programmer les fonctions plus élaborées. Mais la SDL n’est pas que graphique, elle permet
entre autre de gérer les événements (clavier et souris par exemple) ou des timers. Elle reste
simple d’utilisation.
-openGL et direct X : ces bibliothèques de bas niveau sont les plus performantes, elles
sont optimisées pour les cartes graphiques et permettent de gérer efficacement la 3D. Elles sont
peut être trop élaborées pour l’interface graphique que j’ai à réaliser. Direct X, comme l’API
win32, n’est utilisable que sur windows.
J’ai choisi d’utiliser la SDL qui est une bibliothèque de bas niveau (donc plus
polyvalente et plus rapide) simple et suffisamment complète pour réaliser mes interfaces
graphiques. Elle est également portable et les programmes pourront alors facilement être
adaptés sous un système UNIX. Les fichiers nécessaires au fonctionnement de la SDL peuvent
être téléchargés sur Internet [LIBSDL] et de nombreux tutoriels existent [TUTO,
DEVELOPPEZ]
A défaut de parvenir rapidement à communiquer avec Matlab, j’ai dans un premier lieu
opté pour une méthode simple mais peu efficace : la communication par fichiers. Matlab écrit
ses résultats dans un fichier que le programme C lit. Cette solution s’est révélée suffisante pour
les premières applications mais ne pourrait être utilisée en direct lors d’une prise de mesures
puisque le programme C ne peut lire le fichier quand Matlab y écrit. On pourrait contourner le
problème en demandant à Matlab de sauvegarder les mesures par séquences d’une dizaine de
points avant de changer de fichier. Le programme C pourrait alors lire les fichiers un à un en
décalé. Cette solution reste assez lourde et limitée. Il faut donc se pencher sur les autres
moyens de communication que propose Matlab.
Il est possible d’utiliser le compilateur Matlab mcc pour compiler le code Matlab
directement en code C. L’avantage serait alors de pouvoir tout effectuer (traitement et
affichage) dans un seul et unique programme en C. Je n’ai cependant pas réussi à réaliser cette
fonction malgré l’aide de Matlab.
Il est également possible d’appeler la machine Matlab depuis C grâce à l’outil mex.
Cette option est simple d’utilisation (une fois celle-ci assimilée !) et est performante.
La principale utilisation de l’outil mex est de créer des MEX-files à partir de routines
écrites en C ou fortran. Les MEX-files permettent d’appeler du code C dans Matlab. Mais mex
permet aussi de réaliser l’inverse : compiler un programme C qui appelle la machine Matlab.
Mex n’est pas en lui-même un compilateur. Il appelle un compilateur qui par défaut est lcc
sous windows. Il faut indiquer à l’outil mex quelle action réaliser avec quel compilateur. Pour
cela on utilise un fichier .bat. On trouve ces fichiers dans le répertoire
‘$MATLAB\bin\win32\mexopts\’.
Pour indiquer que l’on veut compiler un programme C appelant Matlab avec le
compilateur lcc il faut donner le fichier ‘lccengmatopts.bat’. On compile alors sous Matlab
grâce à la commande :
Pour pouvoir appeler la machine Matlab, le programme C doit avoir une forme
spécifique. Tout d’abord, il faut penser à définir les includes suivants au préprocesseur :
- ''engine.h'' pour manipuler la machine Matlab elle-même.
- <windows.h> pour l’utiliser sous windows.
Sous Windows, il faut également changer la fonction main en WinMain qui a la forme
suivante :
La machine Matlab doit être déclarée comme une variable de type Engine (On déclare
en fait un pointeur 'ep' vers cette variable).
L’ouverture de la machine se fait par la fonction : ep = engOpen(NULL); qui renvoie 0
en cas de problème.
On ferme la machine grâce à la fonction : engClose(ep);
Il existe ensuite plusieurs fonctions que l’on peut utiliser pour communiquer entre C et
la machine Matlab. Citons entre autres :
-engPutVariable(ep, "T", t);=> met la variable t du programme C dans la variable T de
la machine Matlab
-engEvalString(ep, "commande Matlab;"); => exécute la commande dans la machine
Matlab
-t =engGetVariable(ep,"T"); prend la variable T de la machine Matlab.
Pour manipuler les variables dans le programme C, il faut déclarer des variables dédiées
à la communication avec Matlab par exemple de type mxArray pour un tableau et utiliser les
fonctions mx comme :
-mxCreateDoubleMatrix => crée une matrice renvoyée dans un mxArray.
-mxGetPr(T); =>renvoie la partie réelle de T dans un double ou tableau de double.
On utilise la fonction memcpy() ; pour remplir les valeurs d’un mxArray à partir d’un
tableau d’entiers.
Il reste cependant un problème de taille sachant que nous voulons créer une interface
graphique : peut-on lancer la SDL en même temps que la machine Matlab ? A priori il suffit de
rassembler les deux dans le même programme C, et d’ajouter les bibliothèques de la SDL à la
commande mex.
Malheureusement, cela ne fonctionne pas ! Il m’a fallu de nombreux essais pour me
convaincre que le problème venait du compilateur lcc utilisé par Matlab. En effet sur le site de
la SDL il n’existe pour Windows que des bibliothèques pour le compilateur de Visual C++ et
de mingw (utilisé par mon IDE Code::Blocs). J’ai donc cherché à utiliser le compilateur
mingw mais Matlab ne le prend pas en charge !
Par chance il existe un logiciel libre : gnumex [GNUMEX], qui permet de créer des
fichiers .bat à entrer en option de l’outil mex. J’ai donc pu créer un fichier 'mexmingwopts.bat'
qui demande à l’outil mex de compiler grâce à mingw des programmes C appelant la machine
Matlab. Il suffit maintenant d’ajouter les bibliothèques de la SDL pour le compilateur mingw
et la compilation fonctionne !
La SDL est une librairie graphique de bas niveau, c'est-à-dire qu’elle ne possède pas de
fonctions élaborées telles que tracer un graphe. Il faudra donc coder les fonctionnalités
recherchées à partir des fonctions de bases. Par exemple pour réaliser un graphe il faut tracer
une droite entre tous les points consécutifs du graphe, et pour tracer une droite, modifier un à
un tous les pixels entre les deux points.
Nous utiliserons également d’autres fonctions de la SDL pour gérer les événements
souris et clavier et pour gérer les temps grâce à des timers. Nous utiliserons également une
extension de la bibliothèque permettant d’écrire du texte pour donner les valeurs maximales et
minimales des graphes par exemple.
Nous allons maintenant voir les points importants pour utiliser la SDL et réaliser notre
programme. Avant toute chose nous réalisons les includes suivants au préprocesseur :
#include <SDL/SDL.h> // contient les fonctions SDL
#include <SDL/SDL_ttf.h> //contient les fonctions texte
Création de la fenêtre :
On commence par charger la SDL en sélectionnant les options dont nous aurons besoin.
Ici nous chargeons les systèmes d’affichage et de timers :
SDL_Init(SDL_INIT_VIDEO| SDL_INIT_TIMER);
Il faudra à la fin du programme quitter la SDL par la fonction : SDL_Quit();
Pour Créer la fenêtre on va ensuite utiliser une surface SDL qui correspondra à l'écran
de fond du programme.
Pour cela on déclare un pointeur sur une surface : SDL_Surface *ecran;
Il est possible d'effectuer cette déclaration publiquement dans un fichier .h pour pouvoir
utiliser cet écran dans toutes les fonctions qui utilisent notre interface.
On peut ensuite choisir le mode vidéo de notre fenêtre en donnant : sa taille en pixels, le
nombre de bits par pixels pour les couleurs ainsi que différentes options. Ici nous indiquons
que nous chargeons les données dans une mémoire plus rapide, nous améliorons l’effet visuel
de l’affichage grâce au Double Buffering et nous mettons la fenêtre en plein écran :
Pour finir on met à jour l’affichage à l’écran. En effet toutes les modifications
précédentes ont été effectuées en mémoire uniquement. Il faut maintenant les afficher. Il faudra
faire la même opération à chaque modification de la fenêtre : SDL_Flip(ecran);
SDL_Rect position_curseur;
position_curseur.x=470;
position_curseur.y=50;
Pour écrire du texte on utilise l’extension ttf de la SDL. Cette extension doit être
chargée au début du programme : TTF_Init(); et arrêtée à la fin : TTF_Quit();
Il faut ensuite charger une police. Pour cela on crée une variable : TTF_Font* police;
Puis on alloue la police désirée et sa taille : police = TTF_OpenFont("times.ttf", 20);
Il faudra penser à fermer cette police à la fin du programme : TTF_CloseFont(police);
On peut ensuite associer un texte contenu dans une chaîne de caractères à une surface grâce à
la fonction : text_min = TTF_RenderText_Solid(police,chaine, couleur_noire); où couleur
noire est définie ainsi : SDL_Color couleur_noire= {0, 0, 0};
La SDL est capable de gérer les signaux d’entrée tels que l’appui sur une touche du
clavier ou le déplacement de la souris.
Pour cela, il faut d'abord créer une variable de type SDL_Event : SDL_Event event;
On entre ensuite dans une boucle qui ne se terminera que lorsque l'on souhaitera quitter
le programme. Cette boucle attend à chaque fois un événement grâce à la fonction :
SDL_WaitEvent(&event); (reste bloquée tant qu’il n’y a pas d’événement) ou
SDL_PollEvent(&event);
Gestion du temps :
Pour réaliser les programmes d’interfaçage graphique, un point essentiel est de pouvoir
gérer le temps. La SDL permet cela grâce à plusieurs fonctions. La première est une fonction
très simple (SDL_GetTicks();) qui ne fait rien d’autre que renvoyer le nombre de millisecondes
passées depuis le début du programme. Il suffit de faire la différence entre deux commandes
SDL_GetTicks() pour obtenir le temps qui s’est écoulé.
Une autre fonctionnalité importante et plus complexe est la gestion des timers : un timer
est un système qui va appeler une fonction de manière périodique.
Remarque : on ne peut passer qu’un unique paramètre. Si l’on souhaite en passer plus,
il faut nécessairement créer une structure contenant tous les paramètres.
La fonction lancée par le timer doit avoir un format type. Elle doit prendre en entrée le
délai du timer et un pointeur de type void. Elle renvoie la valeur du délai. Le prototype de la
fonction est donc le suivant : Uint32 tracer(Uint32 intervalle, void *parametre);
On peut alors directement modifier notre structure passée en paramètre. On accède aux
sous-variables de la structure grâce à graphe->sous_variable qui correspond à
(*graphe).sous_variable.
Il ne faut pas oublier de retourner le délai du timer à la fin de la fonction : return intervalle;
Ce programme est plus destiné à l’étude des signaux EEG qu’à leur application. En
effet, dans le cadre d’une visite au centre hospitalier de Nancy, nous avons voulu définir des
protocoles de prises de mesures. Le but de ce programme est de mettre en œuvre ces protocoles
en demandant à un utilisateur muni d’un casque d’effectuer divers exercices comme lever un
bras ou compter le nombre d’apparitions d’une lettre. Le programme note dans un fichier les
opérations demandées et la date de la demande. On pourra ainsi caler le fichier eeg avec les
exercices réalisés.
La réalisation du programme reste assez simple. Il s’agit juste d’afficher des phrases à
tour de rôle, soit de manière définie soit aléatoire. Il n’y a pas besoin de communiquer avec
Matlab puisque le traitement se fait après coup. Il n’y a pas non plus besoin d’effectuer du
temps réel. La SDL permet ici d’améliorer l’affichage des actions à réaliser pour que celles-ci
soient écrites en plus gros et plus lisible qu’en ligne de commande. Cela est important car
l’utilisateur ne doit pas avoir à trop se forcer pour lire. Surtout qu’il n’est pas forcément bien
installé pour cela.
J’ai choisi de réaliser un programme qui va simplement tracer des signaux en fonction
du temps. Ce programme nous permet de tracer les signaux EEG ainsi que les différentes
étapes du traitement. C’est une bonne introduction avec la bibliothèque SDL et nécessite la
recherche d’un moyen pour récupérer les données Matlab. Ce programme doit également
prouver qu’on a réussi à détecter un événement.
L’idéal serait de tracer les signaux en temps réel, cependant, nous avons décidé de
commencer par traiter le signal et de le tracer a posteriori. Pour cela le programme Matlab
enregistre les signaux dans un fichier que le programme doit lire.
Plutôt que de tracer directement l’ensemble du fichier j’ai choisi de simuler le temps en
lisant un point du fichier toutes les 4ms (période d’échantillonnage du signal) et en traçant
l’ensemble des points déjà lus toutes les 40ms (25 images par seconde). Ceci pour permettre
une meilleure adaptation future à une exécution en direct. Le programme utilise donc des
timers pour actualiser le graphe toutes les 40ms et pour lire une valeur d’un fichier toutes les
4ms.
L’interface contient 4 graphiques permettant de tracer différents signaux, par exemple
un signal non traité, débruité, après traitement par une fonction de corrélation et une détection
d’événement. Un disque rouge permet de montrer que l’on a détecté un événement. Soit en
s’allumant, soit en se déplaçant à droite ou à gauche.
Il faut donc créer une structure graphique contenant toutes les variables nécessaires à
son utilisation. Il est ensuite possible de créer une variable de type graphique et d’envoyer son
adresse en paramètre d’une fonction pour directement la modifier. On crée alors une classe
graphique.c contenant les fonctions permettant de modifier les variables de type Graphique.
On peut alors voir Graphique comme un objet Java avec ses attributs définis dans la structure
et ses méthodes dans la classe graphique.c
-Des surfaces SDL pour : tracer le cadre du graphique, le fond et pour écrire les valeurs
minimales et maximales
Pour permettre de tracer un graphique, j’ai réalisé une fonction ‘tracer_graphe’. Celle-
ci prend en entier la position, la taille, les valeurs max et min, le nombre de points et un tableau
de mesures à tracer. La fonction calcule l’échelle des ordonnées en fonction de la hauteur du
graphe et des valeurs maximale et minimale. L’échelle des abscisses est calculée pour pouvoir
positionner 800 points dans toute la largeur du graphique. S’il y a plus de points à tracer seuls
les 800 derniers le seront. Cela entraînera un défilement du signal avec le temps.
On entre ensuite dans une boucle qui parcourt tous les points à tracer et calcule
l’ordonnée et l’abscisse d’un point et de son suivant par rapport à la fenêtre principale grâce à
la position du graphe, sa taille et les échelles en abscisse et ordonnée. On trace alors une ligne
entre les deux points et on recommence pour tous les points.
Tracer une ligne en SDL n’est pas si simple qu’il n’y parait. Il faut en fait modifier un à
un tous les pixels entre les deux extrémités. Cependant, vu l’importance d’une telle fonction,
de nombreux sites offrent le code permettant de la réaliser. J’ai donc pu récupérer une fonction
qui trace une ligne [DEVELOPPEZ LIGNE]. Cette fonction ligne prend en entrée l’abscisse et
l’ordonnée des deux points à relier ainsi que la couleur de la ligne. Elle utilise les fonctions
‘SetPixel’ définies dans la documentation de la SDL et ‘echangerEntier’ qui permet
d’intervertir les deux points en entrée. Toutes ces fonctions, de même que ‘tracer_graphe’ ont
été placées dans la classe tracer_graphe.c pour plus de clarté.
Améliorations du programme :
On peut alors constater un retard dans le lancement de chaque fonction. Ce retard est dû
à deux phénomènes distincts :
-le premier, et aussi le plus prévisible est dû au temps pris pour tracer les graphiques. Celui-ci
est compris entre 5 et 10 ms. Cela laisse une marge de temps très réduite pour tracer 4 graphes
actualisés toutes les 40ms mais cela reste suffisant. Il s’ensuit que le tracé des graphes se fait
en décalé. Mais cela ne devrait pas ralentir le tracé en lui-même.
-la deuxième raison est plus subtile. Elle provient d’un non respect de la période des timers de
lecture de valeurs (4ms). En effet cette lecture est faite toutes les 10ms! Et si l’on fixe la
période à 11ms, elle est en réalité à 20ms! La période doit donc être arrondie à la dizaine de
ms.
Pour pouvoir utiliser la machine Matlab dans différentes fonctions, celle-ci doit être
déclarée de façon publique dans un fichier .h. De plus la fonction ep = engOpen(NULL); doit
être lancée dans toutes les fonctions qui l'utilisent.
Compte tenu des faibles rapports signal sur bruit des différentes applications d'interface
cerveau-machine, le domaine de recherche sur les BCI est un secteur qui regroupe de
nombreuses techniques de traitement du signal et le développement des activités et des études
sur les ondes cérébrales va demander un apport encore plus important de méthodes.
EDLINGER G., GUGER C., The Brain-Computer Interface, [en ligne], janvier 2006, [consulté
le 16 octobre 2007],
< http://www.mathworks.com/company/newsletters/news_notes/jan06/brain.html >
FIEVET C., Le contrôle par la pensée, l'interface ultime ?, [en ligne], mars 2005, [consulté le
7 novembre 2007], < http://www.internetactu.net/?p=5854 >
GLOVER John R., JANSEN Ben H., Brain-wave Analysis, [en ligne], 2008, [consulté le 15
mars 2008], < http://www.egr.uh.edu/cnecs/research/?e=brainwaveanalysis >
GUILLEMAUD R., Vers des interfaces BCI intégrées et implantables, [en ligne], mai 2007,
[consulté le 30 novembre 2007], < www-bci.univ-lille1.fr/more/journee-ifrath-2007/regis-
guillemaud.pdf >
JACQUEMIN C., Les Interfaces cerveau/ordinateur ont le vent en poupe, [en ligne] , janvier
2007, [consulté le 16 octobre 2007],
< http://www.automatesintelligents.com/labo/2007/jan/bci.html >
WOLKAM, SecondLife, pour mieux se comprendre, [en ligne], mars 2007, [consulté le 22
février 2008], < http://secondworld.wordpress.com/2007/03/20/secondlife-pour-mieux-se-
comprendre >
Sites Internet :
[WIKI CORTEX]
http://fr.wikipedia.org/wiki/Cortex_sensoriel_et_plasticit%C3%A9_c%C3%A9r%C3%A9bral
e, [en ligne], consulté le 25 janvier 2008
[MEDPHAR] http://medphar.univ-poitiers.fr/DU_alzheimer/
EEG_et_demences_DU_ALZ_2005.pps, [en ligne], consulté le 7 décembre 2007
[ELECTRODESALES] http://www.electrodesales.com/electrode-accessories-eeg-electrode-
cap.html, [en ligne], consulté le 19 octobre 2007
Installation de mingw :
Installation de la SDL :