Nachdem wir im letzten Kapitel ein ganz simples eigenes KNN mit Python programmiert haben, möchten wir jetzt mit einer vorhandenen Bibliothek eine echte Anwendung programmieren. Wir verwenden OpenCV und werden eine Gesichtserkennung (im Sinn von face detection programmieren. (Gesichter einer Person zuordnen ist etwas komplizierter, hier spricht man von face recognition.)
Der Code dieses Kapitels basiert mit Modifikationen auf einem Artikel von Nagesh Singh Chauhan (opens new window)
# Gesichtserkennung mit OpenCV
OpenCV liefert alles was wir benötigen um in Bildern menschliche Gesichter zu erkennen. Wir werden den «Haar»-Klassifikator verwenden, um Gesichter zu erkennen. OpenCV bietet bereits trainierte Daten in Form von xml-Dateien zur Verfügung.
# Vorbereitung
- Projekt-Verzeichnis anlegen
- Bilder sammeln
- 2-3 Bilder im Projekt-Verzeichnis abspeichern
- mit einem oder mehreren Gesichtern, 1x ohne Gesicht
- Dateiendung
jpg
- Bibliotheken installieren
- Thonny starten
- Packages installieren:
numpy
,matplotlib
,opencv-python
# Python-Code
import cv2
import numpy as np
from matplotlib import pyplot as plt
import glob
COLOR_FACE = (255, 0, 255) # Farbe für Rahmen ums Gesicht
image_files = glob.glob("*.jpg") # Alle jpg-Dateien im aktuellen Verzeichnis in Liste speichern
# Für jedes Bild Gesichtserkennung machen
for file in image_files:
img_bgr = cv2.imread(file, cv2.IMREAD_COLOR) # Die Bilddatei farbig einlesen
b,g,r = cv2.split(img_bgr) # Die Farbwerte auslesen (cv2 erstellt BGR-Bild)
img_rgb = cv2.merge([r,g,b]) # Aus den BGR-Farbwerten ein RGB-Bild machen
img_gray = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2GRAY) # Ein Graustufenbild für die Erkennung machen
# Gesichts-Klassifikatoren aus Datei laden
# (im Python-Modul sind die Standard-xml-Dateien bereits enthalten)
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + "haarcascade_frontalface_default.xml")
# eigentliche Gesichtserkennung ausführen
faces = face_cascade.detectMultiScale(img_gray, scaleFactor=1.2, minNeighbors=5)
print("Anzahl erkannte Gesichter:", len(faces)) # Anzahl erkannte Gesichter ausgeben
# Erkannte Gesichter durchgehen.
# Die erkannten Gesichter werden durch ein umrahmendes Redchteck gegebn:
# (x, y, w, h) stellen Koordinaten, Breite und Höhe des Rechtecks dar
for (x, y, w, h) in faces:
# das Gesicht durch ein farbiges Rechteck im Bild markieren
cv2.rectangle(img_rgb, (x, y), (x+w, y+h), COLOR_FACE, 2)
plt.axis('off') # Diagramm-Achsen ausblenden
plt.imshow(img_rgb) # Dem Diagramm das Bild hinzufügen
plt.title(file) # Titel des Diagramms setzen
plt.show() # Diagramm anzeigen
exit()
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
Aufgabe
- Lies den obenstehenden Python-Code und alle Kommentare durch.
- Kopiere den Code in dein Projektverzeichnis und führe ihn aus.
- Versuche den Code zu optimieren, indem du mit den Werten
scaleFactor
undminNeighbors
in der MethodedetectMultiScale
spielst. Versuche zu verstehen was diese Parameter machen. Lies dazu auch die beiden verlinkten stackoverflow-Beiträge durch.
# Augen erkennen
Für erkannte Gesichter können wir nun auch die Augen erkennen. Das Prinzip ist das selbe wie bei der Gesichtserkennung. Wir gehen wie folgt vor:
- Wir erstellen einen neuen Klassifikator für die Augen. Die Trainingsdaten finden wir in der Datei
haarcascade_eye.xml
. - Für jedes erkannte Gesicht erstellen wir ein neues Bild, welches nur das Gesicht beinhaltet.
- Auf diesem Bild führen wir die Augenerkennung durch.
- Wir markieren im Gesamtbild die erkannten Augen durch einen farbigen Rahmen.
Hinweis
Die in OpenCV geladenen Bilder sind zweidimensionale Listen. Wir können mit der Range-Auswahl von Python ein Rechteckiges Bild aus einem grösseren Bild ausschneiden.
Das folgende Beispiel schneidet im Bild img
ein Rechteck an den Koordinaten (x,y)
mit einer Breite w
und einer Höhe h
aus und speichert das ausgeschnittene Bild in einem neuen Array face
.
img = cv2.imread("testbild.jpg", cv2.IMREAD_COLOR)
face = img[y:y+h, x:x+w]
2
Aufgabe
Speichere deine Python-Datei unter einem neuen Dateinamen ab und füge der Gesichtserkennung eine Augenerkennung hinzu. Gehe dabei gemäss den 4 oben besprochenen Schritten vor. Versuche wiederum die Erkennung zu optimieren.
Zusatzaufgabe «Make-Up»
Füge den Augen Make-Up hinzu, indem du um die Augen herum etwas Farbe aufträgst. OpenCV-Zeichenbefehle (opens new window)
Zusatzaufgabe «Zensur»
Baue eine automatische Zensur. Du kannst eine oder beide Zensurvarianten umsetzen:
- Variante A
- Finde alle Gesichter und «verpixele» sie oder wende einen «Weichzeichner» an.
cv2.blur()
- Variante B
- Verbinde die beiden Augen eines Gesichtes mit einem schwarzen Balken, also einem sogenannten Zensurbalken.
Zusatzaufgabe «Der Blick»
- Variante A
- Finde Augen und spiegle diese horizontal.
cv2.flip()
- Variante B
- Finde ein Gesicht mit zwei Augen. Vertausche die beiden Augen!
# andere Dinge erkennen
Im Repo von OpenCV finden wir weitere Trainingsdaten für den Haar-Klassifikator: https://github.com/opencv/opencv/tree/master/data/haarcascades (opens new window). Einige Mögliche Anwendungsbeispiele:
haarcascade_fullbody.xml
– Fussgänger erkennen für ein selbstfahrendes Autohaarcascade_smile.xml
– Bei Gesichtern ein Lächeln erkennen, z.b. für eine Kamera die erst auslöst wenn alle Personen lächeln.haarcascade_profileface.xml
– hinzufügen zu unserer Gesichtserkennung um auch Personen von der Seite her zu erkennen.
Aufgabe
Wähle einen der im Repo verfügbaren Haar-Klassifikator aus und versuche damit eine Anwendung zu erstellen:
- passende Bilder sammeln
- das Python-Skript mit den neuen Trainingsdaten ausstatten
- Die Objekt-Erkennung testen und optimieren
- Etwas «sinnvolles» mit den erkannten Objekten anstellen