5 Acquisition et traitement vidéo avec OpenCV - Quentin-LAURENT-git/Projet-ENSISA-CPB1 GitHub Wiki
A- Capture du flux vidéo :
Pour pouvoir capturer un flux video, on utilise la librairie OpenCV:
import cv2 #On importe OpenCV(cv2)
cap= cv2.VideoCapture(2) #On crée une variable cap qui récupère le flux video.
while True: #On initie une boucle qui permet d'afficher chaque frame du flux vidéo.
ret,frame=cap.read()
''' On crée une variable ret (booléen) qui renvoie True si cap enregistre un flux vidéo
et une variable frame (numpy.ndarray) qui stocke l'information du flux vidéo. '''
if not ret: break #On arrête la boucle si la variable ret vaut false.
cv2.imshow('1',frame) # On affiche l'image contenue dans frame dans une nouvelle fenêtre nommée "1"
if cv2.waitKey(1) & 0xFF == ord('q'): break # On arrête la boucle si la touche "q" est pressée
cap.release() # la variable cap abandonne le contrôle de la camera pour ne pas bloquer les autres programmes
cv2.destroyAllWindows() # On ferme toutes les fenêtres ouvertes par le programme
B- Traitement de l'image :
Image binaire :
Une image binaire est une image où les pixels ont soit la valeur 0 soit 255 selon différents critères.
Afin de pouvoir extraire les contours de l'objet que l'on souhaite mesurer, nous devons tout d'abord passer l'image en binaire. Pour cela, on passe dans un premier temps l'image en niveau de gris gâce à la fonction suivante :
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
Pour passer l'image en binaire, deux fonctions existent la fonction cv2.Canny() et la fonction cv2.threshold().
- La fonction cv2.threshold renvoie une image binaire selon un seuil fixé :
_,binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY_INV)
Cette fonction prend en paramètres une image en niveau de gris, les limites du seuil utilisé et la fonction cv2.THRESH_BINARY_INV qui indique ce sont les zones sombres de l'image qui prennent la valeur 255.
- La fonction cv2.Canny détecte les contours en utilisant les variations d’intensité et deux seuils pour filtrer les bords :
binary = cv2.Canny(gray, 100, 200)
Dans notre cas, on va privilégier la fonction cv2.Canny qui permet de récupérer les bords de manière plus précise y compris lorsque la coleur de l'objet se rapproche de la couleur de l'arrière plan.
Détection des contours :
Pour pouvoir avoir les contours d'un objet, on utilise la fonction cv2.findContours():
contours, _ = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
Cette fonction prend en paramètres une image binaire, ainsi que les fonctions cv2.RETR_EXTERNAL qui indique que la fonction ne renvoie que les contours externes de l'objet et CV2.CHAIN_APPROX_NONE qui indique que la fonction ne réduit pas le nombre de points utilisés pour calculer les contours. On évite les appoximations afin d'avoir des mesures du périmètre et de la surface occupée par l'objet le plus précis possible.
Affichage des contours :
Afin d'aficher les contours de notre objet sur notre flux vidéo inital en couleur, nous devons utiliser la fonction suivante :
cv2.drawContours(frame,contours,-1,(0,255,0),2)
Cette fonction prend en paramètres l'image sur laquelle les contours seront dessinés (frame), le tableau contenant tous les contours (contours) l'indice du contour que l'on veut dessiner (ici on choisit -1 qui dessine tous les contours du tableau), la couleur du contour (triplet donnant la valeur BVR de la couleur), ainsi que l'épaisseur du contour.
Ainsi, lorsque l'on affiche l'image contenue dans frame avec cv.imshow("1",frame), les contours s'affichent par dessus l'image originale.