Table des matières
Piège Photographique
Le piège photographique consiste à prendre des photos uniquement lorsqu'on capte un mouvement.
l'intégralité du code se trouve ici
Pour ce programme, non seulement il nous faudra importer les librairie cv2 et numpy mais nous avons aussi besoin de la librairie time et Thread ainsi que Event, ces trois dernières librairie seront utile dans le thread pour prendre les photos lors de mouvement dans la capture de vidéo.
import cv2 import time import numpy as np from threading import Thread, Event
Capture du mouvement
Le début du programme ce fait exactement comme la détection de mouvement.
Avant la boucle while, on crée un thread myThread pour la fonction takePicture() qui va nous servir par la suite à prendre la photo. Dans le début de la boucle while on exécute un flou gaussien et un seuillage (comme vu dans Motion Detection):
capture = cv2.VideoCapture(0) prevFrame = None myThread = takePicture() while True: (grabbed,frame) = capture.read() if not grabbed: break gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY) gray = cv2.GaussianBlur(gray,(25,25), 0) if prevFrame is None: prevFrame = gray 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)
Puis lors des recherches de contours de l'image dilaté, on crée une variable area, qu'on initialise à 0. Cela va nous servir par la suite à voir s'il y a un contour dans l'image, et donc du mouvement.
Lors du parcours des contours: tout les petits objets sont ignorés, et on enregistre l'aire du contour pour la suite.
Enfin, si il y a une aire dans l'image, et donc un mouvement, et que le thread n'est pas déjà en train de prendre une photo, alors on peut en relancer un autre pour prendre une photo.
(img,contr,hrchy) = cv2.findContours(thresh.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE) area = 0 for c in contr: if cv2.contourArea(c) < 1500: continue area = cv2.contourArea(c) if area != 0 and not(myThread.is_alive()): myThread = takePicture() myThread.start()
Prise de la photo
On crée un thread pour la prise de la photo alors que le programme principale est encore en train de s’exécuter en parallèle
Le thread takePicture() va écrire l'image en cours dans un format spécifique (ici .png) puis on lance un sleep(), cela permet, si il y a du mouvement en continue de prendre uniquement des photos toute les n secondes (ici on à choisi toute les 1 seconde).
De plus, on crée une variable globale qui s’incrémente à chaque fois que l'on prend une nouvelle photo, Cela permet de ne pas écraser les anciennes photos prise lors de la capture vidéo.
img_counter = 0 class takePicture(Thread): def __init__(self): Thread.__init__(self) self._stop_event = Event() def run(self): global img_counter imgName = ("frame_{}.png".format(img_counter)) cv2.imwrite(imgName,frame) #print("{} ecrit".format(imgName)) img_counter += 1 time.sleep(1)