- Détection d'objets à l'aide de SIFT
- Détection d'objets à l'aide d'ORB
- Histogramme des dégradés orientés (HOG)
- Histogramme des dégradés orientés (HOG), étape par étape:
- Classificateurs en cascade HAAR
- Détection du visage et des yeux
- Détection des visages et des yeux en direct
- Réglage des classificateurs en cascade
- Détection de voitures et de piétons en vidéos
Nous avons commencé par installer python OpenCV sur Windows et jusqu'à présent effectué un traitement d'image de base, une segmentation d'image et une détection d'objets à l'aide de Python, qui sont traités dans les didacticiels ci-dessous:
- Premiers pas avec Python OpenCV: installation et traitement d'image de base
- Manipulations d'images dans Python OpenCV (Partie 1)
- Manipulations d'images dans OpenCV (partie 2)
- Segmentation d'image à l'aide d'OpenCV - Extraction de zones spécifiques d'une image
Nous avons également découvert diverses méthodes et algorithmes pour la détection d'objets où certains points clés ont été identifiés pour chaque objet à l'aide de différents algorithmes. Dans ce tutoriel, nous allons utiliser ces algorithmes pour détecter des objets réels, ici nous utiliserions SIFT et ORB pour la détection.
Détection d'objets à l'aide de SIFT
Ici, la détection d'objet se fera en utilisant un flux de webcam en direct, donc s'il reconnaît l'objet, il mentionnera l'objet trouvé. Dans le code, la partie principale est jouée par la fonction appelée détecteur SIFT, la majeure partie du traitement est effectuée par cette fonction.
Et dans l'autre moitié du code, nous commençons par ouvrir le flux de la webcam, puis nous chargeons le modèle d'image, c'est-à-dire l'image de référence, c'est-à-dire que le programme regarde réellement le flux de la webcam.
Ensuite, nous capturons en continu les images du flux de webcam à l'aide d'une boucle while infinie, puis capturons la hauteur et la largeur correspondantes du cadre de la webcam, puis définissons les paramètres de la zone d'intérêt (ROI) dans laquelle notre objet peut s'intégrer en prenant la hauteur et la largeur correspondantes du cadre de la webcam. Et puis nous dessinons le rectangle à partir des paramètres ROI que nous avions définis ci-dessus. Ensuite, recadrez enfin le rectangle et insérez-le dans la partie détecteur SWIFT du code.
Maintenant, le détecteur SIFT a essentiellement deux entrées, l'une est l'image recadrée et l'autre est le modèle d'image que nous avons précédemment défini, puis il nous donne des correspondances, donc les correspondances sont essentiellement le nombre d'objets ou de points clés similaires dans l'image recadrée et l'image cible. Ensuite, nous définissons une valeur seuil pour les correspondances, si la valeur des correspondances est supérieure au seuil, nous mettons l'image trouvée sur notre écran avec la couleur verte du rectangle ROI.
Revenons maintenant à la partie principale du code, la fonction qui s'appelle détecteur SIFT, elle prend l'entrée comme deux images l'une est l'image où elle cherche l'objet et l'autre est l'objet que nous essayons de faire correspondre à (modèle d'image). Ensuite, mettez à l'échelle la première image en gris et définissez le modèle d'image comme deuxième image. Ensuite, nous créons un objet détecteur SIFT et exécutons la fonction de détection et de calcul OpenCV SIFT, afin de détecter les points clés et de calculer les descripteurs, les descripteurs sont essentiellement les vecteurs qui stockent les informations sur les points clés, et c'est vraiment important lorsque nous faisons la correspondance entre les descripteurs des images.
Et puis définissez le matcher basé sur FLANN, nous n'allons pas dans la théorie mathématique de la correspondance derrière lui, mais vous pouvez facilement Google à ce sujet. Tout d'abord, définissez l'index kdtree à zéro, puis nous définissons les paramètres d'index et de recherche au format dictionnaire, nous définissons simplement l'algorithme que nous allons utiliser qui est KDTREE, et le nombre d'arbres que nous allons utiliser, plus il y a d'arbre nous utilisons le plus compliqué et le plus lent. Et dans le paramètre de recherche, définissez le nombre de vérifications, qui est essentiellement le nombre de correspondances qu'il va compléter.
Et puis créez notre objet matcher basé sur FLANN en chargeant le paramètre que nous avons précédemment défini, qui sont les paramètres d'index et les paramètres de recherche, et en fonction de cela, créez notre matcher basé sur FLANN, qui est un matcher KNN où KNN est K-plus proche voisins, en gros c'est un moyen où nous cherchons les correspondants et les descripteurs les plus proches et nous faisons la correspondance avec la constante d'initialisation k. Maintenant, ce matcher basé sur FLANN renvoie le nombre de correspondances que nous obtenons.
L'appariement basé sur FLANN n'est qu'une approximation, afin d'augmenter la précision du matcher basé sur FLANN, nous effectuons un test de ratio de Lowe et ce qu'il fait, c'est qu'il recherche les correspondances à partir du matcher basé sur knn flann et définit certains paramètres matriciels qui sont ici la distance, pour laquelle la distance est une fonction numpy, et une fois qu'elle répond aux critères, ajoutez les correspondances aux bonnes correspondances et renvoie les bonnes correspondances trouvées, de sorte que le flux vidéo en direct indique le nombre de correspondances trouvées dans le coin de l'écran.
Regardons maintenant le code pour la description ci-dessus:
import cv2 import numpy as np def sift_detector (new_image, image_template): # Fonction qui compare l'image d'entrée au modèle # Elle renvoie ensuite le nombre de correspondances SIFT entre elles image1 = cv2.cvtColor (nouvelle_image, cv2.COLOR_BGR2GRAY) image2 = image_template # Create Objet détecteur SIFT #sift = cv2.SIFT () sift = cv2.xfeatures2d.SIFT_create () # Obtenez les points-clés et les descripteurs à l'aide de points-clés SIFT_1, descripteurs_1 = sift.detectAndCompute (image1, Aucun) points-clés_2, descripteurs_2 = sift.detectAndCompute Aucun) # Définir les paramètres de notre Flann Matcher FLANN_INDEX_KDTREE = 0 index_params = dict (algorithme = FLANN_INDEX_KDTREE, arbres = 3) search_params = dict (checks = 100) # Créer l'objet Flann Matcher flann = cv2.FlannBasedMatcher (index_params, search_params) # Obtenir des correspondances en utilisant la méthode K-Nearest Neighbor # le résultat 'correspond' est le nombre de correspondances similaires trouvées dans les deux images correspond = flann.knnMatch (descriptors_1, descriptors_2, k = 2) # Stocker les bonnes correspondances en utilisant le test de rapport de Lowe good_matches = pour m, n dans les correspondances: si m.distance <0,7 * n.distance: good_matches.append (m) return len (good_matches) cap = cv2.VideoCapture (0) # Chargez notre modèle d'image, c'est notre image de référence image_template = cv2.imread ('phone.jpg', 0) while True: # Obtenez des images de webcam ret, frame = cap.read () # Obtenir la hauteur et la largeur de la hauteur du cadre de la webcam , width = frame.shape # Définir les dimensions de la boîte ROI top_left_x = int (width / 3) top_left_y = int ((height / 2) + (height / 4)) bottom_right_x = int ((width / 3) * 2) bottom_right_y = int ((height / 2) - (height / 4)) # Dessine une fenêtre rectangulaire pour notre région d'intérêt cv2.rectangle (frame, (top_left_x, top_left_y), (bottom_right_x, bottom_right_y), 255, 3) # fenêtre de recadrage de l' observation que nous avons définie ci - dessus rogné = cadre # orientation de trame flip horizontalement de trame = cv2.flip (structure 1) # Get nombre de SIFT correspond resultat = sift_detector (recadrée, image_template) # Afficher la chaîne d'état indiquant le no actuel. de correspondances cv2.putText (frame, str (matches), (450,450), cv2.FONT_HERSHEY_COMPLEX, 2, (0,255,0), 1) # Notre seuil pour indiquer la détection d'objet # Nous utilisons 10 puisque le détecteur SIFT renvoie peu de faux positifs seuil = 10 # Si les correspondances dépassent notre seuil, alors l'objet a été détecté si les correspondances> seuil: cv2.rectangle (frame, (top_left_x, top_left_y), (bottom_right_x, bottom_right_y), (0,255,0), 3) cv2.putText (frame, 'Object Found', (50,50), cv2.FONT_HERSHEY_COMPLEX, 2, (0,255,0), 2) cv2.imshow ('Object Detector using SIFT', frame) if cv2.waitKey (1) == 13: # 13 est la touche Entrée pause cap.release () cv2.destroyAllWindows ()
Détection d'objets à l'aide d'ORB
La détection d'objets à l'aide de SIFT est plutôt cool et précise, car elle génère un nombre beaucoup plus précis de correspondances basées sur les points clés, mais elle est brevetée et cela rend son utilisation difficile pour les applications commerciales, l'autre solution est l'algorithme ORB. pour la détection d'objets.
Similaire à la méthode de détection d'objet par SIFT dans laquelle nous avons divisé le programme en deux parties, la même chose sera suivie ici.
Tout d'abord, nous définissons la fonction ORB_detector qui prend deux entrées, l' une est l'image du flux en direct provenant de la webcam et l'autre est le modèle d'image sur la base duquel nous allons faire correspondre notre image. Ensuite, nous mettons l'image de notre webcam en niveaux de gris, puis initialisons notre détecteur ORB, et nous le définissons ici à 1000 points clés et à des paramètres de mise à l'échelle de 1,2. vous pouvez facilement jouer avec ces paramètres, puis détecter les points clés (kp) et les descripteurs (des) pour les images et le deuxième paramètre que nous définissons dans la fonction detectANDCompute est AUCUN, il demande l'utilisation du masque d'image ou non et nous le nions ici.
Ensuite, passez au détecteur précédemment que nous utilisions le matcher basé sur FLANN, mais ici nous utiliserons BFMatcher et à l'intérieur de BFMatcher nous définissons deux paramètres l'un est NORM_HAMMING et l'autre est le crossCheck dont la valeur est TRUE.
Ensuite, calculez les correspondances entre ces deux images en utilisant les descripteurs définis ci-dessus, qui dans l'ensemble retourne le nombre de correspondances puisque ces correspondances ne sont pas des approximations et qu'il n'est donc pas nécessaire de faire le test de rapport de Lowe, à la place nous trions les correspondances en fonction de la distance, moins la distance plus la correspondance est meilleure (ici la distance signifie la distance entre les points), et à la fin nous renvoyons le nombre de correspondances en utilisant la fonction de longueur.
Et dans la fonction principale, nous définissons le seuil sur une valeur beaucoup plus élevée, car le détecteur d'orbe génère beaucoup de bruit.
Regardons maintenant le code pour la détection basée sur ORB
import cv2 import numpy as np def ORB_detector (new_image, image_template): # Fonction qui compare l'image d'entrée au modèle # Elle renvoie ensuite le nombre de correspondances ORB entre elles image1 = cv2.cvtColor (nouvelle_image, cv2.COLOR_BGR2GRAY) # Créer un détecteur ORB avec 1000 points clés avec un facteur de pyramide de mise à l'échelle de 1,2 orb = cv2.ORB_create (1000, 1,2) # Détecter les points clés de l'image d'origine (kp1, des1) = orb.detectAndCompute (image1, Aucun) # Détecter les points clés de l'image pivotée (kp2, des2) = orb.detectAndCompute (image_template, None) # Create matcher # Notez que nous n'utilisons plus la correspondance basée sur Flann bf = cv2.BFMatcher (cv2.NORM_HAMMING, crossCheck = True) # Faire des correspondances = bf.match (des1, des2) # Trier les correspondances en fonction de la distance. La distance minimale # est la meilleure correspondance = triée (correspondances, clé = lambda val: val.distance) return len (correspondances) cap = cv2.VideoCapture (0) # Chargez notre modèle d'image, voici notre image de référence image_template = cv2.imread ('phone.jpg', 0) # image_template = cv2.imread ('images / kitkat.jpg', 0) while True: # Get webcam images ret, frame = cap.read () # Get hauteur et la largeur du cadre de la webcam hauteur, width = frame.shape # Définir les dimensions de la boîte ROI (notez que certaines de ces choses doivent être en dehors de la boucle) top_left_x = int (width / 3) top_left_y = int ((height / 2) + (height / 4)) bottom_right_x = int ((width / 3) * 2) bottom_right_y = int ((height / 2) - (height / 4)) # Dessine une fenêtre rectangulaire pour notre région d'intérêt cv2.rectangle (frame, (top_left_x, top_left_y), (bottom_right_x, bottom_right_y), 255, 3) # Recadrer la fenêtre d'observation définie ci-dessus cropped = frame # Retourner l'orientation du cadre horizontalement frame = cv2.flip (frame, 1) # Obtenir le nombre de correspondances ORB correspond à = ORB_detector (cropped, image_template) # Afficher la chaîne d'état indiquant le no actuel. de correspondances output_string = "Matches =" + str (matches) cv2.putText (frame, output_string, (50,450), cv2.FONT_HERSHEY_COMPLEX, 2, (250,0,150), 2) # Notre seuil pour indiquer la détection d'objet # Pour de nouvelles images ou des conditions d'éclaircissement, vous devrez peut-être expérimenter un peu # Remarque: Le détecteur ORB pour obtenir les 1000 meilleures correspondances, 350 est essentiellement un seuil de correspondance min 35% = 250 # Si les correspondances dépassent notre seuil alors l'objet a été détecté si correspond à> seuil: cv2.rectangle (frame, (top_left_x, top_left_y), (bottom_right_x, bottom_right_y), (0,255,0), 3) cv2.putText (frame, 'Object Found', (50, 50), cv2.FONT_HERSHEY_COMPLEX, 2, (0,255,0), 2) cv2.imshow ('Object Detector using ORB', frame) if cv2.waitKey (1) == 13: # 13 est la limite de rupture de clé d'entrée .release () cv2.destroyAllWindows ()
Histogramme des dégradés orientés (HOG)
Parlons maintenant d'un descripteur différent qui est l'histogramme des dégradés orientés (HOG).
Les HOG sont des descripteurs plutôt sympas et utiles et ils sont largement et avec succès utilisés pour la détection d'objets, comme on l'a vu précédemment, les descripteurs d'image comme SIFT et ORB où nous devons calculer des points clés et ensuite calculer des descripteurs à partir de ces points clés, les HOG font ce processus différemment. Il représente les objets sous la forme d'un seul vecteur de caractéristiques par opposition à un ensemble de vecteurs de caractéristiques où chacun représente un segment de l'image. Cela signifie que nous avons une seule fonction vectorielle pour l'image entière.
Il est calculé par un détecteur de fenêtre glissante sur une image, où un descripteur HOG est calculé pour chaque position. Et puis chaque position est combinée pour un seul vecteur de caractéristiques.
Comme SIFT, l'échelle de l'image est ajustée par pyramidage.
Auparavant, nous avons utilisé des matchers comme FLANN et BFMatcher, mais les HOG le font différemment à l'aide des classificateurs SVM (support vector machine), où chaque descripteur HOG calculé est transmis à un classificateur SVM pour déterminer si l'objet a été trouvé ou non.
Voici le lien vers un excellent article de Dalal & Triggs sur l'utilisation des HOG pour la détection humaine:
Histogramme des dégradés orientés (HOG), étape par étape:
Comprendre les HOG pourrait être assez complexe, mais ici nous allons seulement traiter de la théorie des HOG sans approfondir les mathématiques qui y sont liées.
Alors prenons cette image, elle est un peu pixélisée, et dans le coin supérieur se trouve une boîte de 8x8 pixels, donc dans cette boîte, nous calculons le vecteur de gradient ou les orientations des bords à chaque pixel. Cela signifie donc que dans cette boîte, nous calculons le vecteur de gradient d'image des pixels à l'intérieur de la boîte (ils sont une sorte de direction ou de flux de l'intensité de l'image elle-même), et cela génère 64 vecteurs de gradient (8 x 8) qui sont ensuite représentés sous forme d'histogramme. Imaginez donc un histogramme qui représente chaque vecteur de gradient. Donc, si tous les points ou intensités se trouvaient dans une direction, l'histogramme pour cette direction disons 45 degrés, l'histogramme aurait un pic à 45 degrés.
Donc ce que nous faisons maintenant, c'est que nous divisons chaque cellule en cases angulaires, où chaque case correspond à une direction de gradient (par exemple x, y). Dans le papier Dalal et Triggs, ils ont utilisé 9 bacs 0-180 ° (20 ° chaque bac). Cela réduit efficacement 64 vecteurs à seulement 9 valeurs. Donc, ce que nous avons fait est de réduire la taille mais de garder toutes les informations clés nécessaires.
La prochaine étape dans le calcul du porc est la normalisation, nous normalisons les gradients pour assurer l'invariance des changements d'éclairage, c'est-à-dire la luminosité et le contraste.
Dans cette image, les valeurs d'intensité sont indiquées dans le carré selon la direction respective et ont toutes une différence de 50 entre elles
∆ H = 50, ∆ v = 50; │∆│ = √50 2 +50 = 70,72, 70,72 / 100 = 0,707
Nous divisons les vecteurs par les magnitudes du gradient, nous obtenons 0,707 pour tous, c'est la normalisation.
De même, si nous changeons l'intensité ou le contraste, nous obtenons les valeurs ci-dessous.
∆ H = 50, ∆ v = 50; │∆│ = √50 2 +50 = 70,72, 70,72 / 100 = 0,707; ∆ H = 100, ∆ v = 100; │∆│ = √100 2 +100 = 141,42, 141,42 / 100 = 1,41
La normalisation n'a pas lieu au niveau de la cellule, au lieu de cela, elle a lieu au niveau d'un bloc, donc ici les blocs sont fondamentalement un groupe de 4 cellules, cela prend en compte les blocs voisins afin de normaliser tout en prenant en compte des segments plus grands de l'image.
Regardons maintenant le code
import numpy as np import cv2 import matplotlib.pyplot as plt # Charger l'image puis l'image en niveaux de gris = cv2.imread ('elephant.jpg') grey = cv2.cvtColor (image, cv2.COLOR_BGR2GRAY) # Afficher l'image d'origine cv2.imshow (' Image d'entrée ', image) cv2.waitKey (0) # définition des paramètres, taille de cellule et taille de bloc # hxw en pixels cell_size = (8, 8) # hxw dans les cellules block_size = (2, 2) # nombre de bacs d'orientation nbins = 9 # Utilisation du descripteur HOG d'OpenCV # winSize est la taille de l'image recadrée à un multiple de la taille de la cellule hog = cv2.HOGDescriptor (_winSize = (gray.shape // cell_size * cell_size, gray.shape // cell_size * cell_size), _blockSize = (block_size * cell_size, block_size * cell_size), _blockStride = (cell_size, cell_size), _cellSize = (cell_size, cell_size), _nbins = nbins) # Créer une forme de tableau numpy pour créer hog_features n_cells = (gray.shape // cell_size, gray.shape // cell_size) # Nous indexons d' abord les blocs par lignes. # hog_feats contient maintenant les amplitudes de gradient pour chaque direction, # pour chaque cellule de son groupe pour chaque groupe. L'indexation se fait par lignes puis par colonnes. hog_feats = hog.compute (gris).reshape (n_cells - block_size + 1, n_cells - block_size + 1, block_size, block_size, nbins).transpose ((1, 0, 2, 3, 4)) # Créez notre tableau de dégradés avec nbin dimensions pour stocker les orientations de dégradé gradients = np.zeros ((n_cells, n_cells, nbins)) # Créez un tableau de dimensions cell_count = np.full ((n_cells, n_cells, 1), 0, dtype = int) # Normalisation de bloc pour off_y in range (block_size): pour off_x in range (block_size): gradients - block_size + off_y + 1, off_x: n_cells - block_size + off_x + 1] + = \ hog_feats cell_count - block_size + off_y + 1, off_x: n_cells - block_size + off_x + 1] + = 1 # Gradients moyens gradients / = cell_count # Tracer les HOGs en utilisant Matplotlib # angle est de 360 / nbins * direction color_bins = 5 plt.pcolor (dégradés) plt.gca (). invert_yaxis () plt.gca (). set_aspect ('égal', réglable = 'boîte') plt.colorbar () plt.show () cv2.destroyAllWindows ()
L'image montre comment l'image d'entrée est représentée sous forme de représentation HOG.
Classificateurs en cascade HAAR
Comme indiqué précédemment, nous pouvons extraire des caractéristiques d'une image et utiliser ces caractéristiques pour classer ou détecter des objets.
Que sont les classificateurs HAAR Cascade?
Une méthode de détection d'objets qui saisit les caractéristiques de Haar dans une série de classificateurs (en cascade) pour identifier les objets dans une image. Ils sont formés pour identifier un type d'objet, cependant, nous pouvons en utiliser plusieurs en parallèle, par exemple en détectant les yeux et les visages ensemble.
Les classificateurs HAAR expliqués:
Les classificateurs HAAR sont formés en utilisant de nombreuses images positives (c'est-à-dire des images avec l'objet présent) et
des images négatives (c'est-à-dire des images sans l'objet présent).
Une fois que nous avons ces images, nous extrayons ensuite des entités à l'aide de fenêtres coulissantes de blocs rectangulaires. Ces caractéristiques (caractéristiques HAAR) ont une valeur unique et sont calculées en soustrayant la somme des intensités de pixels sous les rectangles blancs des rectangles noirs.
Cependant, c'est un nombre ridicule de calculs, même pour une fenêtre de base de 24 x 24 pixels (180 000 fonctionnalités générées).
Les chercheurs ont donc conçu une méthode appelée Images intégrales qui a calculé cela avec quatre références de tableau. Cependant, ils avaient encore 180 000 fonctionnalités et la majorité d'entre elles n'ajoutaient aucune valeur réelle.
Le boosting a ensuite été utilisé pour déterminer les fonctionnalités les plus informatives, avec l' AdaBoost de Freund & Schapire et il a trouvé les fonctionnalités les plus informatives dans l'image. Le boosting est le processus par lequel nous utilisons des classificateurs faibles pour construire des classificateurs forts, simplement en attribuant des pénalités pondérées plus lourdes aux classifications incorrectes. Réduire les 180000 fonctionnalités à 6000, ce qui est encore un peu des fonctionnalités.
Dans ces 6000 fonctionnalités, certaines seront plus informatives que d'autres. Donc, si nous avons utilisé les fonctionnalités les plus informatives pour vérifier d'abord si la région peut potentiellement avoir un visage (les faux positifs ne seront pas un gros problème). Cela élimine le besoin de calculer les 6000 caractéristiques à la fois. Ce concept est appelé la cascade de classificateurs - pour la détection de visage, la méthode Viola Jones a utilisé 38 étapes.
Détection du visage et des yeux
Donc, après avoir acquis des connaissances théoriques sur les cascades HAAR, nous allons enfin les mettre en œuvre, afin de clarifier les choses, nous allons briser les leçons par parties, d' abord nous détecterons la face frontale, puis nous nous déplacerons pour détecter la face frontale avec yeux et enfin nous ferions une détection en direct du visage et des yeux via la webcam.
Donc, pour cela, nous allons utiliser des classificateurs pré-entraînés qui ont été fournis par OpenCV sous forme de fichiers.xml, xml signifie langage de balisage extensible, ce langage est utilisé pour stocker une grande quantité de données, vous pouvez même créer une base de données dessus.
Vous pouvez avoir accès à ces classificateurs à ce lien .
Détection facial
Essayons pour la détection de visage frontal, vous pouvez avoir accès à la cascade de détecteur de visage frontal ici. Extrayez simplement le fichier zip pour obtenir le fichier xml.
import numpy as np import cv2 # Nous pointons la fonction CascadeClassifier d'OpenCV vers l'endroit où notre # classificateur (format de fichier XML) est stocké, n'oubliez pas de garder le code et le classificateur dans le même dossier face_cascade = cv2.CascadeClassifier ('haarcascade_frontalface_default.xml') # Load notre image puis la convertit en niveaux de gris image = cv2.imread ('Trump.jpg') gray = cv2.cvtColor (image, cv2.COLOR_BGR2GRAY) # Notre classificateur renvoie le retour sur investissement du visage détecté sous forme de tuple # Il stocke le haut à gauche coordonnée et les coordonnées en bas à droite # il renvoie la liste des listes, qui sont l'emplacement des différentes faces détectées. faces = face_cascade.detectMultiScale (gris, 1.3, 5) # Lorsqu'aucun visage n'est détecté, face_classifier retourne et vide le tuple si faces is (): print ("No faces found") # Nous parcourons notre tableau de faces et dessinons un rectangle # sur chaque face dans les faces pour (x, y, w, h) dans les faces: cv2.rectangle (image, (x, y), (x + w, y + h), (127,0,255), 2) cv2.imshow ('Face Detection', image) cv2.waitKey (0) cv2.destroyAllWindows ()
Maintenant, combinons la détection du visage et des yeux ensemble, vous pouvez avoir accès à la cascade de détecteur d'œil dans le même fichier zip.
import numpy as np import cv2 face_classifier = cv2.CascadeClassifier ('haarcascade_frontalface_default.xml') eye_classifier = cv2.CascadeClassifier ('haarcascade_eye.xml') img = cv2.imread ('Trump.jpg') gray = cv2.cgvt cv2.COLOR_BGR2GRAY) faces = face_classifier.detectMultiScale (gray, 1.3, 5) # Lorsqu'aucun visage n'est détecté, face_classifier retourne et vide tuple si faces est (): print ("No Face Found") for (x, y, w, h) dans les faces: cv2.rectangle (img, (x, y), (x + w, y + h), (127,0,255), 2) cv2.imshow ('img', img) roi_gray = gray roi_color = img eyes = eye_classifier.detectMultiScale (roi_gray) cv2.waitKey (0) for (ex, ey, ew, eh) dans les yeux: cv2.rectangle (roi_color, (ex, ey), (ex + ew, ey + eh), (255,255,0), 2) cv2.imshow ('img', img) cv2.waitKey (0) cv2.destroyAllWindows () cv2.waitKey (0)
Donc, ce code est autant que le code pour la détection de visage, mais ici nous avons ajouté des cascades oculaires et une méthode pour les détecter, comme vous pouvez le voir, nous avons choisi la version à échelle de gris du visage comme paramètre pour la detectMultiScale pour les yeux, ce qui nous amène à la réduction du calcul car nous n'allons détecter les yeux que dans cette zone seulement.
Détection des visages et des yeux en direct
Donc, jusqu'à présent, nous avons fait la détection des visages et des yeux, maintenant implémentons la même chose avec le flux vidéo en direct de la webcam. En cela, nous ferons la même détection du visage et des yeux, mais cette fois, nous le ferons pour le flux en direct de la webcam. Dans la plupart des applications, vous trouverez votre visage mis en évidence avec une boîte autour de lui, mais ici, nous avons fait quelque chose de différent pour que vous trouviez votre visage rogné et que les yeux ne s'identifieraient que dans cela.
Donc, ici, nous importons à la fois le classificateur de visage et d'oeil, et avons défini une fonction pour faire tout le traitement pour la détection du visage et des yeux. Et après cela a démarré le flux webcam et appelé la fonction de détecteur de visage pour détecter le visage et les yeux. Le paramètre que nous définissons dans la fonction de détecteur de visage sont les images continues du flux de webcam en direct
import cv2 import numpy as np face_classifier = cv2.CascadeClassifier ('haarcascade_frontalface_default.xml') eye_classifier = cv2.CascadeClassifier ('haarcascade_eye.xml') def face_detector (img, size = 0.5): # Convertir l'image en niveaux de grisv gris (img, cv2.COLOR_BGR2GRAY) faces = face_classifier.detectMultiScale (gray, 1.3, 5) if faces is (): return img for (x, y, w, h) in faces: x = x - 50 w = w + 50 y = y - 50 h = h + 50 cv2.rectangle (img, (x, y), (x + w, y + h), (255,0,0), 2) roi_gray = gris roi_color = img yeux = eye_classifier.detectMultiScale (roi_gray) pour (ex, ey, ew, eh) dans les yeux: cv2.rectangle (roi_color, (ex, ey), (ex + ew, ey + eh), (0,0,255), 2) roi_color = cv2.flip (roi_color, 1) return roi_color cap = cv2.VideoCapture (0) while True: ret, frame = cap.read () cv2.imshow ('Our Face Extractor', face_detector (frame)) if cv2.waitKey (1) == 13: # 13 est la clé Enter break cap.release () cv2.destroyAllWindows ()
Réglage des classificateurs en cascade
Les paramètres définis dans detectMultiScale autres que l'image d'entrée ont la signification suivante
ourClassifier. detectMultiScale (image d'entrée, facteur d'échelle, voisins min.)
- Facteur d'échelle Spécifie dans quelle mesure nous réduisons la taille de l'image à chaque mise à l'échelle. Par exemple, dans la détection de visage, nous utilisons généralement 1.3. Cela signifie que nous réduisons l'image de 30% à chaque fois qu'elle est mise à l'échelle. Des valeurs plus petites, comme 1.05, prendront plus de temps à calculer, mais augmenteront le taux de détection.
- Min Neighbours Spécifie le nombre de voisins que chaque fenêtre potentielle doit avoir pour la considérer comme une détection positive. Généralement défini entre 3-6. Il agit comme paramètre de sensibilité, des valeurs faibles détectent parfois plusieurs visages sur une seule face. Des valeurs élevées garantiront moins de faux positifs, mais vous risquez de manquer certains visages.
Détection de voitures et de piétons en vidéos
Nous allons maintenant détecter les piétons et les voitures dans les vidéos en utilisant les cascades HAAR, mais dans le cas où aucune vidéo ne se charge et que le code se compile sans erreur, vous devez suivre les étapes suivantes:
Si aucune vidéo ne se charge après l'exécution du code, vous devrez peut-être copier notre opencv_ffmpeg.dl à partir de : opencv \ sources \ 3rdparty \ ffmpeg pour le coller là où votre python est installé, par exemple C: \ Anaconda2
Une fois copié, vous devrez renommer le fichier en fonction de la version d'OpenCV que vous utilisez.eg si vous utilisez OpenCV 2.4.13 puis renommez le fichier comme: opencv_ffmpeg2413_64.dll ou opencv_ffmpeg2413.dll (si vous en utilisant une machine X86) opencv_ffmpeg310_64.dll ou opencv_ffmpeg310.dll (si vous utilisez une machine X86)
Pour savoir où vous python.exe est installé, exécutez simplement ces deux lignes de code, il afficherait l'emplacement où python est installé.
import sys print (sys.executable)
Maintenant, si vous avez réussi ces étapes, passons au code de détection des piétons, Vous pouvez avoir la cascade pour la détection des piétons et à partir du fichier zip joint ici.
import cv2 import numpy as np # Créer notre classificateur de corps body_classifier = cv2.CascadeClassifier ('haarcascade_fullbody.xml') # Lancer la capture vidéo pour le fichier vidéo, ici nous utilisons le fichier vidéo dans lequel les piétons seraient détectés cap = cv2.VideoCapture ('walking.avi') # Boucle une fois la vidéo chargée avec succès tandis que cap.isOpened (): # Lecture de chaque image de la vidéo ret, frame = cap.read () # ici nous redimensionnons l'image à la moitié de sa taille, nous faisons pour accélérer la classification # car les images plus grandes ont beaucoup plus de fenêtres sur lesquelles glisser, donc dans l'ensemble nous réduisons la résolution #of vidéo par moitié, c'est ce que 0.5 indique, et nous utilisons également une méthode d'interpolation plus rapide qui est #interlinear frame = cv2.resize (frame, None, fx = 0.5, fy = 0.5, interpolation = cv2.INTER_LINEAR) gray = cv2. cvtColor (frame, cv2.COLOR_BGR2GRAY) # Passer le frame à notre classificateur de corps corps = body_classifier.detectMultiScale (gray, 1.2, 3) # Extraire les cadres de délimitation pour tous les corps identifiés pour (x, y, w, h) dans les corps: cv2. rectangle (frame, (x, y), (x + w, y + h), (0, 255, 255), 2) cv2.imshow ('Piétons', frame) si cv2.waitKey (1) == 13: # 13 est la touche Entrée pause cap.release () cv2.destroyAllWindows ()
Après avoir détecté avec succès un piéton en vidéo, passons au code pour la détection de voiture.Vous pouvez avoir la cascade pour la détection de piétons à partir d'ici.
import cv2 import time import numpy as np # Créer notre classificateur de corps car_classifier = cv2.CascadeClassifier ('haarcascade_car.xml') # Lancer la capture vidéo pour le fichier vidéo cap = cv2.VideoCapture ('cars.avi') # Boucle une fois la vidéo réussie chargé pendant que cap.isOpened (): time.sleep (.05) # Lire la première image ret, frame = cap.read () gray = cv2.cvtColor (frame, cv2.COLOR_BGR2GRAY) # Passer le cadre à notre classificateur de voiture cars = car_classifier.detectMultiScale (gray, 1.4, 2) # Extraire les cadres de délimitation pour tous les corps identifiés pour (x, y, w, h) dans les voitures: cv2.rectangle (frame, (x, y), (x + w, y + h)), (0, 255, 255), 2) cv2.imshow ('Cars', cadre) si cv2.waitKey (1) == 13: # 13 est la touche Entrée pause cap.release () cv2.destroyAllWindows ()
Vous avez remarqué que nous avons ajouté time.sleep (.05) , c'est juste un retard dans la fréquence d'images afin que vous puissiez confirmer que toutes les voitures sont correctement identifiées, ou vous pouvez facilement le supprimer simplement en y ajoutant une étiquette de commentaire.
Cet article est issu du cours Master Computer Vision ™ OpenCV4 en Python avec Deep Learning sur Udemy, créé par Rajeev Ratan, abonnez-vous pour en savoir plus sur Computer Vision et Python.