- Objekterkennung mit SIFT
- Objekterkennung mit ORB
- Histogramm orientierter Gradienten (HOGs)
- Histogramm orientierter Gradienten (HOGs), Schritt für Schritt:
- HAAR-Kaskadenklassifikatoren
- Gesichts- und Augenerkennung
- Live-Gesichts- und Augenerkennung
- Tuning Cascade Classifiers
- Auto- und Fußgängererkennung in Videos
Wir haben mit der Installation von Python OpenCV unter Windows begonnen und bisher einige grundlegende Bildverarbeitungs-, Bildsegmentierungs- und Objekterkennungsfunktionen mit Python durchgeführt, die in den folgenden Tutorials behandelt werden:
- Erste Schritte mit Python OpenCV: Installation und grundlegende Bildverarbeitung
- Bildmanipulationen in Python OpenCV (Teil 1)
- Bildmanipulationen in OpenCV (Teil-2)
- Bildsegmentierung mit OpenCV - Extrahieren bestimmter Bereiche eines Bildes
Wir haben auch verschiedene Methoden und Algorithmen für die Objekterkennung kennengelernt, bei denen einige Schlüsselpunkte für jedes Objekt mithilfe verschiedener Algorithmen identifiziert wurden. In diesem Tutorial werden wir diese Algorithmen verwenden, um reale Objekte zu erkennen. Hier würden wir SIFT und ORB für die Erkennung verwenden.
Objekterkennung mit SIFT
Hier erfolgt die Objekterkennung mithilfe eines Live-Webcam-Streams. Wenn das Objekt erkannt wird, wird das gefundene Objekt erwähnt. Im Code spielt die Funktion, die als SIFT-Detektor bezeichnet wird, die Hauptrolle. Der größte Teil der Verarbeitung erfolgt über diese Funktion.
In der anderen Hälfte des Codes beginnen wir mit dem Öffnen des Webcam-Streams und laden dann die Bildvorlage, dh das Referenzbild, dh das Programm schaut tatsächlich durch den Webcam-Stream.
Als nächst wir die Erfassung kontinuierlich die Bilder von dem Webcam Strom mit Hilfe von unendlich, während Schleife und dann auf die entsprechende Höhe und Breite des Webcam Rahmens aufnehmen, und nach dann den Parametern des interessierenden Bereichs (ROI) Feld definieren, in dem Unser Objekt kann passen, indem die entsprechende Höhe und Breite des Webcam-Rahmens verwendet wird. Und dann zeichnen wir das Rechteck aus den oben definierten ROI-Parametern. Schneiden Sie das Rechteck schließlich aus und führen Sie es in den SWIFT-Detektorteil des Codes ein.
Jetzt hat der SIFT-Detektor im Wesentlichen zwei Eingänge, einer ist das zugeschnittene Bild und der andere ist die zuvor definierte Bildvorlage. Dann gibt er uns einige Übereinstimmungen, sodass Übereinstimmungen im Grunde die Anzahl der Objekte oder Schlüsselpunkte sind, die im zugeschnittenen Bild ähnlich sind und das Zielbild. Dann definieren wir einen Schwellenwert für die Übereinstimmungen. Wenn der Übereinstimmungswert größer als der Schwellenwert ist, setzen wir das gefundene Bild mit der grünen Farbe des ROI-Rechtecks auf unseren Bildschirm.
Kehren wir nun zum Hauptteil des Codes zurück, der Funktion, die als SIFT-Detektor bezeichnet wird. Sie verwendet die Eingabe als zwei Bilder. Eines ist das Bild, in dem nach dem Objekt gesucht wird, und das andere ist das Objekt, mit dem wir übereinstimmen möchten zu (Bildvorlage). Graustufen Sie dann das erste Bild und definieren Sie die Bildvorlage als zweites Bild. Dann erstellen wir ein SIFT-Detektorobjekt und führen die OpenCV-SIFT-Erkennungs- und Berechnungsfunktion aus. Um die Schlüsselpunkte zu erkennen und die Deskriptoren zu berechnen, sind Deskriptoren im Grunde die Vektoren, die die Informationen über die Schlüsselpunkte speichern, und es ist wirklich wichtig, wenn wir den Abgleich durchführen zwischen den Deskriptoren der Bilder.
Und dann definieren Sie den FLANN-basierten Matcher. Wir gehen nicht auf die mathematische Theorie des Matchings dahinter ein, aber Sie können ganz einfach darüber googeln. Definieren Sie zuerst den Index kdtree auf Null und setzen Sie dann die Index- und Suchparameter im Wörterbuchformat. Wir definieren nur den Algorithmus, den wir verwenden möchten, nämlich KDTREE, und die Anzahl der Bäume, die wir verwenden werden, je mehr Baum Wir verwenden die kompliziertere und langsamere. Definieren Sie im Suchparameter die Anzahl der Überprüfungen, dh die Anzahl der Übereinstimmungen, die abgeschlossen werden sollen.
Erstellen Sie dann unser FLANN-basiertes Matcher-Objekt, indem Sie den zuvor definierten Parameter laden, bei dem es sich um Indexparameter und Suchparameter handelt, und erstellen Sie darauf basierend unseren FLANN-basierten Matcher, einen KNN-Matcher, bei dem KNN K-nächste Nachbarn ist Wir suchen nach nächsten Matchern und Deskriptoren und führen den Matching mit der Initialisierungskonstante k durch. Jetzt gibt dieser FLANN-basierte Matcher die Anzahl der Übereinstimmungen zurück, die wir erhalten.
FLANN-basiertes Matching ist nur eine Annäherung. Um die Genauigkeit des FLANN-basierten Matchers zu erhöhen, führen wir einen Lowe-Ratio-Test durch. Dabei werden die Übereinstimmungen des bekannten Flann-basierten Matchers gesucht und einige Matrizenparameter definiert, bei denen es sich um die Entfernung handelt, für welche Entfernung eine Numpy-Funktion ist, und sobald sie die Kriterien erfüllt, hängen Sie die Übereinstimmungen an die guten Übereinstimmungen an und geben die gefundenen guten Übereinstimmungen zurück. Der Live-Videostream gibt daher die Anzahl der gefundenen Übereinstimmungen in der Ecke des Bildschirms an.
Schauen wir uns nun den Code für die obige Beschreibung an:
import cv2 import numpy as np def sift_detector (new_image, image_template): # Funktion, die das Eingabebild mit der Vorlage vergleicht # Anschließend wird die Anzahl der SIFT-Übereinstimmungen zwischen ihnen zurückgegeben. image1 = cv2.cvtColor (new_image, cv2.COLOR_BGR2GRAY) image2 = image_template # Create SIFT Detektor Objekt #sift = cv2.SIFT () Sift cv2.xfeatures2d.SIFT_create = () # Besorgen die keypoints und Deskriptoren unter Verwendung SIFT keypoints_1, descriptors_1 = sift.detectAndCompute (image1, None) keypoints_2, descriptors_2 = sift.detectAndCompute (image2, Keine) # Definieren Sie Parameter für unseren Flann Matcher FLANN_INDEX_KDTREE = 0 index_params = dict (Algorithmus = FLANN_INDEX_KDTREE, Bäume = 3) search_params = dict (Kontrollen = 100) # Erzeuge das Flann Matcher Objekt flann = cv2.FlannBasedMatcher (index_params, search_params) # paßt Erhalten K-Nearest Neighbor - Methode unter Verwendung der Folge 'Match' ist die Anzahl von ähnlichen Übereinstimmungen in beiden Bildern gefunden # Streichhölzern = flann.knnMatch (Deskriptoren_1, Deskriptoren_2, k = 2) # Speichern Sie gute Übereinstimmungen mit dem Lowe-Verhältnis-Test good_matches = für m, n in Übereinstimmungen: wenn m.distance <0,7 * n.distance: good_matches.append (m) return len (good_matches) cap = cv2.VideoCapture (0) # Laden Sie unsere Bildvorlage. Dies ist unser Referenzbild. image_template = cv2.imread ('phone.jpg', 0), während True: # Webcam-Bilder abrufen ret, frame = cap.read () # Höhe und Breite der Webcam-Rahmenhöhe ermitteln , width = frame.shape # ROI-Box-Abmessungen definieren 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)) # Zeichne ein rechteckiges Fenster für unsere Region von Interesse cv2.rectangle (frame, (top_left_x, top_left_y)), (bottom_right_x, bottom_right_y), 255, 3) # Crop-Beobachtungsfenster, das wir oben definiert haben, beschnitten = frame # Frame-Ausrichtung horizontal spiegeln frame = cv2.flip (frame, 1) # Anzahl der SIFT-Übereinstimmungen abgleichen matchs = sift_detector (beschnitten, image_template) # Statuszeichenfolge mit der aktuellen Nr. Anzeigen. Anzahl der Übereinstimmungen cv2.putText (frame, str (Übereinstimmungen), (450.450), cv2.FONT_HERSHEY_COMPLEX, 2, (0,255,0), 1) # Unser Schwellenwert für die Anzeige der Objekterkennung # Wir verwenden 10, da der SIFT-Detektor nur wenige Fehlalarme zurückgibt Schwelle = 10 # Wenn Übereinstimmungen unsere Schwelle überschreiten, wurde ein Objekt erkannt, wenn Übereinstimmungen> Schwelle: cv2.rectangle (frame, (top_left_x, top_left_y), (bottom_right_x, bottom_right_y), (0,255,0), 3) cv2.putText (frame, 'Objekt gefunden', (50,50), cv2.FONT_HERSHEY_COMPLEX, 2, (0,255,0), 2) cv2.imshow ('Objektdetektor mit SIFT', Rahmen), wenn cv2.waitKey (1) == 13: # 13 ist der Enter Key break cap.release () cv2.destroyAllWindows ()
Objekterkennung mit ORB
Die Objekterkennung mit SIFT ist ziemlich cool und genau, da sie eine sehr genaue Anzahl von Übereinstimmungen basierend auf Schlüsselpunkten generiert, jedoch patentiert ist. Dies macht es schwierig, sie für kommerzielle Anwendungen zu verwenden. Der andere Ausweg ist der ORB-Algorithmus zur Objekterkennung.
Ähnlich wie bei der Objekterkennungsmethode durch SIFT, bei der wir das Programm in zwei Teile geteilt haben, wird hier dasselbe befolgt.
Zunächst definieren wir die Funktion ORB_detector, die zwei Eingaben benötigt. Eine ist das von der Webcam kommende Live-Stream-Bild und die andere ist die Bildvorlage, auf deren Grundlage wir unserem Bild entsprechen werden. Dann skalieren wir unser Webcam-Bild in Graustufen und initialisieren dann unseren ORB-Detektor. Hier setzen wir ihn auf 1000 Schlüsselpunkte und Skalierungsparameter von 1,2. Sie können leicht mit diesen Parametern herumspielen und dann die Schlüsselpunkte (kp) und Deskriptoren (des) für beide Bilder erkennen. Der zweite Parameter, den wir in der Funktion " detandANDCompute" definieren, ist NONE. Er fordert die Verwendung einer Bildmaske oder nicht und wir leugnen es hier.
Gehen Sie dann zum Detektor, den wir zuvor mit FLANN-basiertem Matcher verwendet haben. Hier verwenden wir jedoch BFMatcher. In BFMatcher definieren wir zwei Parameter, einen NORM_HAMMING und einen CrossCheck mit dem Wert TRUE.
Berechnen Sie dann die Übereinstimmungen der Übereinstimmungen zwischen diesen beiden Bildern unter Verwendung der oben definierten Deskriptoren, die insgesamt die Anzahl der Übereinstimmungen zurückgeben, da diese Übereinstimmungen keine Annäherung darstellen und daher kein Lowe-Verhältnis-Test erforderlich ist. Stattdessen sortieren wir die Übereinstimmungen nach Entfernung Mindestens die Entfernung ist größer, je besser die Übereinstimmung ist (hier bedeutet die Entfernung die Entfernung zwischen den Punkten), und am Ende geben wir die Anzahl der Übereinstimmungen mithilfe der Längenfunktion zurück.
Und in der Hauptfunktion setzen wir den Schwellenwert auf einen viel höheren Wert, da der Kugeldetektor viel Rauschen erzeugt.
Schauen wir uns nun den Code für die ORB-basierte Erkennung an
import cv2 import numpy as np def ORB_detector (new_image, image_template): # Funktion, die das Eingabebild mit der Vorlage vergleicht # Gibt dann die Anzahl der ORB-Übereinstimmungen zwischen ihnen zurück image1 = cv2.cvtColor (new_image, cv2.COLOR_BGR2GRAY) # ORB-Detektor erstellen mit 1000 Schlüsselpunkte mit einem Skalierungspyramidenfaktor von 1,2 orb = cv2.ORB_create (1000, 1.2) # Schlüsselpunkte des Originalbilds erkennen (kp1, des1) = orb.detectAndCompute (Bild1, Keine) # Schlüsselpunkte des gedrehten Bildes erkennen (kp2, des2) = orb.detectAndCompute (image_template, None) # Matcher erstellen # Beachten Sie, dass wir kein flannbasiertes Matching mehr verwenden. bf = cv2.BFMatcher (cv2.NORM_HAMMING, crossCheck = True) # Übereinstimmende Übereinstimmungen durchführen = bf.match (des1, des2) # Sortieren Sie die Übereinstimmungen nach Entfernung. Der geringste Abstand # ist besser Übereinstimmungen = sortiert (Übereinstimmungen, Schlüssel = Lambda val: val.distance) return len (Übereinstimmungen) cap = cv2.VideoCapture (0) # Laden Sie unsere Bildvorlage, dies ist unser Referenzbild image_template = cv2.imread ('phone.jpg', 0) # image_template = cv2.imread ('images / kitkat.jpg', 0), während True: # Get Webcam - Bilder ret, frame = cap.read () # Get Höhe und Breite der Webcam Rahmenhöhe, width = frame.shape # ROI-Box-Abmessungen definieren (Beachten Sie, dass einige dieser Dinge außerhalb der Schleife liegen sollten) top_left_x = int (width / 3) top_left_y = int ((Höhe / 2) + (Höhe / 4)) bottom_right_x = int ((Breite / 3) * 2) bottom_right_y = int ((Höhe / 2) - (Höhe / 4)) # Zeichne ein rechteckiges Fenster für unsere region of interest cv2.rectangle (Rahmen, (top_left_x, top_left_y), (bottom_right_x, bottom_right_y), 255, 3) # Crop Beobachtungsfenster wir oben definiert abgeschnitten = Rahmenausrichtung # Flip Rahmen horizontal frame = cv2.flip (frame, 1) # Anzahl der übereinstimmenden ORB-Übereinstimmungen abrufen = ORB_detector (beschnitten, image_template) # Statuszeichenfolge mit der aktuellen Nr. Anzeigen. Anzahl Übereinstimmungen output_string = "Matches =" + str (Übereinstimmungen) cv2.putText (frame, output_string, (50.450), cv2.FONT_HERSHEY_COMPLEX, 2, (250,0,150), 2) # Unser Schwellenwert zur Anzeige der Objekterkennung # Für neue Bilder oder Aufhellungsbedingungen müssen Sie möglicherweise ein wenig experimentieren. # Hinweis: Der ORB-Detektor, um die besten 1000 Übereinstimmungen zu erzielen , 350 ist im Wesentlichen ein Mindestübereinstimmungsschwellenwert von 35% = 250 # Wenn Übereinstimmungen unsere überschreiten Schwelle dann Objekt wurde erkannt, wenn Übereinstimmungen> Schwelle: cv2.rectangle (Rahmen, (top_left_x, top_left_y), (bottom_right_x, bottom_right_y), (0,255,0), 3) cv2.putText (Rahmen, 'Objekt gefunden', (50, 50), cv2.FONT_HERSHEY_COMPLEX, 2, (0,255,0), 2) cv2.imshow ('Object Detector ORB', Rahmen), wenn cv2.waitKey (1) == 13: 13 # ist die Enter - Taste Pause Kappe.release () cv2.destroyAllWindows ()
Histogramm orientierter Gradienten (HOGs)
Lassen Sie uns nun über einen anderen Deskriptor sprechen, nämlich das Histogramm orientierter Gradienten (HOGs).
HOGs sind ziemlich coole und nützliche Deskriptoren, und sie werden häufig und erfolgreich zur Objekterkennung verwendet, wie zuvor bei Bilddeskriptoren wie SIFT und ORB zu sehen war, bei denen wir Schlüsselpunkte berechnen und dann Deskriptoren aus diesen Schlüsselpunkten berechnen müssen. HOGs führen diesen Prozess aus anders. Es repräsentiert Objekte als einen einzelnen Merkmalsvektor im Gegensatz zu einem Satz von Merkmalsvektoren, wobei jeder ein Segment des Bildes darstellt. Dies bedeutet, dass wir ein einzelnes Vektormerkmal für das gesamte Bild haben.
Es wird von einem Schiebefensterdetektor über einem Bild berechnet, wobei ein HOG-Deskriptor für jede Position berechnet wird. Und dann wird jede Position für einen einzelnen Merkmalsvektor kombiniert.
Wie bei SIFT wird der Maßstab des Bildes durch Pyramiden angepasst.
Früher haben wir Matcher wie FLANN und BFMatcher verwendet, aber HOGs machen es mit Hilfe von SVM-Klassifikatoren (Support Vector Machine) anders, wobei jeder berechnete HOG-Deskriptor einem SVM-Klassifikator zugeführt wird, um festzustellen, ob das Objekt gefunden wurde oder nicht.
Hier ist der Link zu einem großartigen Artikel von Dalal & Triggs über die Verwendung von HOGs zur Erkennung von Menschen:
Histogramm orientierter Gradienten (HOGs), Schritt für Schritt:
Das Verständnis von HOGs könnte recht komplex sein, aber hier werden wir uns nur mit der Theorie von HOGs befassen, ohne näher auf die damit verbundene Mathematik einzugehen.
Nehmen wir also dieses Bild auf, es ist ein wenig pixelig, und in der oberen Ecke befindet sich hier eine 8x8-Pixel-Box. In dieser Box berechnen wir den Gradientenvektor oder die Kantenausrichtungen für jedes Pixel. Das bedeutet, dass wir in dieser Box den Bildgradientenvektor der Pixel innerhalb der Box berechnen (sie sind eine Art Richtung oder Fluss der Bildintensität selbst), und dies erzeugt 64 (8 x 8) Gradientenvektoren, die dann als Histogramm dargestellt werden. Stellen Sie sich also ein Histogramm vor, das jeden Gradientenvektor darstellt. Wenn also alle Punkte oder Intensitäten in einer Richtung liegen, das Histogramm für diese Richtung, sagen wir 45 Grad, hätte das Histogramm eine Spitze bei 45 Grad.
Was wir jetzt tun, ist, dass wir jede Zelle in eckige Behälter aufteilen, wobei jeder Behälter einer Gradientenrichtung entspricht (z. B. x, y). Im Dalal- und Triggs-Papier verwendeten sie 9 Behälter 0-180 ° (20 ° pro Behälter). Dies reduziert 64 Vektoren effektiv auf nur 9 Werte. Wir haben also die Größe reduziert, aber alle wichtigen Informationen aufbewahrt, die benötigt werden.
Der nächste Schritt bei der Berechnung der Schweine ist die Normalisierung. Wir normalisieren die Gradienten, um die Invarianz gegenüber Beleuchtungsänderungen, dh Helligkeit und Kontrast, sicherzustellen.
In diesem Bild werden die Intensitätswerte entsprechend der jeweiligen Richtung im Quadrat angezeigt und haben alle einen Unterschied von 50 untereinander
∆ H = 50, ∆ v = 50; │∆│ = √50 2 +50 = 70,72, 70,72 / 100 = 0,707
Wir teilen die Vektoren durch die Gradientengrößen, die wir für alle 0,707 erhalten, dies ist Normalisierung.
In ähnlicher Weise erhalten wir die folgenden Werte, wenn wir die Intensität oder den Kontrast ändern.
∆ 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
Die Normalisierung findet nicht auf Zellebene statt, sondern auf Blockebene. Hier sind die Blöcke also im Grunde eine Gruppe von 4 Zellen. Dies berücksichtigt benachbarte Blöcke, also normalisieren Sie, während Sie größere Bildsegmente berücksichtigen.
Schauen wir uns nun den Code an
import numpy as np import cv2 import matplotlib.pyplot as plt # Bild laden, dann Graustufenbild = cv2.imread ('elephant.jpg') grey = cv2.cvtColor (image, cv2.COLOR_BGR2GRAY) # Originalbild anzeigen cv2.imshow (' Eingabebild ', Bild) cv2.waitKey (0) # Definieren der Parameter, Zellengröße und Blockgröße # hxw in Pixel cell_size = (8, 8) # hxw in Zellen block_size = (2, 2) # Anzahl der Orientierungsfächer nbins = 9 # Verwenden des HOG-Deskriptors von OpenCV # winSize ist die Größe des Bildes, das auf ein Vielfaches der Zellengröße zugeschnitten ist. Hog = cv2.HOGDescriptor (_winSize = (grey.shape // cell_size * cell_size, grey.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) # Erstellen Sie eine numpy-Array-Form, die wir verwenden um hog_features zu erstellen n_cells = (grey.shape // cell_size, grey.shape // cell_size) # Wir indizieren Blöcke zuerst nach Zeilen. # hog_feats enthält jetzt die Gradientenamplituden für jede Richtung, # für jede Zelle ihrer Gruppe für jede Gruppe. Die Indizierung erfolgt nach Zeilen und dann nach Spalten. hog_feats = hog.compute (grau).reshape (n_cells - block_size + 1, n_cells - block_size + 1, block_size, block_size, nbins).transpose ((1, 0, 2, 3, 4)) # Erstellen Sie unser Verlaufsarray mit nbin-Dimensionen, um Gradientenorientierungen zu speichern. Gradienten = np.zeros ((n_cells, n_cells, nbins)) # Erstellen Sie ein Array von Dimensionen cell_count = np.full ((n_cells, n_cells, 1), 0, dtype = int) # Blocknormalisierung für off_y im Bereich (block_size): für off_x im Bereich (block_size): Farbverläufe - 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 # Durchschnittliche Gradientengradienten / = cell_count # HOGs mit Matplotlib zeichnen # Winkel beträgt 360 / nbins * Richtung color_bins = 5 plt.pcolor (Gradienten) plt.gca (). invert_yaxis () plt.gca (). set_aspect ('gleich', einstellbar = 'box') plt.colorbar () plt.show () cv2.destroyAllWindows ()
Das Bild zeigt, wie das Eingabebild als HOG-Darstellung dargestellt wird.
HAAR-Kaskadenklassifikatoren
Wie bereits erwähnt, können wir Features aus einem Bild extrahieren und diese Features zum Klassifizieren oder Erkennen von Objekten verwenden.
Was sind HAAR Cascade Classifiers?
Ein Objekt - Detektionsverfahren, dass Eingänge Haar kennzeichnet in eine Reihe von Klassifikatoren (Kaskade) Objekte in einem Bild zu identifizieren. Sie sind darauf trainiert, einen Objekttyp zu identifizieren. Wir können jedoch mehrere davon parallel verwenden, z. B. Augen und Gesichter gemeinsam erkennen.
HAAR-Klassifikatoren Erklärt:
HAAR-Klassifikatoren werden mit vielen positiven Bildern (dh Bildern mit vorhandenem Objekt) und
negativen Bildern (dh Bildern ohne vorhandenes Objekt) trainiert.
Sobald wir diese Bilder haben, extrahieren wir Features mithilfe von Schiebefenstern aus rechteckigen Blöcken. Diese Merkmale (HAAR-Merkmale) sind einwertig und werden berechnet, indem die Summe der Pixelintensitäten unter den weißen Rechtecken von den schwarzen Rechtecken subtrahiert wird.
Dies ist jedoch eine lächerliche Anzahl von Berechnungen, selbst für ein Basisfenster von 24 x 24 Pixel (180.000 generierte Features).
Daher entwickelten die Forscher eine Methode namens Integral Images, die dies mit vier Array-Referenzen berechnete. Sie hatten jedoch immer noch 180.000 Funktionen und die meisten von ihnen fügten keinen wirklichen Mehrwert hinzu.
Boosting wurde dann verwendet, um die informativsten Merkmale mit AdaBoost von Freund & Schapire zu bestimmen, und es wurden die informativsten Merkmale im Bild gefunden. Boosting ist der Prozess, bei dem wir schwache Klassifikatoren verwenden, um starke Klassifikatoren zu erstellen, indem wir einfach schwergewichtige Strafen für falsche Klassifikationen zuweisen. Reduzierung der 180.000 Funktionen auf 6000, was immer noch einiges ist.
In diesen 6000 Funktionen sind einige informativer als andere. Wenn wir also die informativsten Funktionen verwenden, um zunächst zu prüfen, ob die Region möglicherweise ein Gesicht haben kann (Fehlalarme sind keine große Sache). Auf diese Weise müssen nicht alle 6000 Funktionen gleichzeitig berechnet werden. Dieses Konzept wird als Cascade of Classifiers bezeichnet - für die Gesichtserkennung verwendete die Viola Jones-Methode 38 Stufen.
Gesichts- und Augenerkennung
Nachdem wir einige theoretische Kenntnisse über die HAAR-Kaskaden erworben haben, werden wir sie endlich implementieren. Um die Dinge ziemlich klar zu machen, werden wir die Lektionen in Teile aufteilen. Zuerst würden wir das Frontalgesicht erkennen, danach werden wir uns bewegen, um das Frontalgesicht mit zu erkennen Augen und schließlich würden wir Gesicht und Augen live über die Webcam erkennen.
Daher werden wir vorgefertigte Klassifizierer verwenden, die von OpenCV als XML-Dateien bereitgestellt wurden. XML steht für erweiterbare Auszeichnungssprache. Diese Sprache wird zum Speichern großer Datenmengen verwendet. Sie können sogar eine Datenbank darauf erstellen.
Sie können auf diese Klassifizierer unter diesem Link zugreifen .
Gesichtserkennung
Versuchen wir es mit der Frontalgesichtserkennung. Hier können Sie auf die Kaskade des Frontalgesichtsdetektors zugreifen. Extrahieren Sie einfach die Zip-Datei, um die XML-Datei zu erhalten.
import numpy as np import cv2 # Wir verweisen auf die CascadeClassifier-Funktion von OpenCV, in der unser # Klassifikator (XML-Dateiformat) gespeichert ist. Denken Sie daran, den Code und den Klassifikator im selben Ordner zu speichern. face_cascade = cv2.CascadeClassifier ('haarcascade_frontalface_default.xml') # Load Unser Bild konvertiert es dann in Graustufen. image = cv2.imread ('Trump.jpg') grey = cv2.cvtColor (image, cv2.COLOR_BGR2GRAY) # Unser Klassifikator gibt den ROI des erkannten Gesichts als Tupel zurück. # Es speichert oben links Koordinate und die Koordinaten unten rechts # gibt die Liste der Listen zurück, in denen verschiedene Gesichter erkannt wurden. Gesichter = face_cascade.detectMultiScale (grau, 1.3, 5) # Wenn keine Gesichter erkannt werden, gibt face_classifier zurück und leert das Tupel, wenn Gesichter () ist: print ("Keine Gesichter gefunden") # Wir durchlaufen unser Gesichtsarray und zeichnen ein Rechteck # über jedes Gesicht in Gesichtern für (x, y, w, h) in Gesichtern: cv2.rectangle (Bild, (x, y), (x + w, y + h), (127,0,255), 2) cv2.imshow ('Gesichtserkennung', Bild) cv2.waitKey (0) cv2.destroyAllWindows ()
Kombinieren wir nun die Gesichts- und Augenerkennung miteinander. Sie können auf die Kaskade des Augendetektors in derselben Zip-Datei zugreifen.
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') grey = cv2.cvt cv2.COLOR_BGR2GRAY) zugewandt = face_classifier.detectMultiScale (grau, 1.3, 5) # wenn keine Gesichter erkannt, kehrt face_classifier und leere Tupels, wenn Flächen sind (): print ("No Face gefunden") für (x, y, w, h) in Gesichtern: cv2.rectangle (img, (x, y), (x + w, y + h), (127,0,255), 2) cv2.imshow ('img', img) roi_gray = grey roi_color = img eyes = eye_classifier.detectMultiScale (roi_gray) cv2.waitKey (0) für (ex, ey, ew, eh) in Augen: 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)
Dieser Code ist also genauso wie der Code für die Gesichtserkennung, aber hier haben wir Augenkaskaden und Methoden hinzugefügt, um sie zu erkennen. Wie Sie sehen, haben wir die grau skalierte Version des Gesichts als Parameter für die Erkennung von MultiScale ausgewählt die Augen, was uns zu einer Verringerung der Berechnung führt, da wir nur in diesem Bereich Augen erkennen werden.
Live-Gesichts- und Augenerkennung
Bis jetzt haben wir die Gesichts- und Augenerkennung durchgeführt. Jetzt implementieren wir dasselbe mit dem Live-Videostream von der Webcam. Dabei werden wir die gleiche Erkennung von Gesicht und Augen durchführen, diesmal jedoch für den Live-Stream der Webcam. In den meisten Anwendungen wurde Ihr Gesicht mit einem Kästchen hervorgehoben, aber hier haben wir etwas anderes gemacht, bei dem Ihr Gesicht ausgeschnitten ist und die Augen sich nur darin identifizieren.
Hier importieren wir also sowohl den Gesichts- als auch den Augenklassifikator und definieren eine Funktion für die gesamte Verarbeitung der Gesichts- und Augenerkennung. Danach startete der Webcam-Stream und rief die Gesichtserkennungsfunktion auf, um das Gesicht und die Augen zu erkennen. Der Parameter, den wir innerhalb der Gesichtsdetektorfunktion definieren, sind die fortlaufenden Bilder aus dem Live-Web-Cam-Stream
cv2 importieren numpy als np importieren face_classifier = cv2.CascadeClassifier ('haarcascade_frontalface_default.xml') eye_classifier = cv2.CascadeClassifier ('haarcascade_eye.xml') def face_detector (img, size = 0.5): # Bild in Graustufen konvertieren (img, cv2.COLOR_BGR2GRAY) Gesichter = face_classifier.detectMultiScale (grau, 1.3, 5) wenn Gesichter () sind: Geben Sie img für (x, y, w, h) in Gesichtern zurück: x = x - 50 w = w + 50 y = y - 50 h = h + 50 cv2. Rechteck (img, (x, y), (x + w, y + h), (255,0,0), 2) roi_gray = grau roi_color = img Augen = eye_classifier.detectMultiScale (roi_gray) für (ex, ey, ew, eh) in Augen: 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) während True: ret, frame = cap.read () cv2.imshow ('Unser Gesichtsextraktor', face_detector (frame)), wenn cv2.waitKey (1) == 13: # 13 der Enter Key break cap.release () ist cv2.destroyAllWindows ()
Tuning Cascade Classifiers
Die in detectMultiScale definierten Parameter außer dem Eingabebild haben die folgende Bedeutung
ourClassifier. detectMultiScale (Eingabebild, Skalierungsfaktor, Min. Nachbarn)
- Skalierungsfaktor Gibt an, um wie viel wir die Bildgröße bei jeder Skalierung reduzieren. Beispielsweise verwenden wir bei der Gesichtserkennung normalerweise 1.3. Dies bedeutet, dass wir das Bild bei jeder Skalierung um 30% reduzieren. Kleinere Werte wie 1,05 benötigen länger für die Berechnung, erhöhen jedoch die Erkennungsrate.
- Min. Nachbarn Gibt die Anzahl der Nachbarn an, die jedes potenzielle Fenster haben sollte, um es als positive Erkennung zu betrachten. In der Regel zwischen 3-6 eingestellt. Es dient als Empfindlichkeitseinstellung. Niedrige Werte erkennen manchmal mehrere Gesichter über einem einzelnen Gesicht. Hohe Werte sorgen für weniger Fehlalarme, aber Sie können einige Gesichter übersehen.
Auto- und Fußgängererkennung in Videos
Jetzt erkennen wir Fußgänger und Autos in Videos mithilfe der HAAR-Kaskaden. Wenn jedoch kein Video geladen wird und der Code fehlerfrei kompiliert wird, müssen Sie die folgenden Schritte ausführen:
Wenn keine Videolasten nach Code ausgeführt wird, müssen Sie unsere kopieren opencv_ffmpeg.dl aus : opencv \ sources \ 3rdparty \ ffmpeg es einzufügen , wo Ihre Python installiert ist, zB C: \ Anaconda2
Nach dem Kopieren müssen Sie die Datei entsprechend der von Ihnen verwendeten OpenCV-Version umbenennen. Wenn Sie OpenCV 2.4.13 verwenden, benennen Sie die Datei wie folgt um: opencv_ffmpeg2413_64.dll oder opencv_ffmpeg2413.dll (falls vorhanden) Verwenden eines X86-Computers) opencv_ffmpeg310_64.dll oder opencv_ffmpeg310.dll (wenn Sie einen X86-Computer verwenden)
Um herauszufinden, wo Sie python.exe installiert haben, führen Sie einfach diese beiden Codezeilen aus. Es wird der Speicherort gedruckt, an dem Python installiert ist.
sys print importieren (sys.executable)
Wenn Sie diese Schritte erfolgreich ausgeführt haben, wechseln wir zum Code für die Fußgängererkennung.
Sie können die Kaskade für die Fußgängererkennung und aus der hier angehängten Zip-Datei haben.
import cv2 import numpy as np # Erstellen Sie unseren Body Classifier body_classifier = cv2.CascadeClassifier ('haarcascade_fullbody.xml') # Initiieren Sie die Videoaufnahme für die Videodatei. Hier verwenden wir die Videodatei, in der Fußgänger erkannt werden würden. cap = cv2.VideoCapture ('walk.avi') # Schleife, sobald das Video erfolgreich geladen wurde, während cap.isOpened (): # Beim Lesen jedes Frames des Videos ret, frame = cap.read () # wird die Größe des Frames auf die Hälfte seiner Größe geändert Wir tun dies, um die Klassifizierung zu beschleunigen, da größere Bilder viel mehr Fenster zum Übergleiten haben. Insgesamt reduzieren wir also die Auflösung #von Video um die Hälfte ist das, was 0,5 anzeigt, und wir verwenden auch eine schnellere Interpolationsmethode, nämlich #interlineares Bild = cv2.resize (Bild, keine, fx = 0,5, fy = 0,5, Interpolation = cv2.INTER_LINEAR) grau = cv2. cvtColor (frame, cv2.COLOR_BGR2GRAY) # Übergeben Sie den Frame an unseren Body-Klassifikator body = body_classifier.detectMultiScale (grau, 1.2, 3) # Extrahieren Sie Begrenzungsrahmen für alle Körper, die für (x, y, w, h) in Körpern identifiziert wurden : cv2. Rechteck (Rahmen, (x, y), (x + w, y + h), (0, 255, 255), 2) cv2.imshow ('Fußgänger', Rahmen), wenn cv2.waitKey (1) == 13: # 13 ist der Enter Key break cap.release () cv2.destroyAllWindows ()
Nach dem erfolgreichen Fußgänger in Video zu erfassen, lassen Sie sich bewegen, um den Code für Auto - Erkennung, Sie haben die Kaskade zur Fußgängererkennung von hier haben können.
import cv2 import time import numpy as np # Erstellen Sie unseren Body Classifier car_classifier = cv2.CascadeClassifier ('haarcascade_car.xml') # Initiieren Sie die Videoaufnahme für die Videodatei cap = cv2.VideoCapture ('cars.avi') # Schleife, sobald das Video erfolgreich ist geladen, während cap.isOpened (): time.sleep (.05) # Lies den ersten Frame ret, frame = cap.read () grey = cv2.cvtColor (frame, cv2.COLOR_BGR2GRAY) # Übergebe den Frame an unseren Autoklassifikator cars = car_classifier.detectMultiScale (grau, 1.4, 2) # Extrahieren Sie Begrenzungsrahmen für alle Körper, die für (x, y, w, h) in Autos identifiziert wurden: cv2.rectangle (Rahmen, (x, y), (x + w, y + h)), (0, 255, 255), 2) cv2.imshow ('Cars', frame) wenn cv2.waitKey (1) == 13: # 13 der Enter Key break cap.release () cv2.destroyAllWindows () ist
Sie haben festgestellt, dass wir time.sleep (.05) hinzugefügt haben. Dies ist nur eine Verzögerung der Bildrate, sodass Sie bestätigen können, dass alle Autos korrekt identifiziert wurden, oder Sie können sie einfach entfernen, indem Sie ihr ein Kommentaretikett hinzufügen.
Dieser Artikel stammt aus dem Master Computer Vision ™ OpenCV4 in Python mit dem von Rajeev Ratan erstellten Deep Learning-Kurs über Udemy. Abonnieren Sie ihn, um mehr über Computer Vision und Python zu erfahren.