So erkennen und extrahieren Sie Gesichter aus einem Bild mit OpenCV und Python

Der Autor hat Open Internet / Free Speech Fund ausgewählt, um eine Spende im Rahmen von https://do.co/w4do-cta zu erhalten [Write for DOnations] program.

Einführung

Bilder machen eine große Menge der Daten aus, die jeden Tag generiert werden, weshalb die Fähigkeit zur Verarbeitung dieser Bilder wichtig ist. Eine Methode zur Verarbeitung von Bildern ist die Gesichtserkennung. Die Gesichtserkennung ist ein Zweig der Bildverarbeitung, bei dem maschinelles Lernen zum Erkennen von Gesichtern in Bildern verwendet wird.

Eine Haar Cascade ist eine Objekterkennungsmethode, die zum Auffinden eines Objekts von Interesse in Bildern verwendet wird. Der Algorithmus wird auf eine große Anzahl von positiven und negativen Abtastwerten trainiert, wobei positive Abtastwerte Bilder sind, die das interessierende Objekt enthalten. Negative Samples sind Bilder, die alles andere als das gewünschte Objekt enthalten können. Sobald er trainiert ist, kann der Klassifizierer das interessierende Objekt in allen neuen Bildern lokalisieren.

In diesem Tutorial verwenden Sie ein vorab geschultes Haar Cascade -Modell von OpenCV und https: //www.python.org/[Python] zum Erkennen und Extrahieren von Gesichtern aus einem Bild. OpenCV ist eine Open-Source-Programmierbibliothek, mit der Bilder verarbeitet werden.

Voraussetzungen

Schritt 1 - Konfigurieren der lokalen Umgebung

Bevor Sie mit dem Schreiben Ihres Codes beginnen, erstellen Sie zunächst einen Arbeitsbereich, in dem sich der Code befindet, und installieren einige Abhängigkeiten.

Erstellen Sie ein Verzeichnis für das Projekt mit dem Befehl + mkdir +:

mkdir

Wechseln Sie in das neu erstellte Verzeichnis:

cd

Als Nächstes erstellen Sie eine virtuelle Umgebung für dieses Projekt. Virtuelle Umgebungen isolieren verschiedene Projekte, sodass unterschiedliche Abhängigkeiten keine Unterbrechungen verursachen. Erstellen Sie eine virtuelle Umgebung mit dem Namen "+ face_scrapper +" für dieses Projekt:

python3 -m venv

Aktivieren Sie die isolierte Umgebung:

source /bin/activate

Sie werden nun sehen, dass Ihrer Eingabeaufforderung der Name Ihrer virtuellen Umgebung vorangestellt ist:

Nachdem Sie Ihre virtuelle Umgebung aktiviert haben, verwenden Sie "+ nano " oder Ihren bevorzugten Texteditor, um eine " requirements.txt +" - Datei zu erstellen. Diese Datei gibt die erforderlichen Python-Abhängigkeiten an:

nano requirements.txt

Als Nächstes müssen Sie drei Abhängigkeiten installieren, um dieses Lernprogramm abzuschließen:

  • + numpy +: numpy ist eine Python-Bibliothek, die Unterstützung für große, mehrdimensionale Arrays bietet. Es enthält auch eine große Sammlung mathematischer Funktionen, mit denen die Arrays bearbeitet werden können.

  • + opencv-utils +: Dies ist die erweiterte Bibliothek für OpenCV, die Hilfsfunktionen enthält.

  • + opencv-python +: Dies ist das von Python verwendete OpenCV-Kernmodul.

Fügen Sie der Datei die folgenden Abhängigkeiten hinzu:

requirements.txt

numpy
opencv-utils
opencv-python

Speichern und schließen Sie die Datei.

Installieren Sie die Abhängigkeiten, indem Sie die Datei "+ requirements.txt " an den Python-Paketmanager " pip " übergeben. Das Flag " -r " gibt den Speicherort der Datei " requirements.txt +" an.

pip install -r requirements.txt

In diesem Schritt richten Sie eine virtuelle Umgebung für Ihr Projekt ein und installieren die erforderlichen Abhängigkeiten. Sie können nun mit dem Schreiben des Codes beginnen, um im nächsten Schritt Gesichter aus einem Eingabebild zu erkennen.

Schritt 2 - Schreiben und Ausführen des Gesichtserkennungsskripts

In diesem Abschnitt schreiben Sie Code, der ein Bild als Eingabe aufnimmt und zwei Dinge zurückgibt:

  • Die Anzahl der im Eingabebild gefundenen Gesichter.

  • Ein neues Bild mit einem rechteckigen Plot um jedes erkannte Gesicht.

Beginnen Sie, indem Sie eine neue Datei erstellen, die Ihren Code enthält:

nano app.py

Beginnen Sie in dieser neuen Datei mit dem Schreiben Ihres Codes, indem Sie zuerst die erforderlichen Bibliotheken importieren. Sie importieren hier zwei Module: + cv2 + und + sys +. Das + cv2 + - Modul importiert die + OpenCV + - Bibliothek in das Programm, und + sys + importiert allgemeine Python-Funktionen wie + argv +, die Ihr Code verwenden wird.

app.py

import cv2
import sys

Als Nächstes geben Sie an, dass das Eingabebild zur Laufzeit als Argument an das Skript übergeben wird. Die Pythonic-Methode zum Lesen des ersten Arguments besteht darin, den von der Funktion "+ sys.argv [1] +" zurückgegebenen Wert einer Variablen zuzuweisen:

app.py

...
imagePath = sys.argv[1]

In der Bildverarbeitung ist es üblich, das eingegebene Bild zunächst in Graustufen umzuwandeln. Dies liegt daran, dass das Erfassen der Leuchtdichte im Gegensatz zur Farbe im Allgemeinen bessere Ergebnisse bei der Objekterfassung liefert. Fügen Sie den folgenden Code hinzu, um ein Eingabebild als Argument zu verwenden und es in Graustufen umzuwandeln:

app.py

...
image = cv2.imread(imagePath)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

Die Funktion + .imread () + nimmt das Eingabebild, das als Argument an das Skript übergeben wird, und konvertiert es in ein OpenCV-Objekt. Als nächstes konvertiert die OpenCV-Funktion + .cvtColor () + das eingegebene Bildobjekt in ein Graustufenobjekt.

Nachdem Sie den Code zum Laden eines Bildes hinzugefügt haben, fügen Sie den Code hinzu, der Gesichter im angegebenen Bild erkennt:

app.py

...
faceCascade = cv2.CascadeClassifier(cv2.data.haarcascades + "haarcascade_frontalface_default.xml")
faces = faceCascade.detectMultiScale(
       gray,
       scaleFactor=1.3,
       minNeighbors=3,
       minSize=(30, 30)
)

print("Found {0} Faces!".format(len(faces)))

Dieser Code erstellt ein "+ faceCascade " - Objekt, das die Haar Cascade-Datei mit der " cv2.CascadeClassifier +" - Methode lädt. Dadurch können Python und Ihr Code die Haar Cascade verwenden.

Als nächstes wendet der Code die OpenCV-Methode "+ .detectMultiScale () " auf das " faceCascade " -Objekt an. Dies erzeugt eine _Liste von Rechtecken_ für alle erkannten Gesichter im Bild. Die Liste der Rechtecke ist eine Sammlung von Pixelpositionen aus dem Bild in Form von " Rect (x, y, w, h) +".

Hier ist eine Zusammenfassung der anderen Parameter, die Ihr Code verwendet:

  • + grau +: Dies gibt die Verwendung des OpenCV-Graustufenbildobjekts an, das Sie zuvor geladen haben.

  • + scaleFactor +: Dieser Parameter gibt die Rate an, mit der die Bildgröße bei jedem Bildmaßstab verringert wird. Ihr Modell hat während des Trainings einen festen Maßstab, sodass Eingabebilder zur besseren Erkennung verkleinert werden können. Dieser Vorgang stoppt nach Erreichen eines Schwellenwerts, der durch "+ maxSize " und " minSize +" definiert ist.

  • + minNeighbors +: Dieser Parameter gibt an, wie viele Nachbarn oder Erkennungen jedes Kandidatenrechteck behalten muss. Ein höherer Wert kann zu weniger Fehlalarmen führen, ein zu hoher Wert kann jedoch echte Positive eliminieren.

  • + minSize +: Hiermit können Sie die kleinstmögliche Objektgröße in Pixel festlegen. Objekte, die kleiner als dieser Parameter sind, werden ignoriert.

Nach dem Erzeugen einer Liste von Rechtecken werden die Flächen mit der Funktion "+ len +" gezählt. Die Anzahl der erkannten Gesichter wird nach dem Ausführen des Skripts als Ausgabe zurückgegeben.

Als Nächstes verwenden Sie die OpenCV-Methode "+ .rectangle () +", um ein Rechteck um die erkannten Gesichter zu zeichnen:

app.py

...
for (x, y, w, h) in faces:
   cv2.rectangle(image, (x, y), (x+w, y+h), (0, 255, 0), 2)

Dieser Code verwendet eine for-Schleife, um die Liste der Pixelpositionen zu durchlaufen, die von der faceCascade.detectMultiScale-Methode für jedes erkannte Objekt zurückgegeben wurden. Die Methode "+ Rectangle +" akzeptiert vier Argumente:

  • + Bild + weist den Code an, Rechtecke auf das ursprüngliche Eingabebild zu zeichnen.

  • + (x, y), (x + w, y + h) + sind die vier Pixelpositionen für das erkannte Objekt. + Rectangle + verwendet diese, um die erkannten Objekte im Eingabebild zu lokalisieren und Rechtecke zu zeichnen.

  • "+ (0, 255, 0) " ist die Farbe der Form. Dieses Argument wird als Tupel für BGR übergeben. Zum Beispiel würden Sie ` (255, 0, 0) +` für Blau verwenden. In diesem Fall verwenden wir grün.

  • "+ 2 +" ist die Dicke der Linie, gemessen in Pixeln.

Nachdem Sie den Code zum Zeichnen der Rechtecke hinzugefügt haben, verwenden Sie die OpenCV-Methode "+ .imwrite () ", um das neue Bild als " faces_detected.jpg " in Ihr lokales Dateisystem zu schreiben. Diese Methode gibt " true " zurück, wenn der Schreibvorgang erfolgreich war, und " false +", wenn das neue Image nicht geschrieben werden konnte.

app.py

...
status = cv2.imwrite('faces_detected.jpg', image)

Fügen Sie schließlich diesen Code hinzu, um den Rückgabestatus "+ true " oder " false " der Funktion " .imwrite () +" an der Konsole auszugeben. Dadurch erfahren Sie, ob der Schreibvorgang nach dem Ausführen des Skripts erfolgreich war.

app.py

...
print ("Image faces_detected.jpg written to filesystem: ",status)

Die fertige Datei sieht folgendermaßen aus:

app.py

import cv2
import sys

imagePath = sys.argv[1]

image = cv2.imread(imagePath)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

faceCascade = cv2.CascadeClassifier(cv2.data.haarcascades + "haarcascade_frontalface_default.xml")
faces = faceCascade.detectMultiScale(
   gray,
   scaleFactor=1.3,
   minNeighbors=3,
   minSize=(30, 30)
)

print("[INFO] Found {0} Faces!".format(len(faces)))

for (x, y, w, h) in faces:
   cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)

status = cv2.imwrite('faces_detected.jpg', image)
print("[INFO] Image faces_detected.jpg written to filesystem: ", status)

Speichern und schließen Sie die Datei, nachdem Sie überprüft haben, dass alles korrekt eingegeben wurde.

Ihr Code ist vollständig und Sie können das Skript ausführen.

Schritt 3 - Ausführen des Skripts

In diesem Schritt verwenden Sie ein Bild, um Ihr Skript zu testen. Wenn Sie ein Bild finden, das Sie zum Testen verwenden möchten, speichern Sie es im selben Verzeichnis wie Ihr Skript "+ app.py +". In diesem Tutorial wird das folgende Bild verwendet:

image: https://assets.digitalocean.com/articles/CART-63965/people_with_phones.png [Eingabebild von vier Personen, die Telefone betrachten]

Wenn Sie mit demselben Image testen möchten, verwenden Sie den folgenden Befehl, um es herunterzuladen:

curl -O https://assets.digitalocean.com/articles/CART-63965/people_with_phones.png

Wenn Sie ein Image zum Testen des Skripts haben, führen Sie das Script aus und geben Sie den Image-Pfad als Argument an:

python app.py

Sobald das Skript ausgeführt wurde, erhalten Sie folgende Ausgabe:

Output[INFO] Found 4 Faces!
[INFO] Image faces_detected.jpg written to filesystem:

Die Ausgabe + true + zeigt an, dass das aktualisierte Image erfolgreich in das Dateisystem geschrieben wurde. Öffnen Sie das Image auf Ihrem lokalen Computer, um die Änderungen in der neuen Datei anzuzeigen:

Sie sollten sehen, dass Ihr Skript vier Gesichter im Eingabebild erkannt und Rechtecke gezeichnet hat, um sie zu markieren. Im nächsten Schritt werden Sie die Pixelpositionen verwenden, um Gesichter aus dem Bild zu extrahieren.

Schritt 4 - Gesichter extrahieren und lokal speichern (optional)

Im vorherigen Schritt haben Sie Code geschrieben, um OpenCV und eine Haar-Kaskade zum Erkennen und Zeichnen von Rechtecken um Gesichter in einem Bild zu verwenden. In diesem Abschnitt ändern Sie Ihren Code, um die erkannten Gesichter aus dem Bild in eigene Dateien zu extrahieren.

Öffnen Sie zunächst die Datei "+ app.py +" mit Ihrem Texteditor:

nano app.py

Fügen Sie als nächstes die markierten Zeilen unter der Zeile + cv2.rectangle + hinzu:

app.py

...
for (x, y, w, h) in faces:
   cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)



...

Das Objekt "+ roi_color " zeichnet die Pixelpositionen aus der Liste " faces " auf dem ursprünglichen Eingabebild. Die Variablen ` x `, ` y `, ` h ` und ` w ` sind die Pixelpositionen für jedes der Objekte, die mit der Methode ` faceCascade.detectMultiScale +` ermittelt wurden. Der Code gibt dann eine Ausgabe aus, die besagt, dass ein Objekt gefunden wurde und lokal gespeichert wird.

Sobald dies erledigt ist, speichert der Code die Zeichnung als neues Bild mit der Methode + cv2.imwrite +. Die Breite und Höhe des Plots werden an den Namen des Bildes angehängt, in das geschrieben wird. Dadurch bleibt der Name eindeutig, falls mehrere Gesichter erkannt werden.

Das aktualisierte Skript + app.py + sieht folgendermaßen aus:

app.py

import cv2
import sys

imagePath = sys.argv[1]

image = cv2.imread(imagePath)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

faceCascade = cv2.CascadeClassifier(cv2.data.haarcascades + "haarcascade_frontalface_default.xml")
faces = faceCascade.detectMultiScale(
   gray,
   scaleFactor=1.3,
   minNeighbors=3,
   minSize=(30, 30)
)

print("[INFO] Found {0} Faces.".format(len(faces)))

for (x, y, w, h) in faces:
   cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)
   roi_color = image[y:y + h, x:x + w]
   print("[INFO] Object found. Saving locally.")
   cv2.imwrite(str(w) + str(h) + '_faces.jpg', roi_color)

status = cv2.imwrite('faces_detected.jpg', image)
print("[INFO] Image faces_detected.jpg written to filesystem: ", status)

Zusammenfassend verwendet der aktualisierte Code die Pixelpositionen, um die Gesichter aus dem Bild in eine neue Datei zu extrahieren. Speichern und schließen Sie die Datei, nachdem Sie den Code aktualisiert haben.

Nachdem Sie den Code aktualisiert haben, können Sie das Skript erneut ausführen:

python app.py

Sie werden die ähnliche Ausgabe sehen, sobald Ihr Skript das Bild verarbeitet hat:

Output[INFO] Found 4 Faces.
[INFO] Object found. Saving locally.
[INFO] Object found. Saving locally.
[INFO] Object found. Saving locally.
[INFO] Object found. Saving locally.
[INFO] Image faces_detected.jpg written to file-system:

Je nachdem, wie viele Gesichter in Ihrem Beispielbild enthalten sind, wird möglicherweise mehr oder weniger ausgegeben.

Wenn Sie sich den Inhalt des Arbeitsverzeichnisses nach der Ausführung des Skripts ansehen, werden Dateien mit den Kopfschüssen aller im Eingabebild gefundenen Gesichter angezeigt.

Sie werden jetzt Kopfschüsse sehen, die aus dem im Arbeitsverzeichnis gesammelten Eingabebild extrahiert wurden:

In diesem Schritt haben Sie Ihr Skript so geändert, dass die erkannten Objekte aus dem Eingabebild extrahiert und lokal gespeichert werden.

Fazit

In diesem Tutorial haben Sie ein Skript geschrieben, das OpenCV und Python zum Erkennen, Zählen und Extrahieren von Gesichtern aus einem Eingabebild verwendet. Sie können dieses Skript aktualisieren, um verschiedene Objekte zu erkennen, indem Sie eine andere vorab trainierte Haar Cascade aus der OpenCV-Bibliothek verwenden, oder Sie lernen, wie Sie https://docs.opencv.org/3.3.0/dc/d88/tutorial_traincascade.html [Trainiere dein eigenes] Haar Cascade.