Détection de mouvement OpenCV

Salman Mehmood 10 octobre 2023
Détection de mouvement OpenCV

Dans cet article, nous apprendrons comment créer un projet de détection de mouvement à l’aide d’OpenCV et de Python.

Créer un projet de détection de mouvement à l’aide d’OpenCV et de Python

Tout d’abord, parlons de l’exigence de ce projet. La première exigence sera évidemment nécessaire pour installer Python, et nous avons également besoin d’un package externe à installer qui s’appelle opencv.

Nous devons ouvrir l’invite de commande et exécuter cette commande pour installer ce package sur votre PC. Passons à notre éditeur et commençons à écrire notre code.

La première chose que nous importerons est nos bibliothèques requises, cv2 et time, et la prochaine chose est que nous prendrons les données de notre webcam en utilisant la méthode VideoCapture() d’OpenCV.

Créons un objet nommé Video, et nous devons passer 0 au VideoCapture() car nous utilisons le canal 0 pour la webcam.

import cv2
import time

Video = cv2.VideoCapture(0)
First_Frame = None

Maintenant on va créer une boucle while True ou une boucle infinie car on va extraire une vidéo, et une vidéo c’est le déplacement continu sur un diaporama d’images.

Nous allons maintenant définir plusieurs instructions dans une boucle while, et dans la première ligne, nous allons créer deux variables, Check et frame, et lire les données extraites par la méthode VideoCapture(). Dans la prochaine instruction, nous convertirons cette image extraite en niveaux de gris.

Mais pourquoi convertissons-nous cela en niveaux de gris ? Nous faisons cela parce que nous voulons augmenter la précision de la détection des caractéristiques.

Nous utilisons la méthode cvtColor() pour passer en niveaux de gris et avons deux paramètres. Le premier est le frame ou une image que nous voulons convertir en niveaux de gris, puis le suivant est COLOR_BGR2GRAY, qui convertira une image en couleur grise.

Maintenant, nous allons rendre une image floue ou lissée, c’est pourquoi la détection d’objet ou le mouvement d’un objet sera beaucoup plus facile. Nous utilisons la méthode GaussianBlur() pour appliquer le lissage et lui transmettre une image en niveaux de gris, la taille du noyau et le sigma.

while True:
    Check, frame = Video.read()
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    gray = cv2.GaussianBlur(gray, (21, 21), 0)

Nous allons créer une instruction if qui vérifiera si le cadre arrive ou non, et nous le faisons parce que nous voulons que le First_Frame soit notre cadre de référence.

Voyons ce que la physique dit du mouvement ? Le mouvement est identifié à partir d’un point de référence, et nous expliquons cela avec un exemple.

Disons que vous êtes assis dans un train, et pour vous, les arbres bougent, mais ils ne bougent pas ; ils sont immobiles, mais vous vous éloignez de votre point de référence. Dans ce cas, les arbres sont des points de référence, mais le cadre est une référence dans notre cas.

Nous fixons le First_Frame comme cadre de référence ; si un changement se produit à partir du cadre de référence, alors nous pouvons dire que le mouvement est là.

Maintenant, nous allons définir une déclaration comme si la variable First_Frame est None qui est true dans le premier cas, puis nous rendrons la variable First_Frame égale à l’image en niveaux de gris qui est la variable gray.

if First_Frame is None:
    First_Frame = gray
    continue

Nous allons utiliser la méthode absdiff() pour trouver la différence entre les images. Créons une variable de cadre delta et passons les deux paramètres à la méthode absdiff() pour comparaison.

Nous devons définir un seuil ou une limite à laquelle nous voulons que le mouvement soit détecté car nous ne voulons pas que les bruits soient détectés comme un mouvement.

Pour ce faire, nous utilisons la méthode threshold(), et elle a quelques paramètres, le premier est le delta_frame, le second est l’intensité, le troisième est la nuance de couleur qui est blanche dans ce cas, puis le le suivant est THRESH_BINARY puisqu’il s’agit d’un tuple, nous devons donc sélectionner le premier élément.

Nous devons également appliquer une autre couche de lissage dans la prochaine instruction. Pour ce faire, nous devons utiliser une autre fonction de lissage appelée dilate(), et elle accepte trois paramètres, le premier est le seuil, le second est None, et le troisième paramètre est les itérations.

Le paramètre itérations définit la précision de votre lissage ; votre programme capturera également les bruits si vous augmentez la valeur de ce paramètre.

Cette fois, nous allons créer les contours, alors que sont les contours ? Les contours sont les points où le mouvement se produit.

Si le cadre est immobile et que la main est en mouvement, alors la partie de la main est le contour.

La méthode findContours() aide à trouver les contours, et elle accepte trois paramètres, le premier est le cadre, et nous utilisons la méthode copy() pour créer la copie du tableau de cadres.

delta_frame = cv2.absdiff(First_Frame, gray)
Threshold_frame = cv2.threshold(delta_frame, 50, 255, cv2.THRESH_BINARY)[1]
Threshold_frame = cv2.dilate(Threshold_frame, None, iterations=2)
(cntr, _) = cv2.findContours(
    Threshold_frame.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE
)

Maintenant, nous allons obtenir des contours à travers l’itération et définir la zone approximative comme étant un mouvement. Si nous ne définissons pas la zone, nous obtiendrons une détection de mouvement très bruyante.

Tout d’abord, nous vérifierons que si la zone de contour est inférieure à mille, alors nous ne considérons pas cela comme une zone de mouvement, et nous continuerons l’itération, et si elle est supérieure à mille, alors nous dessinerons un Triangle.

for contour in cntr:
    if cv2.contourArea(contour) < 1000:
        continue

La méthode findContours() donne quatre valeurs (x, y, hauteur, largeur), et nous allons extraire ces points à l’aide de la méthode boundingRect(), qui va lier l’aire du rectangle. Nous allons maintenant créer le rectangle à l’aide de la méthode rectangle().

Le premier paramètre est le frame ou l’image sur laquelle on veut dessiner le rectangle. Le suivant est les points de coordonnées (x,y), le suivant est la hauteur et la largeur, le suivant est la couleur du cadre, puis le dernier paramètre est la taille du stylo sélectionné pour dessiner le rectangle.

(x, y, w, h) = cv2.boundingRect(contour)
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 3)

Code source complet :

import cv2
import time

Video = cv2.VideoCapture(0)
First_Frame = None

while True:
    Check, frame = Video.read()
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    gray = cv2.GaussianBlur(gray, (21, 21), 0)
    if First_Frame is None:
        First_Frame = gray
        continue
    delta_frame = cv2.absdiff(First_Frame, gray)
    Threshold_frame = cv2.threshold(delta_frame, 50, 255, cv2.THRESH_BINARY)[1]
    Threshold_frame = cv2.dilate(Threshold_frame, None, iterations=2)
    (cntr, _) = cv2.findContours(
        Threshold_frame.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE
    )
    for contour in cntr:
        if cv2.contourArea(contour) < 1000:
            continue
        (x, y, w, h) = cv2.boundingRect(contour)
        cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 3)
    cv2.imshow("Frame", frame)
    Key = cv2.waitKey(1)
    if Key == ord("q"):
        break

Video.release()
cv2.destroyAllWindows()

Nous pouvons maintenant voir que la détection de mouvement se produit lorsque la main bouge.

Créer un projet de détection de mouvement à l&rsquo;aide d&rsquo;OpenCV et de Python

Salman Mehmood avatar Salman Mehmood avatar

Hello! I am Salman Bin Mehmood(Baum), a software developer and I help organizations, address complex problems. My expertise lies within back-end, data science and machine learning. I am a lifelong learner, currently working on metaverse, and enrolled in a course building an AI application with python. I love solving problems and developing bug-free software for people. I write content related to python and hot Technologies.

LinkedIn