Outils pour utilisateurs

Outils du site


diy:projets:motiondetection

Motion Detection

La détection de mouvement est utilisé en général dans la vidéo surveillance, elle sert à détecter les mouvements et capturer les événements. La détection de mouvement est généralement un algorithme de surveillance qui, lorsqu'il détecte des mouvements, signale à la caméra de surveillance de commencer à capturer l'événement. Aussi appelé détection d'activité. Un système de surveillance avancé de détection de mouvement peut analyser le type de mouvement pour voir s'il justifie une alarme.

Le programme présenté ici est bien plus basique. Ce dernier capture la vidéo et encadre les objets en mouvement.

Note: Ce code a été lancé sous python 2.7.6 avec openCV 2.4

Programme

Ce programme va permettre de capturer une scène à l'aide d'une caméra et de détecter chaque objets en mouvement dans celle ci, ainsi que la couleur dominante dans ces objets, et de les encadrer.

L'intégralité du code se trouve ici

On a donc le début de code suivant:

capture = cv2.VideoCapture(0)
prevFrame = None

Dans un premier temps, on capture la vidéo du device. Puis on crée une variable prevFrame qu'on initialise à None, celle ci va nous servir plus tard a faire la différence entre l'image actuelle et l'image précédente, pour voir si il y a eu du mouvement.

Nous arrivons ensuite dans l'essentielle du code, la boucle While, ici nous lisons chaque image une par une, si l'image n'est pas lu correctement dans le buffer, alors on quitte la boucle. Cela nous donne :

while True:
    (grabbed,frame) = capture.read()
    if not grabbed:
        break

Flou Gaussien

On récupère l'image en cour qu'on transforme en niveau de gris puis on lui applique un flou gaussien pour atténuer le bruit, sans ce flou on repérerait par la suite tout les bruits comme étant du mouvement. Appliquer un flou gaussien est donc indispensable pour la suite du programme.

Cela ce fait grâce au code suivant et on obtient l'image ci dessous:

gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray,(25,25), 0)

Flou Gaussien Enfin, si cette image est la première, alors la variable prevFrame prend la valeur de cette image:

if prevFrame is None:
        prevFrame = gray

Seuillage

Après avoir obtenu l'image avec le flou gaussien, on fait la différence absolue entre l'image en cours et l'image précédente, cela nous permets de voir les pixels uniquement en mouvement. Ensuite on fait un seuillage binaire sur cette nouvelle image et tout les pixels qui on un certain niveau de gris sont placés à 255. Ici on choisi 7 pour pouvoir repérer même les petits mouvements. Puis on dilate cette image pour avoir bien tout l'objet si possible en mouvement (des fois c'est un échec…); et à l'aide du code suivant on obtient l'image ci dessous:

frameDelta = cv2.absdiff(prevFrame,gray)
thresh = cv2.threshold(frameDelta, 7, 255, cv2.THRESH_BINARY)[1]
kernel = np.ones((11,11),np.uint8)
thresh = cv2.dilate(thresh, kernel, iterations=2)

Contours et Masque

Une fois que tout cela est fait, on cherche les contours des objets de l'image dilaté et on crée un masque qui va nous servir à encadrer l'objet de la couleur de celui ci:

(img,contr,hrchy) = cv2.findContours(thresh.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
mask = np.zeros(frame.shape[:2],np.uint8)

Pour chaque contours trouvés:

-Si c'est un contours trop petit (valeur fixé), on l'ignore.

-Sinon, on crée on rectangle à partir de ce contour, et un masque de la taille du rectangle qui va nous permettre d'obtenir la couleur de l'objet. Pour avoir la couleur de l'objet, on récupère la couleur du pixel du milieu du rectangle, on suppose qu'on est dans le cas ou l'objet a une couleur uniforme.

Le rectangle prend ensuite la couleur de l'objet et les nuances de bleu,vert,rouge sont affichés sur le coté du rectangle. Tout cela se fait avec le code suivant:

    for c in contr:
        if cv2.contourArea(c) < 1500:
			continue
 
        (x,y,w,h) = cv2.boundingRect(c) 
        mask[y:y+h, x:x+w] = 255
 
        (bl,gr,re) = frame[y+(h/2),x+(w/2)]
        bl = int(bl) 
        gr = int(gr)
        re = int(re)
        couleur ='B:'+ str(bl) + 'G:' + str(gr) + 'R:' + str(re)
 
        font = cv2.FONT_HERSHEY_SIMPLEX
        cv2.putText(frame,couleur,(x+w,y), font, 1, (255,255,255), 2, cv2.LINE_AA)
        cv2.rectangle(frame,(x,y),(x+w,y+h),(bl,gr,re),3)
 
    masked_img = cv2.bitwise_and(frame,frame,mask=mask)    
 
    cv2.imshow('contour',frame)

Resultat final:

diy/projets/motiondetection.txt · Dernière modification : 2018/05/28 08:44 de ecausse