Freigeben über



November 2016

Band 31, Nummer 11

Dieser Artikel wurde maschinell übersetzt.

Moderne Apps: Hinzufügen von Gesichtserkennungsfunktionen zu Ihrer App

Durch Frank La La

Frank La VigneAuf der Build 2016 kündigte Microsoft die Version der kognitive Services-API. Sind Sie mehrere Computer Vision Dienste zwischen vielen APIs verfügbar. Diese Dienste können Alter und Geschlecht der Flächen in einem Bild und Eingabe analysieren. Es gibt sogar eine API zum Erkennen von Personen Emotionen basierend auf deren Gesichtsausdrücke. Markieren Sie die Technologie, gab es zahlreiche Kioske im gesamten Ereignis veranschaulicht verschiedene Verwendungen der Technologie. Die kognitive-API nutzt Microsoft Erfahrung und Maßnahmen im Bereich maschinelles lernen. Tausende von bezeichneten Bilder wurden über ein neuronales Netzwerk eingelesen. Darüber hinaus können Sie diese Dienste ohne Kenntnis der Machine Learning oder künstliche Intelligenz nutzen. Sie rufen einfach einen Webdienst über Ihre app. Sehen Sie ein Interview mit einem der Teammitglieder, die Weitere Informationen zu den Prozess auf dem Projekt mitarbeiten bit.ly/1TGi1QK

Kognitive Services-APIs können Sie grundlegende Gesichtsausdruck Erkennung für Ihre Anwendung hinzufügen, ohne APIs aufrufen. Der Windows.Media.FaceAnalysis-Namespace enthält Funktionen zum Erkennen von Flächen in Bilder oder Videos. Der Featuresatz ist ein einfaches und verfügt nicht über die umfangreichen Daten kognitive Services. In der Tat ist es sehr ähnlich Gesichtsausdruck Erkennung in vielen Digitalkameras gefunden. Während der grundlegenden werden, verfügen sie über zwei entscheidende Vorteile: Sie offline arbeiten und, da Sie keine API aufrufen, wird nicht fallen keine Kosten. Ihre app kann als eine Optimierungsstrategie das Vorhandensein einer Fläche erkennen, lokal, bevor Sie die kognitive-API aufrufen. Auf diese Weise wird nicht die app Bilder ohne Flächen der kognitive Services-API senden. Die können erhebliche Kosten einsparen für Sie und weniger Bandbreite für Ihre Benutzer beanspruchen. Erkennen von Flächen lokal können eine nützliche Ergänzung intelligent Clouddienste wie kognitive Services sein.

Einrichten des Projekts

Klicken Sie in Visual Studio 2015 erstellen ein neue universelle Windows-Plattform (UWP)-app-Projekt, wählen Sie die leere Vorlage, und nennen Sie sie FaceDetection. Da die Anwendung die Webcam verwendet wird, müssen Sie die entsprechende Funktion der App hinzufügen. Doppelklicken Sie im Projektmappen-Explorer auf die Datei „Package.appxmanifest“. Überprüfen Sie auf der Registerkarte Funktionen die Kontrollkästchen neben Webcam und Mikrofon Siehe Abbildung 1. Speichern Sie die Datei.

Hinzufügen von Webcam und Mikrofon Funktionen zur App
Abbildung 1 der App Webcam und Mikrofon Funktionen hinzugefügt

Fügen Sie jetzt den folgenden XAML-CODE in die Datei "MainPage.xaml" zum Erstellen der Benutzeroberfläche:

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
  <Grid.RowDefinitions>
    <RowDefinition Height="320*"/>
    <RowDefinition Height="389*"/>
  </Grid.RowDefinitions>
  <CaptureElement Name="cePreview" Stretch="Uniform" Grid.Row="0" />
  <Canvas x:Name="cvsFaceOverlay" Grid.Row="0" ></Canvas>
  <StackPanel Grid.Row="1" HorizontalAlignment="Center" Margin="5">
    <Button x:Name="btnCamera" Click="btnCamera_Click" >Turn on Camera</Button>
    <Button x:Name="btnDetectFaces" Click="btnDetectFaces_Click" >Detect
      Faces</Button>
  </StackPanel>
</Grid>

Sie können nicht mit dem Steuerelement CaptureElement vertraut sein. Das CaptureElement-Steuerelement rendert einen Datenstrom von einem Gerät angeschlossenen erfassen, in der Regel eine Kamera oder Webcam. Die MediaCapture-API verwenden Sie im Code-Behind einen Stream aus der Webcam hergestellt werden.

Anzeigen einer Vorschau der Videos von der Kamera

Fügen Sie in der Datei "MainPage.Xaml.cs" die folgenden Namespaces hinzu:

using Windows.Media.Capture;
using Windows.Media.Core;
using Windows.Media.FaceAnalysis;

Fügen Sie die beiden folgenden Member der MainPage-Klasse:

private FaceDetectionEffect _faceDetectionEffect;
private MediaCapture _mediaCapture;
private IMediaEncodingProperties _previewProperties;

Fügen Sie jetzt den folgenden Ereignishandler für die Schaltfläche Kamera starten:

private async void btnCamera_Click(object sender, RoutedEventArgs e)
  {
    _mediaCapture = new MediaCapture();
    await _mediaCapture.InitializeAsync();
    cePreview.Source = _mediaCapture;
    await _mediaCapture.StartPreviewAsync();
  }

Führen Sie das Projekt, und klicken Sie dann auf die Schaltfläche Kamera starten. Jetzt sollten Sie die Ausgabe der Webcam in der app angezeigt. Wenn Sie eine Webcam an das System angeschlossen haben, wird eine Ausnahme ausgelöst.

Nachverfolgen von Flächen

Mit dem CaptureElement-Steuerelement erfolgreich streaming-Videos von der Webcam ist es nun Zeit verfolgen Flächen zu beginnen. Nachverfolgen von Flächen erfordert die Erstellung eines Objekts FaceDetectionDefinition einige Eigenschaften für das Objekt festgelegt, und erstellt dann das _mediaCapture-Objekt, das das Video auf die CaptureElement steams mit.

Fügen Sie die Ereignishandler für die Schaltfläche erkennen Flächen den folgenden Code:

private async void btnDetectFaces_Click(object sender, RoutedEventArgs e)
{
  var faceDetectionDefinition = new FaceDetectionEffectDefinition();
  faceDetectionDefinition.DetectionMode = FaceDetectionMode.HighPerformance;
  faceDetectionDefinition.SynchronousDetectionEnabled = false;
  _faceDetectionEffect = (FaceDetectionEffect) await    
  _mediaCapture.AddVideoEffectAsync(faceDetectionDefinition,
    MediaStreamType.VideoPreview);
  _faceDetectionEffect.FaceDetected += FaceDetectionEffect_FaceDetected;
  _faceDetectionEffect.DesiredDetectionInterval = TimeSpan.FromMilliseconds(33);
  _faceDetectionEffect.Enabled = true;
}

Dieser Code erstellt ein FaceDetectionDefinition-Objekt, das für die Leistung optimiert ist. Dies kann in der Codezeile angezeigt werden, DetectionMode auf HighPerformance festgelegt ist. Die FaceDetectionMode-Enumeration hat drei Member: HighPerformance Geschwindigkeit über Genauigkeit priorisiert, HighQuality priorisiert Genauigkeit gegenüber Geschwindigkeit und ausgeglichen findet einen Kompromiss zwischen Richtigkeit und Geschwindigkeit. Die nächste Zeile des Codes Verzögerung nicht eingehende Videoframes, während der Ausführung der Fläche Algorithmen zur Erkennung. Dadurch wird die Vorschau video ordnungsgemäß ausgeführt wird.

Als Nächstes wird das Objekt MediaCapture sowie eine Aufzählung, die den Typ des Mediums in den Stream der FaceDetectionDefinition hinzugefügt. Nach dem Hinzufügen, wird ein FaceDetectionEffect-Objekt zurückgegeben. Dieses Objekt verfügt über ein FaceDetected-Ereignis, das ausgelöst wird, wenn eine Fläche erkannt wird, eine DesiredDetectionInterval-Eigenschaft, die Häufigkeit der Erkennung Gesicht festlegt, und eine Enabled-Eigenschaft, die aktiviert oder deaktiviert die Erkennung der Fläche.

Zeichnen von Rechtecken, um Gesichter

Nun, dass die FaceDetectionEffect dem MediaCapture-Objekt hinzugefügt und aktiviert wurde, ist es Zeit, den FaceDetection-Ereignishandler Code hinzu:

private async void FaceDetectionEffect_FaceDetected(
  FaceDetectionEffect sender, FaceDetectedEventArgs args)
{
  var detectedFaces = args.ResultFrame.DetectedFaces;
  await Dispatcher
    .RunAsync(CoreDispatcherPriority.Normal, 
      () => DrawFaceBoxes(detectedFaces));
}

Während dieses Ereignisses in einem anderen Thread ausgeführt wird, müssen Sie den Verteiler verwenden, so ändern Sie den UI-Thread. Die nächste Zeile des Codes durchläuft die IReadOnlyList der erkannten Flächen. Jede erkannte Oberfläche besitzt einen Begrenzungsrahmen, wo Sie auf das Bild, das Gesicht erkannt wurde. Anhand dieser Daten, Sie dann ein neues Rectangle-Objekt erstellen und hinzufügen, die der Leinwand-Overlay Flächen Siehe Abbildung 2.

Abbildung 2: Hinzufügen eines Rectangle-Objekts auf die Oberflächen Overlay-Canvas

private void DrawFaceBoxes(IReadOnlyList<DetectedFace> detectedFaces)
{
  cvsFaceOverlay.Children.Clear();
  for (int i = 0; i < detectedFaces.Count; i++)
  {
    var face = detectedFaces[i];
    var faceBounds = face.FaceBox;
    Rectangle faceHighlightRectangle= new Rectangle()
    {
     Height = faceBounds.Height,
     Width = faceBounds.Width
    };
    Canvas.SetLeft(faceHighlightRectangle, faceBounds.X);
    Canvas.SetTop(faceHighlightRectangle, faceBounds.Y);
    faceHighlightRectangle.StrokeThickness = 2;
    faceHighlightRectangle.Stroke = new SolidColorBrush(Colors.Red);
    cvsFaceOverlay.Children.Add(faceHighlightRectangle);
  }
}

Die Projektmappe jetzt ausführen und Sie sehen etwas ist "deaktiviert" über die Rechtecke, siehe Abbildung 3.

Fläche erkannt aber Speicherort in der Benutzeroberfläche nicht rechts
Abbildung 3 Gesicht erkannt aber Speicherort in der Benutzeroberfläche nicht rechts

Suchen den richtigen Offset

Der Grund für die Rechtecke sind ist, dass am Anfang der Erkennungsalgorithmus Gesicht Pixelraster beginnt links der Mediendatenstrom und nicht die Darstellung der Benutzeroberfläche angezeigt. Sie müssen auch berücksichtigen, dass die Auflösung des videofeeds der Kamera die Auflösung in der Benutzeroberfläche unterscheidet sich möglicherweise. Um das Rechteck an der richtigen Stelle zu platzieren, müssen Sie die Position und die Skalierung Unterschiede in der Benutzeroberfläche und den Videodatenstrom berücksichtigt ausführen. Um dies zu erreichen, fügen Sie zwei Funktionen, die die Arbeit machen: MapRectangleToDetectedFace und LocatePreviewStreamCoordinates.

Der erste Schritt ist das Abrufen von Informationen über die Vorschau des Datenstroms. Dazu müssen Sie die Klasse wide _previewProperties mit einem VideoEncodingProperties-Objekt umwandeln. VideoEncodingProperties beschreibt das Format eines video-Streams. In erster Linie möchten Sie wissen, Höhe und Breite des Streams. Mit dieser Information können Sie bestimmen, das Seitenverhältnis der Datenstrom und gibt an, ob er sich das Steuerelement CaptureElement unterscheidet.

Die LocatePreviewStreamCoordinates-Methode vergleicht die Medien Stream Höhe und Breite, die denen des CaptureElement-Steuerelements.  Je nach den Unterschieden zwischen den beiden Seitenverhältnis eines der drei Fälle sind möglich: Die Seitenverhältnisse sind identisch, und es ist keine Anpassung. Wenn die Seitenverhältnisse unterscheiden, werden Briefkästen hinzugefügt werden. Ist die CaptureElement Seitenverhältnis größer als der Mediendatenstrom Seitenverhältnis beibehalten, werden die Briefkästen an den Seiten hinzugefügt.

Wenn Briefkästen an den Seiten hinzugefügt werden, muss die X-Koordinate des Gesicht Rechtecks angepasst werden. Wenn der Mediendatenstrom Seitenverhältnis größer als die CaptureElement ist, werden die Briefkästen oberhalb und unterhalb des Videos hinzugefügt. In diesem Fall müssen Sie dann die Fläche des Rechtecks Y-Koordinate angepasst werden.

Mit der Platzierung der die Briefkästen berücksichtigt werden soll müssen Sie jetzt die Differenz zwischen der Mediendatenstrom und dem CaptureElement-Steuerelement in der Benutzeroberfläche für die Skalierung festlegen. Ein Rechteck, sind vier Elemente festlegen: oben, links, Breite und Höhe. Oben und Links werden Abhängigkeitseigenschaften. Für einen guten Überblick über Abhängigkeitseigenschaften finden Sie im Artikel zur bit.ly/2bqvsVY.

Führen die Projektmappe erneut, siehe Abbildung 4, sehen Sie die Platzierung von das Gesicht Hervorhebung Rechteck genauer, wie in Abbildung 5.

Abbildung 4 Code den richtigen Offset berechnen

private Rectangle MapRectangleToDetectedFace(BitmapBounds detectedfaceBoxCoordinates)
  {
    var faceRectangle = new Rectangle();
    var previewStreamPropterties =
      _previewProperties as VideoEncodingProperties;
    double mediaStreamWidth = previewStreamPropterties.Width;
    double mediaStreamHeight = previewStreamPropterties.Height;
    var faceHighlightRect = LocatePreviewStreamCoordinates(previewStreamPropterties,
      this.cePreview);
    faceRectangle.Width = (detectedfaceBoxCoordinates.Width / mediaStreamWidth) *
      faceHighlightRect.Width;
    faceRectangle.Height = (detectedfaceBoxCoordinates.Height / mediaStreamHeight) *
      faceHighlightRect.Height;
    var x = (detectedfaceBoxCoordinates.X / mediaStreamWidth) *
      faceHighlightRect.Width;
    var y = (detectedfaceBoxCoordinates.Y / mediaStreamHeight) *
      faceHighlightRect.Height;
    Canvas.SetLeft(faceRectangle, x);
    Canvas.SetTop(faceRectangle, y);
    return faceRectangle;
  }
  public Rect LocatePreviewStreamCoordinates(
    VideoEncodingProperties previewResolution,
    CaptureElement previewControl)
  {
    var uiRectangle = new Rect();
    var mediaStreamWidth = previewResolution.Width;
    var mediaStreamHeight = previewResolution.Height;
    uiRectangle.Width = previewControl.ActualWidth;
    uiRectangle.Height = previewControl.ActualHeight;
    var uiRatio = previewControl.ActualWidth / previewControl.ActualHeight;
    var mediaStreamRatio = mediaStreamWidth / mediaStreamHeight;
    if (uiRatio > mediaStreamRatio)
    {
     var scaleFactor = previewControl.ActualHeight / mediaStreamHeight;
     var scaledWidth = mediaStreamWidth * scaleFactor;
     uiRectangle.X = (previewControl.ActualWidth - scaledWidth) / 2.0;
     uiRectangle.Width = scaledWidth;
    }
    else
     {
      var scaleFactor = previewControl.ActualWidth / mediaStreamWidth;
      var scaledHeight = mediaStreamHeight * scaleFactor;
      uiRectangle.Y = (previewControl.ActualHeight - scaledHeight) / 2.0;
      uiRectangle.Height = scaledHeight;
     }
    return uiRectangle;
    }

Genauere Platzierung der Fläche Hervorhebung Rechteck
Abbildung 5 genauer Platzierung der Fläche Hervorhebung Rechteck

Beenden des Fläche-Erkennung

Fläche Erkennung Leistung beansprucht und, bei mobilen Geräten batteriebetriebenen, erheblich reduzierte Akkulaufzeit führen kann. Sobald Sie Face Erkennung auf haben, sollten Sie Benutzern die Möglichkeit zum deaktivieren, geben.

Das Gesicht Erkennung deaktivieren ist Glücklicherweise relativ einfach. Fügen Sie zunächst eine Schaltfläche zum StackPanel in der Datei "MainPage.xaml" ein:

<Button x:Name="btnStopDetection" Click="btnStopDetection_Click">Stop
  Detecting Faces</Button>

Fügen Sie nun den folgenden Code an den Ereignishandler für die Schaltfläche Beenden Flächen erkennen:

private async void btnStopDetection_Click(object sender, RoutedEventArgs e)
  {
    _faceDetectionEffect.Enabled = false;
    _faceDetectionEffect.FaceDetected -= FaceDetectionEffect_FaceDetected;
    await _mediaCapture.ClearEffectsAsync(MediaStreamType.VideoPreview);
    _faceDetectionEffect = null;
  }

Der Code wird im Wesentlichen den Setupvorgang rückgängig gemacht. Die Auswirkung der Fläche Erkennung deaktiviert ist, FaceDetected Ereignisses wird der Ereignishandler gekündigt und der Effekt aus dem Media-Capture-Objekt deaktiviert ist. Schließlich wird die _faceDetectionEffect auf null festgelegt, um Arbeitsspeicher freizugeben.

Das Projekt jetzt ausführen. Klicken Sie auf die Kamera starten, dann Flächen erkennen und schließlich beenden Flächen erkennen. Sie sollten beachten, dass, obwohl die app nicht mehr Flächen erkannt werden, es ist immer noch ein Rechteck in der letzte Speicherort, den eine Fläche erkannt wurde. Das sollten wir korrigieren.

Beenden der app, und wechseln Sie zurück zu den BtnStopDetection_Click-Ereignishandler, und fügen die folgende Zeile des Codes, den Inhalt der Leinwand CvsFacesOverlay löschen:

this.cvsFaceOverlay.Children.Clear();

Führen Sie die Projektmappe erneut, und wiederholen Sie die Schritte aus. Jetzt stehen Face Erkennung deaktiviert ist, keine Highlights Rechteck.

Zusammenfassung

Kognitive Services-APIs bieten einfachen Zugriff auf leistungsfähige Computer Vision-Algorithmen. Wie alle Clouddienste benötigen sie jedoch Zugriff auf das Internet zu. Für einige Anwendungsfälle, die offline-Szenarien erfordern, können Sie grundlegende Gesichtsausdruck Erkennung ausführen, über die Fläche Erkennung-APIs direkt in die UWP integriert. 

Offline Anwendungsfälle können platzieren eine Webcam und eine Raspberry Pi 2 unter Windows IoT Core an einem Remotestandort verbunden sind. Die app kann Bilder dann lokal speichern, Fund eine Fläche. Wenn Daten vom Gerät erfasst wurden, konnte die Bilder kognitive Dienste für die erweiterte Analyse hochgeladen werden.

Gesicht Erkennung lokal ausführen optimiert auch die Übertragung und Cloud-Dienst Bandbreite, da Entwickler nur mit Flächen in diese hochladen. Kurz gesagt, können lokale Oberfläche Erkennung erweitern, online-Szenarien und ermöglichen auch offline verwendet.

Für eingehendere Informationen, achten Sie darauf, betrachten das Beispiel CameraFaceDetection in die UWP-Beispiel-apps auf GitHub (bit.ly/2b27gLk).


Frank La Vigne ist ein Technologieexperte im Microsoft Technology und staatsbürgerliches Engagement-Team, wo er hilft Benutzern, die Technologie zum Erstellen einer Community besseren zu nutzen.  Auf FranksWorld.com führt er einen Blog, sein YouTube-Kanal heißt Frank’s World TV (youtube.com/FranksWorldTV).

Unser Dank gilt der folgenden technischen Expertin für die Durchsicht dieses Artikels: Rachel Appel