🚧 DĂ©tection de chute Ă  partir des points du squelette en 2D

SystÚme simple de détection de chute : Mediapipe, OpenCV et filtre de Kalman

Mlachahe Said Salimo
Wanabilini
13 min readFeb 27, 2023

--

Cet article fait suite Ă  notre prĂ©cĂ©dent projet, DAÏO, un tableau mural connectĂ© pour la tĂ©lĂ©assistance de personnes ĂągĂ©es. Nous avons dĂ©jĂ  prĂ©sentĂ© rapidement dans un premier article (lien ci-dessous) les caractĂ©ristiques de ce dispositif innovant qui permet notamment de dĂ©tecter les chutes. Ici, nous prĂ©senterons les suites de nos avancĂ©es.

Nous allons nous concentrer sur la mĂ©thode de dĂ©tection de chute que nous avons mise en place, basĂ©e sur l’analyse des points d’un squelette en 2D.

DĂ©monstration de notre systĂšme de dĂ©tection de chute — Ă  voir plus bas

Pourquoi le squelette en 2D ? Pourquoi pas en 3D ?

L’intĂ©rĂȘt de concevoir un algorithme capable de dĂ©tecter une chute Ă  partir des coordonnĂ©es spatiales d’un squelette en 2D plutĂŽt qu’en 3D rĂ©side principalement dans la simplicitĂ© de mise en Ɠuvre de la dĂ©tection en 2D. En effet, au-delĂ  de tous ses inconvĂ©nients, la dĂ©tection Ă  partir un squelette en 2D est moins gourmande en ressources matĂ©rielles et logicielles, car on manipule moins de donnĂ©es, ce qui pourrait permettre une mise en place plus rapide et moins coĂ»teuse ; et ce qui l’a rend beaucoup plus simple Ă  implĂ©menter qu’avec un squelette en 3D.

Tableau comparatif des avantages et des inconvĂ©nients de la dĂ©tection de chute Ă  partir des coordonnĂ©es spatiales d’un squelette en 2D plutĂŽt que 3D — gĂ©nĂ©rĂ© par ChatGPT (important de le prĂ©ciser)

Cependant, il est important de noter que certes la détection en 3D peut offrir une précision supérieure dans certaines situations, mais que le choix entre la détection en 2D et en 3D dépend des exigences spécifiques de chaque application et du contexte.

Notre méthodologie de détection de chute en 2D

Un systÚme classique de vidéosurveillance [1, 2] est composé de 3 modules :

  • Le module de dĂ©tection : permet l’extraction des objets mobiles prĂ©sents sur les images de la sĂ©quence vidĂ©o en les sĂ©parant de l’arriĂšre-plan. C’est une Ă©tape de traitement de bas niveau.
  • Le module de suivi : permet une estimation temporelle des trajectoires des diffĂ©rents objets mobiles.
  • Le module de reconnaissance : permet de reconnaĂźtre des comportements suspects et gĂ©nĂšre une prise de dĂ©cision appropriĂ©e Ă  ce comportement.
Pipeline typique d’un processus de vidĂ©osurveillance [1]

Pour notre projet de dĂ©tection de chute Ă  partir des points d’un squelette en 2D, nous avons construit la pipeline suivante :

Pipeline de notre processus de vidéosurveillance de chute

En résumé, les étapes sont les suivantes :

  1. DĂ©tecter les points d‘intĂ©rĂȘt du corps
  2. Suivre la position et l’accĂ©lĂ©ration de ces points
  3. Reconnaitre la chute en fonction de seuils de position et d’accĂ©lĂ©ration atteint par ces points

À noter que ces 3 Ă©tapes cardinales structurent cet article.

1. DĂ©tection du corps en mouvement

La dĂ©tection du mouvement constitue la premiĂšre Ă©tape d’un systĂšme de vidĂ©osurveillance, elle permet de dĂ©tecter les objets mobiles sur la scĂšne.

PlutĂŽt que qu’une solution simpliste de dĂ©tection de mouvement basĂ©es sur de simples diffĂ©rences d’images ou de soustraction de fond, pour la dĂ©tection de l’objet nous avons choisi d’utiliser la bibliothĂšque Mediapipe pour dĂ©tecter directement le corps d’une personne dans la piĂšce.

1.1 DĂ©tection des points de squelette par Mediapipe Pose

En effet, avec MediaPipe Pose nous pouvons dĂ©tecter la pose humaine, c’est-Ă -dire les principaux points d’articulation du corps humain. Cette solution ML nous permet d’extraire 33 points d’articulation du corps, avec leurs coordonnĂ©es dans un repĂšre 3D, Ă  partir d’images vidĂ©o RVB [4].

Pour notre projet, notre code de dĂ©tection de la posture sera stockĂ© dans le fichier PoseModule.py, dont nous explicitons les fonctionnalitĂ©s dans l’article suivant :

Nous n’utiliserons pas la coordonnĂ©e z des points, elle ne nous intĂ©resse plus parce que nous nous restreignons Ă  la 2D. Par ailleurs, tous les points dĂ©tectĂ©s par Mediapipe ne nous intĂ©ressent pas. Oui car, en s’inspirant du travail de Zaid Mundher & Jiaofei Zhong [8] sur la dĂ©tection de chute Ă  partir de la pose en 2D, parmi tous les points dĂ©tectĂ©s, ceux qui nous intĂ©ressent vraiment pour la dĂ©tection de chute sont ceux : de la tĂȘte, du centre des Ă©paules, du centre du bassin, de la cheville droite et de la cheville gauche. Ils sont marquĂ©s en jaune sur la figure ci-dessous :

Les points d’articulations prĂ©dits par Mediapipe [4] avec nos points d’intĂ©rĂȘts marquĂ©s en jaunes.

DĂšs lors que ces points d’intĂ©rĂȘt sont dĂ©tectĂ©s, il va falloir les suivre.

2. Suivi du corps en mouvement

Le suivi des objets est une Ă©tape importante dans un systĂšme de vidĂ©osurveillance. Il consiste Ă  faire une estimation de la position des objets mobiles dans le temps et l’espace du champ de vision afin de dĂ©terminer leur trajectoire Ă  travers les images successives d’une sĂ©quence [3].

2.1 Suivi de la position par Mediapipe Pose

De fait, avec Mediapipe Pose c’est non seulement la dĂ©tection, mais aussi le suivi de la pose corporelle qui s’opĂšre tout le long de la vidĂ©o.

DĂ©tection et suivi de la position des points du corps par Mediapipe (via PoseModule.py) avec nos points d’intĂ©rĂȘts entourĂ©s en jaunes

L’image ci-dessus Ă  Ă©tĂ© gĂ©nĂ©rĂ©e via les fonctionnalitĂ©s de mon fichier PoseModule.py auxquelles s’ajoute la fonction suivante que j’ai crĂ©e :

  • drawLm : permettant de dessiner les points d’intĂ©rĂȘts du corps sur l’image

GrĂące Ă  Mediapipe Pose, la position des points d’intĂ©rĂȘt du corps est connue en temps rĂ©el. À cette mĂ©thode, on va ajouter quelque chose de couramment employĂ©e dans les processus de suivi : le filtre Kalman.

2.2 Suivi de l’accĂ©lĂ©ration via le filtre de Kalman

À quoi sert le filtre de Kalman ? Pour faire simple, le filtre de Kalman est un algorithme de traitement de donnĂ©es rĂ©cursif qui estime l’état x’ d’un systĂšme Ă  l’instant t Ă  partir des Ă©tats prĂ©cĂ©dents x Ă  l’instant t-1. À chaque estimation, nous associons une mesure d’incertitude P (bruit gaussien) [5, 9].

L’état x d’un systĂšme. Ce vecteur est composĂ© d’une position p, d’une vĂ©locitĂ© v et d’une accĂ©lĂ©ration a.

Le filtre fonctionne de maniĂšre cyclique et possĂšde deux phases distinctes — la prĂ©diction et correction :

  • PrĂ©diction : On utilise l’état estimĂ© pour prĂ©dire l’état et l’incertitude actuel.
  • Correction : On utilise les observations de nos capteurs pour corriger l’état prĂ©dit et obtenir une estimation plus prĂ©cise.

Les étapes récursives du filtre de Kalman sont illustrées ci-dessous :

Etapes de l’algorithme du filtre de Kalman rĂ©cursif (Source)

Voilà à quoi ressemble notre algorithme aprÚs implémentation, celui-ci sera stocké dans le fichier KalmanFilter.py :

Ainsi, l’application du filtre de Kalman dans notre projet est le suivant : Ă  chaque instant de la vidĂ©o, la position du point d’intĂ©rĂȘt captĂ© par Mediapipe Pose va venir nourrir un filtre de Kalman, et celui-ci va pouvoir donner une prĂ©diction de l’état du point d’intĂ©rĂȘt Ă  l’image suivante.

On peut alors tracer la direction de l’accĂ©lĂ©ration du point d’intĂ©rĂȘt [6] — une flĂšche allant du point prĂ©dit (x, y) au point (x+ax, y+ay) :

<gif exemple suivi point occultĂ©, mais dont l’estimation est effective>

On remarque que le filtre de Kalman permet de suivre un point en mouvement, en estimant sa position y compris en cas d’occultations.

Pour la suite, nous appliquerons tout simplement ce processus sur les 5 points d’intĂ©rĂȘts du corps, en leur associant respectivement un filtre de Kalman.

3. Classification du corps en mouvement

La derniĂšre phase d’un systĂšme de vidĂ©osurveillance, en gĂ©nĂ©ral, concerne l’analyse et la reconnaissance des activitĂ©s ou des comportements. Dans un cas comme dans l’autre, le problĂšme de reconnaissance peut ĂȘtre considĂ©rĂ© comme un problĂšme de classification. Il s’agit d’une opĂ©ration de classification supervisĂ©e ou non supervisĂ©e.

Plusieurs outils mathĂ©matiques sont utilisĂ©s dans la reconnaissance : comme les modĂšles de Markov cachĂ©s, les algorithmes de recalage temporel ou encore les rĂ©seaux de neurones artificiels [1, 2]. Mais pour notre projet nous avons fait le choix d’une mĂ©thode de classification beaucoup plus simple : une mĂ©thode non supervisĂ©e basĂ©e essentiellement sur une logique de seuil.

3.1 Seuils sur la position

En effet, comme dit prĂ©cĂ©demment, nous nous sommes Ă©normĂ©ment inspirĂ©s du systĂšme mobile dĂ©tecteur de chute de Zaid Mundher & Jiaofei Zhong [8] : un petit robot, reliĂ© Ă  une camĂ©ra Kinect Sensor, qui peut dĂ©tecter les chutes d’une personne ĂągĂ©es. Ce qui nous intĂ©resse plus particuliĂšrement dans leur systĂšme c’est que, lorsque le sol n’est pas visible ou dĂ©tectable, l’algorithme proposĂ© dĂ©pend du systĂšme de coordonnĂ©es spatiales du squelette 2D pour dĂ©tecter les chutes ! Illustration dans la figure ci-dessous :

Méthode de détection de chute à partir du squelette 2D avec des seuils [8]

Ce qu’il faut comprendre de l’algorithme : si la coordonnĂ©e Y des 5 points d’intĂ©rĂȘt est infĂ©rieure Ă  un seuil donnĂ©, une chute est dĂ©tectĂ©e.

Pour notre projet, il a fallu rĂ©arranger cet algorithme pour qu’il corresponde plus Ă  nos spĂ©cificitĂ©s : par exemple pour nous, l’axe y est orientĂ© vers le bas, ainsi, pour qu’une chute soit dĂ©tectĂ©e il faut que la coordonnĂ©e Y des points d’intĂ©rĂȘt soit supĂ©rieure (et non infĂ©rieure) Ă  un seuil donnĂ©.

Voilà à quoi ressemble notre algorithme aprÚs implémentation :

Cette fonction sera appelĂ©e Ă  chaque image de la vidĂ©o, et ainsi dĂ©terminera Ă  tout instant s’il y a potentialitĂ© de chute ou non Ă  partir de la position des points d’intĂ©rĂȘt.

Et concernant le seuil, il sera défini automatiquement comme la moitié de la hauteur de la vidéo, via les lignes de codes suivantes :

# Charger la vidéo à partir du fichier
cap = cv2.VideoCapture('video.mp4')

# Initialisation du seuil
frame = cap.read()[1]
seuil_position = frame.shape[0] // 2

Pour la suite, afin de bien mettre en Ă©vidence les rouages de notre fonction PersonFallingDown_position, nous avons crĂ©Ă© une fenĂȘtre pour dessiner la coordonnĂ©e Y des points d’intĂ©rĂȘt avec leur seuil, ainsi qu’une deuxiĂšme fenĂȘtre permettant l’analyse en temps rĂ©el des points par rapport Ă  leur seuil via des bandeaux de dĂ©filement [7] :

Analyse de la détection de chute via la position du corps grùce à notre fonction PersonFallingDown_position

Cependant, le fait de se baser uniquement sur la position possĂšde plusieurs limites. Par exemple, si une personne se baisse pour rĂ©cupĂ©rer un objet sur le sol ou bien se met par terre pour faire des pompes, cela pourra ĂȘtre traduit comme une potentialitĂ© de chute : cela crĂ©e des faux positifs.

D’oĂč la nĂ©cessitĂ© de trouver une nouvelle variable Ă  analyser en dehors de la position. VoilĂ  pourquoi nous avons ajoutĂ©, en addition avec la mĂ©thode prĂ©cĂ©dente, une deuxiĂšme mĂ©thode basĂ©e cette fois-ci sur l’accĂ©lĂ©ration des points d’intĂ©rĂȘt, pour diminuer le nombre de faux positifs.

3.2 Seuils sur l’accĂ©lĂ©ration

En effet, grĂące au filtre de Kalman nous avons pu estimer la trajectoire future et ainsi l’accĂ©lĂ©ration de chaque point d’intĂ©rĂȘt. GrĂące Ă  l’existence de ces donnĂ©es, nous implĂ©mentons une mĂ©thode avec un fonctionnement similaire Ă  la mĂ©thode prĂ©cĂ©dente, sauf que cette fois-ci : si la coordonnĂ©e Y de l’accĂ©lĂ©ration de (3 points sur les) 5 points d’intĂ©rĂȘt est supĂ©rieure Ă  un seuil donnĂ©, une chute est dĂ©tectĂ©e.

Voilà à quoi ressemble notre algorithme aprÚs implémentation :

Cette fonction sera appelĂ©e Ă  chaque image de la vidĂ©o, et ainsi dĂ©terminera Ă  tout instant s’il y a potentialitĂ© de chute ou non Ă  partir de l’accĂ©lĂ©ration des points d’intĂ©rĂȘt.

Et concernant le seuil, il sera dĂ©fini automatiquement comme l’un sixiĂšme de la hauteur de la vidĂ©o, via les lignes de codes suivantes :

# Charger la vidéo à partir du fichier
cap = cv2.VideoCapture('video.mp4')

# Initialisation du seuil
frame = cap.read()[1]
seuil_acceleration = frame.shape[0] // 6

Encore une fois, pour la suite, afin de bien mettre en Ă©vidence les rouages de notre fonction PersonFallingDown_acceleration, nous avons crĂ©e une fenĂȘtre pour dessiner la coordonnĂ©e Y des points d’intĂ©rĂȘt avec leur seuil, ainsi qu’une deuxiĂšme fenĂȘtre permettant l’analyse en temps rĂ©el des points par rapport Ă  leur seuil via des bandeaux de dĂ©filement [7] :

Analyse de la dĂ©tection de chute via l’accĂ©lĂ©ration des points d’intĂ©rĂȘt du corps grĂące Ă  notre fonction PersonFallingDown_acceleration

On remarque que parfois notre fonction PersonFallingDown_acceleration, Ă  elle seule, engendre certes quelque faux positif pour la dĂ©tection de chute. Cependant, associĂ©e Ă  PersonFallingDown_position, cette mĂ©thode permettra de tomber sur des rĂ©sultats plus satisfaisants — comme on pourra le voir par la suite, dans la partie DĂ©monstration.

3.3 DĂ©termination de l’état de chute

Ainsi, l’état de chute est liĂ© Ă  ce que retourne nos deux fonctions de dĂ©tection de chute. En clair, c’est “l’intersection” entre les alertes au niveau de la position et celles au niveau de l‘accĂ©lĂ©ration, se matĂ©rialisant par l’opĂ©rateur logique AND entre bool_alarme_position et bool_alarme_acceleration.

À noter que dans notre systĂšme, dĂšs lors que la chute est dĂ©tectĂ© : la sĂ©quence est sauvegardĂ©e puis enregistrĂ© dans le dossier sauvegarde, puis un message SMS est envoyĂ© sur le tĂ©lĂ©phone de l’utilisateur (via l’API twilio) 


Démonstrations de la détection de chute

Mon projet de détection de chute est disponible sur mon Github.

DAIOProject
├── DataVideos
│ ├── 50WayToFall_extract1.mp4
│ ├── ...
│ └── video (27).avi
├── sauvegarde
│ ├── 2023_02_12_00_34_31.avi
│ ├── ...
│ └── 2023_02_18_12_56_09.avi
├── FallDetectionMethod.py
├── GraphicDesigner.py
├── KalmanFilter.py
├── PoseModule.py
└── TestFallDetection.py

Pour tester le code, il suffit de lancer le fichier TestFallDetection.py.

Démonstration 1 : La chute est détecté sans soucis particuliers
  • DĂ©monstration 2 — une vidĂ©o de chutes complexes de Kevin Parry :
DĂ©monstration 2 : La majoritĂ© des chutes sont dĂ©tectĂ©es sauf celles dont les seuils d’accĂ©lĂ©rations n’ont pas Ă©tĂ© atteint
DĂ©monstration 3 : Aucune chute n’est dĂ©tectĂ©e. Les faux positifs Ă©mit par PersonFallingDown_acceleration ne sont pas pris en compte

Limites de la méthode

Bien qu’il ait Ă©tĂ© plaisant de faire une dĂ©monstration de notre mĂ©thode de dĂ©tection de chute Ă  partir des points du squelette en 2D, il est maintenant temps d’aborder ses limites, qui — si on les comprend — sont autant d’axes amĂ©lioration pour la suite.

Limitations dans la détection des points

  • Pour commencer, la dĂ©tection des points de squelette par Mediapipe Pose peut ĂȘtre influencĂ©e par des conditions d’éclairage ou de bruit dans l’environnement de la personne, ce qui peut fausser la dĂ©tection.
  • Également, si la personne est en parti cachĂ©e par un objet ou que la camĂ©ra est obstruĂ©e, la dĂ©tection peut ĂȘtre moins prĂ©cise, manquer de certains points de squelette, voire complĂštement fausse.

Limitations dans le suivi des points

  • D’ailleurs, le suivi des points de squelette par le filtre de Kalman peut ĂȘtre difficile dans des situations complexes oĂč les mouvements sont rapides ou chaotiques, en particulier en raison de ses hypothĂšses linĂ©aires. Ainsi, dans le cas d’une chute (un phĂ©nomĂšne qui n’est pas du tout linĂ©aire), le filtre de Kalman ne sera plus en mesure d’estimer l’état du systĂšme de maniĂšre prĂ©cise. Des approches plus avancĂ©es, telles que les filtres de Kalman Ă©tendus (EKF) ou les filtres de particules (PF), peuvent ĂȘtre utilisĂ©es pour surmonter ces limitations.
  • En outre, les problĂšmes de camouflage et d’obstruction citĂ©s plus haut qui affectent la dĂ©tection peuvent aussi affecter le suivi des points de squelette. Et tout cela mĂȘme si l’on a vu que l’implĂ©mentation du filtre de Kalman nous permet d’estimer un Ă©tat d’un point mĂȘme en cas d’occultation, mais cela est vrai seulement si celle-ci est brusque ; en effet, plus l’occultation est longue, moins le filtre est corrigĂ© et plus l’estimation est fausse.

Limitations dans la reconnaissance de la chute

  • De fait, la reconnaissance de la chute est affectĂ©e par des erreurs de dĂ©tection ou de suivi des points d‘intĂ©rĂȘt citĂ©s juste avant, ce qui entraĂźne des faux positifs.
  • De plus, la reconnaissance de la chute est biaisĂ© par l’éloignement ou non du corps. Par exemple, plus le corps est Ă©loignĂ©, plus le corps est petit et plus il sera succeptible de franchir les seuils de position de PersonFallingDown_position. Quoi qu’il en soit, pour corriger cela, il faudrait peut-ĂȘtre que les seuils de position et d’accĂ©lĂ©ration soient initialisĂ©es en fonction de la taille de la personne, et non plus en fonction de la taille de l’image comme nous avons fait.
  • D’une maniĂšre similaire Ă  la fonction PersonFallingDown_position, qui engendre des faux positifs si une personne s’allonge au sol pour une raison quelconque, la fonction PersonFallingDown_acceleration peut engendrer des faux positifs si une personne se baisse trop rapidement (cf. DĂ©monstration 3).

Conclusion

En somme, cet article a prĂ©sentĂ© notre mĂ©thode de dĂ©tection de chute Ă  partir des points d’un squelette en 2D, pour le projet DAÏO, un tableau mural connectĂ© pour la tĂ©lĂ©assistance de personnes ĂągĂ©es.

Pour dĂ©tecter une chute, nous avons mis en place une pipeline de vidĂ©osurveillance avec trois Ă©tapes clĂ©s : la dĂ©tection des points du corps, le suivi de la position et de l’accĂ©lĂ©ration de ces points, et la dĂ©termination de la chute en fonction de seuils de position et d’accĂ©lĂ©ration atteint par ces points.

Cette mĂ©thode de dĂ©tection de chute Ă  partir des points d’un squelette en 2D est simple et semble peu gourmande en ressources, mais elle entraĂźne des rĂ©sultats Ă  peine prĂ©cis en raison de plusieurs limites : celles propres Ă  la bibliothĂšque Mediapipe dans la dĂ©tection du corps, celles dues Ă  l’imprĂ©cision du suivi avec filtre de Kalman simple, ou bien celles liĂ©s Ă  l’implĂ©mentation prosaĂŻque de nos fonctions de reconnaissance. Mais il faut aussi compter celles dues tout simplement Ă  notre choix du travail uniquement Ă  partir du squelette 2D, qui engendre par exemple de la perte d’informations sur la profondeur et l’orientation du corps.

En fin de compte, notre mĂ©thode reste perfectible. MalgrĂ© tout cela, il faut noter qu’elle s’inscrit parfaitement dans l’esprit (et uniquement l’esprit, pour l’instant) du projet DAÏO, qui vise Ă  fournir une solution rapide, simple et peu coĂ»teuse pour dĂ©tecter les chutes chez les personnes ĂągĂ©es — lĂ  oĂč la dĂ©tection Ă  partir d’un squelette en 3D nous semblait ĂȘtre superflue.

Mlachahe SAID SALIMO.

--

--

Mlachahe Said Salimo
Wanabilini
Editor for

French Student in Computer Science for Health. J'Ă©cris mes notes ici + J'Ă©cris pour apprendre, pas parce que je sais !