la detection de mouvement est une option interressante par exemple dans le cas de video surveillance , ci dessous un programme basique qui fait le boulot.
NOTA: derriere les caractères # des ligne en bleu qui peuvent remplacer la ligne juste avant pour des tests au choix soit sur un fichier video soit sur le livestream d’une camera. et également soit en dessinant des rectangles autour des objets en mouvement soit en dessinant le contour de l’objet.
import cv2
import numpy as np
cap = cv2.VideoCapture(0)
#cap = cv2.VideoCapture('OPENCVmotiondetection.avi')
ret, frame1 = cap.read()
ret, frame2 = cap.read()
while cap.isOpened():
diff = cv2.absdiff(frame1, frame2)
gray = cv2.cvtColor(diff, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (5,5), 0)
_, thresh = cv2.threshold(blur, 20, 255, cv2.THRESH_BINARY)
dilated = cv2.dilate(thresh, None, iterations=3)
_, contours, _ = cv2.findContours(dilated, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
for contour in contours:
(x, y, w, h) = cv2.boundingRect(contour)
if cv2.contourArea(contour) < 500:
continue
cv2.rectangle(frame1, (x, y), (x+w, y+h), (0, 255, 0), 2)
#cv2.drawContours(frame1, contours, -1, (0, 255, 0), 2)
cv2.imshow("feed", frame1)
frame1 = frame2
ret, frame2 = cap.read()
if cv2.waitKey(40) == 27:
break
cv2.destroyAllWindows()
cap.release()
une copie d’ecran du resultat sur une video AVI et avec dessin de rectangles englobants sur les objets en mouvement:
examinons maintenant , une variante du programme précédent utilisant des fonction elaborées de OpenCV ainsi que le principe des masques , qui permet de n’appliquer la detection que sur la partie droite de la video
NOTA: les ligne en bleu sont des variantes du programme par rapport a la ligne en dessous ( il faut remplacer l’une par l’autre).
import cv2
import numpy as np
#cap = cv2.VideoCapture(1)
cap = cv2.VideoCapture('OPENCVmotiondetection.avi')
object_detector = cv2.createBackgroundSubtractorMOG2(history=100, varThreshold=10)
while True:
ret, frame = cap.read()
roi = frame[0:480 , 320:640] # def Region Off Interest
mask = object_detector.apply(roi) # definission d'un masque avec la ROI
_, mask = cv2.threshold(mask, 254, 255, 0) # ne garde que les pixel blancs
_, contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
for cnt in contours:
area = cv2.contourArea(cnt)
if area > 100 :
#cv2.drawContours(roi, [cnt], -1, (0, 255, 0), 2) #dessin contour
x, y, w, h =cv2.boundingRect(cnt) # definition rectangle englobant
cv2.rectangle(roi, (x, y), (x+w, y+h), (0, 255, 0), 3) #dessin rectangle
cv2.imshow("Frame", frame)
cv2.imshow("ROI", roi)
cv2.imshow("Mask", mask)
if cv2.waitKey(40) == 27:
break
cv2.destroyAllWindows()
cap.release()
le resultat avec l’affichage , de la video de base, du ROI et du masque N&B