Surveillance du rythme cardiaque (PPG) (TIPE prépa)
Juin 2024
Dans le cadre de mon Travail d'Initiative Personnelle Encadré (TIPE) réalisé au cours de mes deux années de classe préparatoire, j'ai exploré les méthodes de surveillance de la fréquence cardiaque et leurs applications dans la prévention des incidents de santé. Cet article présente en détail mes recherches et expérimentations réalisées dans le cadre de ce projet.
Dans cet article, je vais développer l'une des méthodes permettant le suivi de la fréquence cardiaque : la photopléthysmographie, souvent abrégée en PPG. Pour comprendre le fonctionnement de la PPG, il est essentiel de saisir ce qu'est un battement cardiaque et les effets qu'il produit. À chaque battement, un afflux de sang se propage dans les vaisseaux, ce qui entraîne une augmentation du volume sanguin et un épaississement des tissus, suivi d'une diminution du volume due au reflux sanguin. La phase d'augmentation du volume est appelée systole, tandis que la phase de reflux est appelée diastole. La photopléthysmographie utilise ce principe pour mesurer les variations d'opacité des tissus.

Pour détecter ces variations, on utilise une LED émettant une lumière dans une certaine gamme de longueurs d'onde, ainsi qu'une photodiode qui convertit l'intensité lumineuse reçue en signal électrique, sensible elle aussi dans une certaine gamme de longueurs d'onde.

Pour maximiser la sensibilité et détecter les variations les plus significatives, il est crucial de choisir la bonne gamme de longueurs d'onde. Étant donné que le sang est principalement composé d'hémoglobine et d'oxyhémoglobine, il est pertinent d'analyser le spectre d'absorption de ces composants.

Sur ce graphique, on observe qu'il est pertinent de choisir une longueur d'onde comprise entre 520 et 550 nm, correspondant à la couleur verte. C'est pourquoi la plupart des montres connectées émettent une lumière verte sur leur face arrière. Dans mon projet, j'ai utilisé un capteur similaire à celui d'une montre connectée, où la LED et la photodiode sont positionnées du même côté, comme illustré sur la photo ci-dessous.

En utilisant une carte Arduino, j'ai pu réaliser une première acquisition en plaçant le capteur sur mon poignet. Voici la courbe obtenue.

Sur cette courbe, on distingue clairement les phases de systole et de diastole, ce qui permet de déduire la fréquence cardiaque. Pour le traitement du signal afin d'obtenir les battements par minute (bpm), j'ai exploré plusieurs approches : la première consiste à appliquer la transformation de Fourier, tandis que la seconde repose sur la détection de pics. Commençons par examiner la méthode utilisant la transformation de Fourier.
Tout d'abord pour éviter le repliement du spectre, nous allons d'abord appliquer un filtre passe-bas de premier ordre sur notre signal.
def filtreList(L: np.array, tau=0.1, Te=0.01) -> np.array:
Lfiltre = np.zeros_like(L)
Lfiltre[0] = L[0]
for i in range(1, len(L)):
Lfiltre[i] = Lfiltre[i - 1] + Te / tau * (L[i] - Lfiltre[i - 1])
return Lfiltre
Ensuite, en utilisant la fonction rfft de NumPy, nous pouvons calculer la transformation de Fourier.
yf = rfft(valeurs, N)
# Valeurs absolues de yf
yf = np.abs(yf)
# Création du tableau NumPy contenant les fréquences pour lesquelles
# les amplitudes des fonctions sinusoïdales ont été calculées
M = len(yf)
xf = np.linspace(0, fe / 2, M)

Avec la transformation de Fourier, nous obtenons une fréquence cardiaque de 76 bpm, ce qui est cohérent avec les attentes.
Passons maintenant à la méthode de détection des pics. L'objectif de cette méthode est de compter le nombre de pics durant la phase de systole afin de calculer le bpm. Pour ce faire, j'ai commencé par filtrer le signal, puis appliqué un algorithme de détection de pics. Le graphique résultant est présenté ci-dessous.

Utiliser simplement un algorithme pour détecter les pics ne suffit pas, car il y a un grand nombre de faux positifs. J'ai donc tenté d'entraîner un réseau de neurones. L'objectif de ce réseau est de déterminer pour chaque point s'il s'agit d'un bon point ou d'un faux positif. Pour cela, en entrée de mon réseau, je lui fournis 40 valeurs du signal avant et après le point, soit un total de 80 valeurs, ce qui représente un peu moins d'une seconde.

Après avoir annoté manuellement plus de 150 points en indiquant s'ils étaient des faux positifs ou non, j'ai pu passer à l'entraînement du réseau de neurones en utilisant la bibliothèque Scikit-learn.
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.2)
regression = MLPClassifier(hidden_layer_sizes=(50, 10), activation="relu", solver="adam")
regression.fit(X_train, Y_train)
# Test avec score
print(regression.score(X_test, Y_test))
filename = 'model92.sav'
joblib.dump(regression, filename)
Une fois le modèle entraîné, j'ai obtenu un score de 92 %, ce qui indique que le modèle est fiable à 92 % pour les données utilisées lors de la phase de test. J'ai ensuite enregistré les poids du modèle pour les utiliser ultérieurement lors de la phase d'inférence. Grâce à ce modèle, j'ai obtenu le graphique suivant :

Avec cette méthode, j'ai également obtenu une fréquence cardiaque de 76 bpm, ce qui confirme la cohérence entre les deux résultats et leur alignement avec les données réelles. Cependant, au cours de mes expérimentations, j'ai identifié certaines limitations pour les deux méthodes.
Tout d'abord, la transformation de Fourier est moins sensible aux artefacts de mesure et aux signaux irréguliers, contrairement à la détection de pics, qui est plus susceptible de commettre des erreurs en présence de signaux irréguliers. En revanche, la transformation de Fourier peut ne pas capter les variations rapides de la fréquence cardiaque, car elle évalue la fréquence sur une période plus longue. De plus, la transformation de Fourier est plus complexe à implémenter en raison du calcul intensif qu'elle requiert, contrairement au réseau de neurones, qui est plus léger une fois entraîné. Par ailleurs, la détection de pics peut offrir une estimation plus précise de la fréquence cardiaque instantanée.
Maintenant que nous avons récupéré la fréquence cardiaque, nous pouvons nous concentrer sur les risques potentiels que cette information permet de prévenir :
- Arythmies cardiaques : Des variations anormales de la fréquence cardiaque, telles que des battements irréguliers, peuvent être un indicateur d'arythmies.
- Détection de la déshydratation : Une fréquence cardiaque plus élevée que la normale pendant l'exercice peut signaler un état de déshydratation.
- Détection du stress ou de la fatigue excessive : La variabilité de la fréquence cardiaque (VFC) est un indicateur de l'état du système nerveux autonome et de la récupération. Une faible VFC peut révéler du stress ou une fatigue excessive.
En conclusion, ce projet m'a permis d'explorer en profondeur les techniques de surveillance de la fréquence cardiaque et leur application dans la prévention de divers risques de santé. À travers l'utilisation de méthodes comme la transformation de Fourier et la détection de pics, ainsi que l'entraînement d'un réseau de neurones pour affiner la précision des résultats, j'ai pu démontrer l'efficacité et les limites de ces approches. Les résultats obtenus, cohérents avec les données réelles, soulignent l'importance de la sélection des méthodes en fonction du contexte d'utilisation.
Ce travail met en lumière le potentiel de la technologie pour non seulement surveiller, mais aussi anticiper des problèmes de santé tels que les arythmies cardiaques, la déshydratation, et le stress. En maîtrisant ces outils, nous ouvrons la voie à des applications concrètes dans le domaine de la santé, avec des implications pour la prévention et le bien-être des individus. Ce projet constitue ainsi une étape importante dans mon parcours d'ingénieur, consolidant mes compétences en traitement du signal et en intelligence artificielle, tout en renforçant mon engagement envers des solutions technologiques ayant un impact réel.