https://d226lax1qjow5r.cloudfront.net/blog/blogposts/real-time-human-detection-with-opencv-and-vonage-sms-api-dr/Blog_Human-Detection_1200x600.png

Détection humaine en temps réel avec OpenCV

Publié le April 15, 2020

Temps de lecture : 5 minutes

Cet article de blog montre comment construire votre propre caméra Video "intelligente". Il montrera comment prendre une image à partir du cadre d'une caméra web, détecter s'il y a un humain dans le cadre, et envoyer un SMS via les API de communication de Vonage pour vous avertir des menaces potentielles.

Introduction

Cette idée m'est venue après le cambriolage de la maison de mes parents. Ils vivent dans un endroit isolé, sans caméras de sécurité, et la police n'a jamais pu trouver l'auteur du crime. Mes parents ont donc décidé d'équiper la maison de matériel de sécurité. Comme j'étais étudiant à l'époque, j'ai décidé d'utiliser mes compétences pour construire un système de sécurité pour eux.

N'hésitez pas à me contacter car je l'ai entièrement développé pour en faire un prototype fonctionnel qui a été utilisé par ma famille !

Exigences en matière de matériel

Vous devez utiliser un Raspberry Pi (j'ai utilisé un Raspberry Pi 2), a caméra Raspberry Piet une "caméra de sécurité "factice.

Conditions préalables

Pour réaliser ce projet, vous aurez besoin des éléments suivants en plus du matériel :

Vonage API Account

To complete this tutorial, you will need a Vonage API account. If you don’t have one already, you can sign up today and start building with free credit. Once you have an account, you can find your API Key and API Secret at the top of the Vonage API Dashboard.

L'algorithme de détection d'objets

Dans ce tutoriel, nous utiliserons le classificateur Haar. Il s'agit d'une méthode efficace de détection d'objets développée par Paul Viola et Michael Jones dans leur article de 2001 intitulé "Rapid Object Detection using a Boosted Cascade of Simple Features" (Détection rapide d'objets à l'aide d'une cascade de caractéristiques simples).

Au départ, l'algorithme a besoin d'un grand nombre d'images positives (dans notre cas, des images de différentes personnes) et d'images négatives (des images qui ne contiennent pas de personne dans le cadre) pour entraîner le classificateur.

À partir de là, nous devons extraire certaines caractéristiques du classificateur. Chaque caractéristique est une valeur unique obtenue en soustrayant la somme des pixels situés sous le rectangle blanc de la somme des pixels situés sous le triangle noir.

Pour en savoir plus sur le classificateur en cascade et l'algorithme qui le sous-tend, consultez l'article suivant OpenCV : article sur le classificateur en cascade.

Mise en œuvre

Sur votre Raspberry Pi, créez un nouveau fichier Python et importez toutes les bibliothèques nécessaires à l'aide des instructions import suivantes :

import cv2
import nexmo
import time

Ces bibliothèques sont utilisées pour détecter des personnes, pour communiquer aux utilisateurs des informations sur les personnes détectées et pour calculer la différence de temps entre les textes envoyés.

Ensuite, nous devrons commencer à capturer les séquences vidéo à partir de votre caméra disponible :

video_captured = cv2.VideoCapture(0)

En spécifiant 0 dans le paramètre ci-dessus, nous utiliserons la première caméra vidéo disponible - en général, il n'y en a qu'une, mais si vous avez branché une caméra externe, vous pouvez spécifier le flux à utiliser en passant le paramètre approprié à VideoCapture.

Maintenant, initialisons le client SMS de l'API Vonage. Pour cela, vous aurez besoin de votre clé API et de votre secret qui se trouvent dans le tableau de bord du compte API Vonage que vous avez créé :

client_nexmo = nexmo.Client(key=’your_project_key’, secret=’your_secret_key’)

Ensuite, nous chargerons le classificateur déjà pré-entraîné. Le classificateur utilisé dans ce tutoriel est accessible en suivant le lien et en saisissant le classificateur que vous souhaitez utiliser dans votre projet.

Nous utiliserons le haarcascade_fullbody.xml classificateur.

À des fins de test, et pour faciliter l'inclusion de captures d'écran appropriées, j'ai utilisé le classificateur haarcascade_frontalface_default.xml classifieur dans mon exemplemais le haarcascade_fullbody.xml est le plus approprié pour le cas d'utilisation des caméras de sécurité.

classifier = cv2.CascadeClassifier('haarcascade/haarcascade_fullbody.xml')

La majeure partie de la détection se fait dans le morceau de code suivant :

while (True):
    # read frame-by-frame
    ret, frame = video_captured.read()

    # set the frame to gray as we do not need color, save up the resources
    gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    # pass the frame to the classifier
    persons_detected = classifier.detectMultiScale(gray_frame, 1.3, 5)

    # check if people were detected on the frame
try:
        human_count = persons_detected.shape[0]
else:
        human_count = 0
    
    # extract boxes so we can visualize things better
    # for actual deployment with hardware, not needed
    for (x, y, w, h) in persons_detected:
        cv2.rectangle(frame, (x,y), (x+w, y+h), (255, 0, 0), 2)    
    cv2.imshow('Video footage', frame)

    if (cv2.waitKey(1) & 0xFF == ord('q')):
        break

Nous lisons chaque image à partir du flux vidéo capturé. Il est également judicieux de les convertir en gris pour économiser les ressources. Une fois cette opération effectuée, nous transmettons l'image au classificateur pour voir si une personne a été détectée. Si c'est le cas, un rectangle est dessiné sur l'image autour de la personne détectée.

Vous trouverez ci-dessous un exemple de détection de mon visage :

Example below of my face being detectedExample below of my face being detected

Si vous chargez un classificateur différent, tel que upperbody.xml ou fullbody.xml, vous pourrez utiliser le même code pour la détection.

Veuillez noter que le classificateur de corps entier ne reconnaît la personne sur le cadre que si tout le corps est dans le cadre. Le visage et/ou la partie supérieure du corps ne suffiraient pas. Il en va de même pour le classificateur de la partie supérieure du corps : la seule présence du visage dans le cadre n'aboutirait pas à une détection réussie.

Cela provient d'une limitation des classificateurs fournis par OpenCV. Vous pouvez toujours essayer d'entraîner vos propres classificateurs ; cela peut prendre du temps et des ressources supplémentaires, mais c'est un bon moyen de développer ce projet si vous souhaitez en savoir plus sur cet aspect des choses.

Ajoutons maintenant les capacités de l'API SMS de Vonage à notre application pour que l'utilisateur puisse être averti si un étranger est détecté sur son image vidéo.

Note: Il est important d'ajouter un délai (surtout lors des tests) afin que l'utilisateur ne reçoive pas un grand nombre de SMS pour un seul événement de détection.

Dans notre exemple, nous utiliserons une méthode time.sleep(number of seconds) mais n'hésitez pas à développer votre propre méthode plus sophistiquée si vous en avez une.

Ajoutez le code suivant après le bloc try/else dans le code :

if (human_count > 0):
        client_nexmo.send_message({
            'from': ‘your_outbound_phone_number’,
                'to': ‘your_inbound_phone_number’,
                'text': 'There has been ' + str(human_count) + ' human(s) detected!',
        })

Le SMS ne sera envoyé que si au moins un être humain est détecté dans le cadre. Pour éviter d'envoyer trop de messages, nous mettrons le fil d'Ariane en veille pendant environ cinq secondes et rechercherons ensuite la personne dans le cadre.

Voilà, c'est fait ! En seulement 50 lignes de code, vous êtes prêt à détecter les personnes qui espionnent votre propriété et à recevoir une notification pratique lorsque cela se produit, en utilisant l'API SMS de Vonage.

Le code source de ce billet se trouve sur le lien suivant lien GitHub suivant. J'ai également inclus les classificateurs Haar Cascade utilisés dans ce projet afin que vous puissiez démarrer rapidement.

Améliorations potentielles

Bien entendu, il est possible de faire davantage pour rendre ce projet plus sophistiqué et plus efficace.

Premièrement, la méthode time.sleep() signifie qu'il y a au moins cinq secondes d'écart entre l'analyse des images, ce qui n'est pas une situation idéale et pourrait être amélioré. Il serait également judicieux de recadrer l'image de la trame vidéo que vous recevez de la caméra pour ne conserver qu'une zone de détection spécifique afin d'améliorer l'efficacité de la détection - moins de pixels à vérifier signifie des détections plus rapides.

Références

https://docs.opencv.org/master/db/d28/tutorial_cascade_classifier.html https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_gui/py_video_display/py_video_display.html https://github.com/opencv/opencv/tree/master/data/haarcascades

Partager:

https://a.storyblok.com/f/270183/364x364/50552ba95c/misha-behei.png
Misha BeheiIngénieur solutions clients

Misha est Ingénieur des solutions clients chez Vonage, où il se concentre sur le développement de l'API Video. Après avoir troqué l'effervescence de San Francisco pour le charme de Milwaukee, dans le Wisconsin, il passe désormais son temps libre à découvrir les joyaux cachés du Midwest.