Gesichtserkennung mit Microsoft Face API

Gesichtserkennung mit Microsoft Face API: Zeig mir dein Gesicht – und die Maschine sagt dir wer du bist.

Es hat einen Hauch von Science-Fiction-Technologie, wenn ein Computer ein Gesicht erkennt und alle möglichen Merkmale wie Alter, Geschlecht, Emotionen, aber auch den Namen der Person ausgibt. Solche Möglichkeiten, die bis vor kurzem nur von Technologiegiganten wie Apple und Google in ihren Fotodiensten eingesetzt wurden, sind inzwischen für eigene Anwendungen nur mehr einen Servicecall entfernt. Hier kommt auch die Gesichtserkennung mit Microsoft Face API ins Spiel.

Doch wofür kann diese neue Technologie verwendet werden?

Anwendungsfälle für Gesichtserkennung:

Gesichtserkennung wird bereits heute für folgende Bereiche eingesetzt:

  • Fahndung nach gesuchten Personen auf öffentlichen Plätzen
  • Aufzeichnung von Personen ohne Visa auf Flughäfen
  • Einkaufen ohne Kasse (Amazon Go)
  • Personenzuordnung auf Bildern/Videos (Social Media)
  • Zugangskontrollen (Tür, Smartphone)

Darüber hinaus gibt es natürlich viele weitere Anwendungsmöglichkeiten. Dabei müssen jedoch immer die gesetzlichen Rahmenbedingungen beachtet werden, um Persönlichkeitsrechte nicht zu verletzen.

Gesichtserkennung mit Microsoft Face API

In diesem Artikel wird die Microsoft Face API vorgestellt. Das beinhaltet Gesichter auf Fotos zu lokalisieren und zu bestimmten Personen zu trainieren, um diese schlussendlich zu erkennen. Abschließend wird eine Applikation vorgestellt, die von einer Webcam Videodaten liest und diese durch die Microsoft Face API analysieren lässt.

Die Microsoft Face API ist ein Cloud-Service, der die Lokalisierung und Identifizierung von Gesichtern in Bildern oder Videos ermöglicht.

Die Face API bietet folgende Funktionen:

  • Gesichtserkennung: Lokalisierung menschlicher Gesichter in einem Bild mit den Positionen der Gesichter sowie Attribute wie Alter, Geschlecht, Emotion, Haare, Brille etc.
  • Gesichtsbestimmung: Erkennung von zuvor trainierten Personen auf neuen Bildern
  • Suche nach ähnlichen Gesichtern: aus einer Sammlung von Bildern ähnliche zu einem neuen Bild suchen
  • Gesichtsgruppierung: eine Menge von Bildern in zusammengehörige Gruppen von Gesichtern gruppieren

https://azure.microsoft.com/de-de/services/cognitive-services/face/, 2018-02-19

Die FaceAPI stellt REST-Services zur Verfügung, die von sämtlichen Plattformen und Sprachen einfach angesprochen werden können. Dokumentation dazu findet man z.B. hier. Eine genaue Beschreibung der Services (API Reference) beziehungsweise jeder angebotenen Funktion findet man hier.

Glücklicherweise gibt es aber auch Client-Libraries sowie Beispiel-Projekte für die folgenden Umgebungen:

  • .net
  • Android (Java)
  • iOS
  • Python

https://docs.microsoft.com/en-us/azure/cognitive-services/face/, 2018-02-19

Diese (abstrakten) Schritte bedarf es, um ein Gesicht mittels Face API in einem Bild zu identifizieren:

  1. Face API Subscription
  2. Personen anlegen und Face API auf Bilder dieser Personen trainieren
  3. Gesicht im Bild lokalisieren
  4. Person im lokalisierten Gesicht auf Basis der trainierten Bilder erkennen

https://docs.microsoft.com/en-us/azure/cognitive-services/face/QuickStarts/client-libraries?tabs=visual-studio&pivots=programming-language-csharp, 2018-02-19

Die folgenden Abschnitte demonstrieren, wie die Face API eingesetzt werden kann, um diese Schritte durchzuführen.

1. Microsoft Face API Subscription

Im Azure-Portal wird eine neue Ressource vom Typ Gesichtserkennungs-API (Face API) erstellt.

Ressource vom Typ Gesichtserkennungs-API (Face API) im Azure-Portal erstellen

Nach dem Eingeben der Werte für Namen, Standort, Tarif und gegebenenfalls der Ressourcengruppe, wird das Service angelegt. F0 wäre der Gratis-Tarif, im folgenden Screenshot stand dieser jedoch nicht mehr zur Verfügung, daher beim Ausprobieren – sofern keine Kosten anlaufen sollen – auf F0 statt S0 ändern.

Wenn man danach in die Verwaltung der neu angelegten Face API wechselt, so sind vor allem die folgenden zwei Punkte wichtig:

  • URL des Endpunktes
  • Access Key

Auf der Überblick-Seite findet man die benötigten Informationen an dieser Stelle:

Überblicks-Seite

Access Key

2.     Lokalisieren eines Gesichts in einem Bild für Gesichtserkennung mit Microsoft Face API

Das Beispiel hier ist eine Konsolen-Anwendung in C#, die eine Bilddatei liest, an die FaceAPI sendet und eine Datei speichert, in der das vom Service gefundene Gesicht gekennzeichnet wird. Zusätzlich werden erkannte Attribute wie Geschlecht, Alter, Emotionen etc. ausgegeben.

Neues Projekt

Erstellung eines neuen Projekts vom Typ C# Konsolenanwendung.

Packages

Im NuGet Package Manager wird das Paket Microsoft.ProjectOxford.Face inklusive Abhängigkeiten hinzugefügt.

Paket Microsoft.ProjectOxford.Face hinzufügen

Code

Die main() – Funktion benötigt den folgenden Code:

static void Main(string[] args)

{

var faceServiceClient = new FaceServiceClient("***MYKEY***", "https://westcentralus.api.cognitive.microsoft.com/face/v1.0");

var stream = new MemoryStream(File.ReadAllBytes(args[0]));

IEnumerable<FaceAttributeType> faceAttributes =

new FaceAttributeType[] { FaceAttributeType.Gender, FaceAttributeType.Age, FaceAttributeType.Smile, FaceAttributeType.Emotion, FaceAttributeType.Glasses, FaceAttributeType.Hair };

Face[] faces = faceServiceClient.DetectAsync(stream, returnFaceId: true, returnFaceLandmarks: false, returnFaceAttributes: faceAttributes).Result;

var face = faces[0];

Console.WriteLine(GetFaceDescription(face));

Bitmap img = new Bitmap(args[0]);

using (var graphics = Graphics.FromImage(img))

{

Pen pen = new Pen(Color.PaleVioletRed, 5);

var x = face.FaceRectangle.Left;

var width = face.FaceRectangle.Width;

var y = face.FaceRectangle.Top;

var height = face.FaceRectangle.Height;

graphics.DrawRectangle(pen, x, y, width, height);

img.Save(@"D:\temp\face.jpg", ImageFormat.Jpeg);

}

Console.ReadLine();

}

Bild

Dabei handelt es sich um dieses Bild:

Bild für Gesichtserkennung mit Microsoft Face API

Gesicht lokalisieren

Zu Beginn wird ein FaceServiceClient mit der URL und dem Key aus dem Azure-Portal erstellt.

Die Zeile

Face[] faces = faceServiceClient.DetectAsync(…).Result;

sendet die zuvor gelesene Datei an die Face API. Als Parameter angegeben wird noch, dass FaceIds, eindeutige Nummern eines Gesichtes für das Service für spätere Verwendung, sowie die in der zuvor erstellten Liste angegebenen Gesichtsttribute wie Geschlecht, Alter etc. zurückgegeben werden sollen. FaceLandmarks, die Information wo bestimmte Merkmale im Gesicht gefunden wurden (right_eyebrow_upper_middle, mouth_upper_lip_left_contour2, mouth_right_corner usw.) werden hier nicht benötigt und abgefragt.

Aus den erkannten Gesichtern wird zur weiteren Verarbeitung nur das erste herangezogen.

Von diesem erkannten Gesicht werden die zurückgelieferten Attribute ausgegeben – die Funktion dazu wurde aus dem Sample der Face API Dokumentation  (2018-02-19) verwendet.

private static string GetFaceDescription(Face face)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("Face: ");
            sb.Append(face.FaceAttributes.Gender);
            sb.Append(", ");
            sb.Append(face.FaceAttributes.Age);
            sb.Append(", ");
            sb.Append(String.Format("smile {0:F1}%, ", face.FaceAttributes.Smile * 100));
            sb.Append("Emotion: ");
            EmotionScores emotionScores = face.FaceAttributes.Emotion;
            if (emotionScores.Anger >= 0.1f) sb.Append(String.Format("anger {0:F1}%, ", emotionScores.Anger * 100));
            if (emotionScores.Contempt >= 0.1f) sb.Append(String.Format("contempt {0:F1}%, ", emotionScores.Contempt * 100));
            if (emotionScores.Disgust >= 0.1f) sb.Append(String.Format("disgust {0:F1}%, ", emotionScores.Disgust * 100));
            if (emotionScores.Fear >= 0.1f) sb.Append(String.Format("fear {0:F1}%, ", emotionScores.Fear * 100));
            if (emotionScores.Happiness >= 0.1f) sb.Append(String.Format("happiness {0:F1}%, ", emotionScores.Happiness * 100));
            if (emotionScores.Neutral >= 0.1f) sb.Append(String.Format("neutral {0:F1}%, ", emotionScores.Neutral * 100));
            if (emotionScores.Sadness >= 0.1f) sb.Append(String.Format("sadness {0:F1}%, ", emotionScores.Sadness * 100));
            if (emotionScores.Surprise >= 0.1f) sb.Append(String.Format("surprise {0:F1}%, ", emotionScores.Surprise * 100));
            sb.Append(face.FaceAttributes.Glasses);
            sb.Append(", ");
            sb.Append("Hair: ");
            if (face.FaceAttributes.Hair.Bald >= 0.01f)
                sb.Append(String.Format("bald {0:F1}% ", face.FaceAttributes.Hair.Bald * 100));
            HairColor[] hairColors = face.FaceAttributes.Hair.HairColor;
            foreach (HairColor hairColor in hairColors)
            {
                if (hairColor.Confidence >= 0.1f)
                {
                    sb.Append(hairColor.Color.ToString());
                    sb.Append(String.Format(" {0:F1}% ", hairColor.Confidence * 100));
                }
            }
            return sb.ToString();
        }

Gesicht kennzeichnen

Nach der Ausgabe der Gesichtsattribute erfolgt noch eine Kennzeichnung des gefundenen Gesichts im Bild. Die Kennzeichnung ist eine Box um den Bereich des Gesichts.

Dazu lädt man das Bild in ein Bitmap, zeichnet mit graphics.DrawRectangle ein Rechteck in das Bild auf die Koordinaten des Gefundenen Gesichts und speichert dann mittels img.Save().

Ergebnis

Mit dem oben angegebenen Bild erhält man nun das folgende Bild,

Rechteck auf Bild für Gesichtserkennung mit Microsoft Face API

sowie die folgenden Attribute des Gesichts:

Face: female, 3,2, smile 100,0%, Emotion: happiness 100,0%, NoGlasses, Hair: bald 1,0% Brown: 100,0% Black 75,0% Red 15,0% Blond 13,0% Other 13,0%

3. Gesichter zu Personen zuordnen und trainieren

Der nächste Schritt zur Gesichtserkennung ist es in der Face API Personen anzulegen, diesen Bilder von Gesichtern zuzuordnen und die Face API darauf zu trainieren.

Zu diesem Zweck erstellt man eine neue Konsolen-Anwendung, die als Kommandozeilenparameter einen Namen und ein Bild bekommt und diese Informationen zum Training an die Face API sendet.

Neues Projekt

Erstellung eines neuen Projekts vom Typ C# Konsolenanwendung.

Packages

Im NuGet Package Manager wird das Paket Microsoft.ProjectOxford.Face inklusive Abhängigkeiten hinzugefügt.

Paket Microsoft.ProjectOxford.Face hinzufügen

Code

Die main() – Funktion benötigt den folgenden Code:

static void Main(string[] args)
        {
            string groupName = "dataformers2";
            var name = args[0];
            var stream = new MemoryStream(File.ReadAllBytes(args[1]));
            var client = new FaceServiceClient("***MYKEY***", "https://westcentralus.api.cognitive.microsoft.com/face/v1.0");
            var groups = client.ListPersonGroupsAsync().Result;
            if (!groups.Any(g => g.Name == groupName))
            {
                client.CreatePersonGroupAsync(groupName, groupName).Wait();
            }
            Guid personId;
            var people = client.ListPersonsAsync(groupName).Result;
            Person person;
            if (!people.Any(p => p.Name.ToLower() == name.ToLower()))
            {         
                personId = client.CreatePersonAsync(groupName, name).Result.PersonId;
            }
            else
            {
                person = people.First(p => p.Name.ToLower() == name.ToLower());
                if (person.PersistedFaceIds.Length > 0)
                {
                    client.DeletePersonFaceAsync(groupName, person.PersonId, person.PersistedFaceIds[0]).Wait();
                }
                personId = person.PersonId;
            }
            client.AddPersonFaceAsync(groupName, personId, stream).Wait();
            TrainingStatus trainingStatus;
            client.TrainPersonGroupAsync(groupName).Wait();
            while (true)
            {
                trainingStatus = client.GetPersonGroupTrainingStatusAsync(groupName).Result;
                if (trainingStatus.Status != Microsoft.ProjectOxford.Face.Contract.Status.Running) break;
                Thread.Sleep(5000);
            }
            Console.WriteLine($"training complete: {trainingStatus.Status.ToString()}");
            Console.ReadKey();
        }

(Sample von hier, 2018-02-02)

Zuerst definiert man den Namen der Personengruppe, dann liest man die Kommandozeilenparameter für Name und Datei aus und liest das angegebene Bild in einen Stream ein.

Personengruppe

Die Personengruppe ist der Container für mehrere Personen, deren Gesichter erkannt werden sollen. Das sind z.B. das Team, eine Firma, Kunden einer Filiale, eine Familie oder ähnliches. Diese Gruppe wird dann beim Abspeichern der Bilder, beim Trainieren und beim Erkennen der Gesichter auf neuen Bildern verwendet.

Mit ListPersonGroupsAsync() werden alle Personengruppen abgerufen. Falls die gewünschte Gruppe noch nicht existiert, legt CreatePersonGroupAsync() diese an.

Person

Das selbe wird nun für die Person durchgeführt. ListPersonsAsync() fragt die Personen ab und CreatePersonAsync() legt die Personen an, falls die gewünschte nicht existiert. Sollte die Person gefunden und dieser ein Gesicht zugeordnet worden sein, so wird das vorhandene, alte Bild gelöscht.

Hinzufügen eines Bildes

Die Funktion AddPersonFaceAsync() lädt zu einer Person in einer Personengruppe ein Bild zum Trainieren der Gesichtserkennung hoch.

Trainieren

Durch den Aufruf von TrainPersonGroupAsync() wird die Face API auf die neue Person und deren Bilder von Gesichtern trainiert.

Ergebnis

Ab jetzt sollte die Face API in der Lage sein auf neuen Bildern die zuvor trainierte Person zu erkennen.

4. Personen auf Bildern identifizieren – Gesichtserkennung

Nachdem man die Face API auf eine Personengruppe trainiert hat, kann man ab jetzt Anfragen mit neuen Bildern gegen den Service durchführen, um bereits bekannte Personen auf Bildern zu identifizieren.

Dazu sind die folgenden Schritte notwendig:

  • Lokalisieren des Gesichts
  • Ermitteln der FaceIDs aus dem ersten Schritt
  • Gesichter zu FaceIDs erkennen (identify)
  • PersonIDs auslesen
  • Personen abfragen

Man erstellt eine neue C#-Kommandozeilenapplikation, die als Parameter einen Dateinamen erhält. Diese versucht dann die Erkennung der Gesichter im angegeben Bild mittels Face API und die Ausgabe der dazugehörigen Namen der Personen.

Neues Projekt 
Man erstellt ein neues Projekt vom Typ C# Konsolenanwendung.

Packages
Im NuGet Package Manager wird das Paket Microsoft.ProjectOxford.Face inklusive Abhängigkeiten hinzugefügt.

Paket Microsoft.ProjectOxford.Face hinzufügen

Parameter
Als Kommandozeilenparameter wird der Dateiname eines Bildes angegeben.

Kommandozeilenparameter angeben

Code

Die main() – Funktion umfasst den folgenden Code:

static void Main(string[] args)
        {
            var stream = new MemoryStream(File.ReadAllBytes(args[0]));
var client = new FaceServiceClient("***mykey***", "https://westcentralus.api.cognitive.microsoft.com/face/v1.0");
            var faces = client.DetectAsync(stream, returnFaceId: true).Result;
            var faceIds = faces.Select(f => f.FaceId).ToArray();
            var people = client.IdentifyAsync(group, faceIds).Result;
            foreach(var p in people)
            {
                var person = client.GetPersonAsync(group, p.Candidates[0].PersonId).Result;
                Console.WriteLine(person.Name);
            }
            Console.ReadLine();      
        }

Die Funktion DetectAsync()  ermittelt Gesichter im angegebenen Bild und gibt deren Positionen und FaceIds zurück.

Die Funktion IdentifyAsync() ermittelt aus der angegebenen Personengruppe die Personen, die zu den Gesichtern mit den gegebenen FaceIds gefunden wurden.

GetPersonAsync() sucht die Personen über die IDs der identifizierten Kandidaten und gibt deren Namen aus.

Ergebnis

Unter der Annahme, dass das Bild im vorigen Artikel bereits trainiert wurde, sollte der Aufruf der Erkennungs-Applikation mit diesem Bild, den Namen der gewünschten Person zurückgeben.

Bild für Aufruf der Erkennungs-Applikation

Code für Aufruf der Erkennungs-Applikation

Erweiterung: Microsoft Face API in Python

Hier gibt es ein Sample für die Lokalisierung eines Gesichtes mittels Face API in Python. Das Beispiel lädt ein Bild von einer URL, ermittelt die Position des Gesichts im Bild, markiert dieses und zeigt das neue Bild als Ergebnis an.

Das folgende Beispiel identifiziert eine der Face API bereits bekannte Person (zuvor trainiert) auf einem Bild:

Die Voraussetzungen (Python, Subscription, SDK etc.) gelten aus dem oben erwähnten Artikel.

Code

import cognitive_face as CF

CF.Key.set('***mykey***')
CF.BaseUrl.set('https://westcentralus.api.cognitive.microsoft.com/face/v1.0/')
group = 'dataformers'
file="C:\\Users\\wm\\Pictures\\diana.jpg"

faces=CF.face.detect(file, True, True)
faceIds = [f['faceId'] for f in faces]
persons=CF.face.identify(faceIds, group)

for p in persons:
 
personId = p['candidates'][0]['personId']
person = CF.person.get(group, personId)
print(person)

Ergebnis

Code-Ergebnis der Gesichtserkennung mit Microsoft Face API

 

Weitere Technologie Beiträge

Lesen Sie sich hier weitere Blogbeiträge zum Thema Technologie.

Weitere Beiträge
crosschevron-left
Datenschutzinformation
Der datenschutzrechtliche Verantwortliche (dataformers GmbH, Österreich) würde gerne mit folgenden Diensten Ihre personenbezogenen Daten verarbeiten. Zur Personalisierung können Technologien wie Cookies, LocalStorage usw. verwendet werden. Dies ist für die Nutzung der Website nicht notwendig, ermöglicht aber eine noch engere Interaktion mit Ihnen. Falls gewünscht, treffen Sie bitte eine Auswahl: