====== 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 [[https://github.com/RenoRincevent/BePython/blob/master/testMove.py|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) {{ :diy:projets:blur.png?nolink&400 |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) {{ :diy:projets:thresh.png?nolink&400 |}} ==== 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:res.png?nolink&400 |}}