Outils pour utilisateurs

Outils du site


diy:projets:piegephoto

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)
diy/projets/piegephoto.txt · Dernière modification : 2018/05/28 08:55 de ecausse