Azure Data Factory – was der neue Azure-Service kann und welche Vorteile er bietet. Azure Data Factory... » weiterlesen
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:
- Face API Subscription
- Personen anlegen und Face API auf Bilder dieser Personen trainieren
- Gesicht im Bild lokalisieren
- Person im lokalisierten Gesicht auf Basis der trainierten Bilder erkennen
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.
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:
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.
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:
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,
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.
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.
Parameter
Als Kommandozeilenparameter wird der Dateiname eines Bildes angegeben.
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.
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
Weitere Technologie Beiträge
Lesen Sie sich hier weitere Blogbeiträge zum Thema Technologie.