Novembre 2016

Volume 31 Numero 11

Il presente articolo è stato tradotto automaticamente.

App moderne - Aggiungi funzionalità di riconoscimento facciale alla tua app

Da Frank La La

Frank La VigneNella compilazione 2016, Microsoft ha annunciato la versione dell'API di cognitivo Services. Tra le molte API disponibili sono molti i servizi di visione di computer. Questi servizi è possono analizzare l'età e sesso di facce in un'immagine di input. È disponibile anche un'API per il rilevamento di emozioni individuali in base alle loro facciale. Per evidenziare la tecnologia, non vi sono numerosi i chioschi nello spazio di evento che illustrano vari utilizzi della tecnologia. L'API dei servizi cognitivo sfrutta l'esperienza e gli sforzi nello spazio di machine learning di Microsoft. Migliaia di immagini con etichettate sono stati inseriti tramite una rete neurale. Soprattutto, è possibile utilizzare questi servizi senza alcuna conoscenza di machine learning o intelligenza artificiale. Sufficiente chiamare un servizio Web dall'app. È possibile vedere un'intervista con uno dei membri del team coinvolti nel progetto per ulteriori informazioni sul processo in bit.ly/1TGi1QK

Con cognitivo API dei servizi, è possibile aggiungere rilevamento facciale base all'App senza chiamare le API. Lo spazio dei nomi Windows.Media.FaceAnalysis contiene funzionalità per rilevare le facce in immagini o video. Il set di funzionalità è semplice e non dispone di set di dati avanzati di servizi cognitivo. In effetti, è molto simile a quello trovato in molte fotocamere digitali facciale. Mentre le funzionalità di base, hanno due vantaggi: Funzionamento non in linea e, poiché non si sta chiamando un'API, si verrà addebitato alcun costo. Come una strategia di ottimizzazione, l'applicazione in grado di rilevare la presenza di una faccia localmente prima di chiamare l'API dei servizi cognitivo. In questo modo l'applicazione non invia immagini senza facce nell'API ODS cognitivo di. Che può raggiungere una significativa riduzione dei costi per la larghezza di banda ridotta per gli utenti. Rilevamento facce locale possono essere un aumento di servizi cloud intelligente come servizi cognitivo utile.

Impostazione del progetto

In Visual Studio 2015, creare un nuovo progetto di app universale Windows piattaforma UWP (), scegliere il modello vuoto e denominarlo FaceDetection. Poiché l'app userà la webcam, è necessario aggiungere tale funzionalità all'app. In Esplora soluzioni fare doppio clic sul file package. appxmanifest. Nella scheda Capabilities, selezionare le caselle di controllo accanto a microfono e Webcam, come illustrato nella Figura 1. Salvare il file.

Aggiunta di Webcam e Microphone funzionalità all'App
Figura 1 aggiunta Webcam e Microphone funzionalità all'App

A questo punto, aggiungere il seguente codice XAML per il file MainPage. XAML per creare l'interfaccia Utente:

<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>

Potrebbe non essere familiarità con il controllo CaptureElement. Il controllo CaptureElement esegue il rendering di un flusso da un dispositivo di acquisizione collegato, in genere una fotocamera o una webcam. Nel codebehind, si userà l'API mediacapture durante il connetterlo a un flusso da webcam.

Visualizzazione in anteprima il Video dalla fotocamera

Nel file MainPage.xaml.cs aggiungere spazi dei nomi seguenti:

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

Successivamente, aggiungere i due membri seguenti alla classe MainPage:

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

A questo punto, aggiungere il seguente gestore eventi per il pulsante Avvia fotocamera:

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

Eseguire il progetto e quindi fare clic sul pulsante Avvia fotocamera. Viene visualizzato l'output di webcam nell'app. Se non si dispone di una webcam collegata al sistema, verrà generata un'eccezione.

Rilevamento facce

Con il controllo CaptureElement correttamente lo streaming video da Webcam, ora è necessario avviare il rilevamento di facce. Rilevamento facce richiede la creazione di un oggetto FaceDetectionDefinition, impostando alcune proprietà sull'oggetto, e quindi collegarlo all'oggetto _mediaCapture steams il video di CaptureElement creato.

Nei gestori eventi per il pulsante rilevare deve affrontare, aggiungere il codice seguente:

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;
}

Questo codice crea un oggetto FaceDetectionDefinition che è ottimizzato per le prestazioni. Può essere visto nella riga di codice in cui DetectionMode è impostato su HighPerformance. L'enumerazione FaceDetectionMode dispone di tre membri: HighPerformance dà priorità alle velocità piuttosto che la precisione, riprodurre assegna accuratezza rispetto alla velocità e bilanciato consente di trovare un compromesso tra precisione e velocità. La riga successiva del codice non ritardata frame video in ingresso durante l'esecuzione faccia algoritmi di rilevamento. In questo modo, l'anteprima video funzionare alla perfezione.

Successivamente, il FaceDetectionDefinition viene aggiunto all'oggetto mediacapture durante il, insieme a un'enumerazione che specifica il tipo di supporto nel flusso. Una volta aggiunta, viene restituito un oggetto FaceDetectionEffect. Questo oggetto dispone di un evento FaceDetected che viene generato quando viene rilevata una faccia, una proprietà DesiredDetectionInterval che imposta la frequenza di rilevamento faccia e una proprietà Enabled che abilita o disabilita il rilevamento dei faccia.

Disegno di rettangoli intorno facce

Ora che il FaceDetectionEffect è stato aggiunto all'oggetto mediacapture durante l'e abilitato, è necessario aggiungere codice al gestore dell'evento FaceDetection:

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

Quando questo evento è in esecuzione su un altro thread, è necessario utilizzare Dispatcher per apportare modifiche al thread dell'interfaccia Utente. La riga di codice successiva iterazione IReadOnlyList di facce rilevate. Ogni faccia rilevato dispone di un rettangolo di cui l'immagine è stata rilevata la superficie. In base a tali dati, quindi creare un nuovo oggetto rettangolo e aggiungerlo all'area di disegno sovrapposizione facce, come illustrato nella Figura 2.

Figura 2 aggiunta di un oggetto rettangolo per le facce sovrapporre 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);
  }
}

Eseguire ora la soluzione e si noterà qualcosa è "off" sui rettangoli, come illustrato nella Figura 3.

Rilevato faccia ma la posizione nell'interfaccia Utente non è a destra
Figura 3 faccia rilevato ma la posizione nell'interfaccia Utente non è a destra

Ricerca l'Offset corretto

Il motivo per cui i rettangoli sono disattivati è che griglia in pixel dell'algoritmo di rilevamento faccia inizia nella parte superiore sinistra del flusso multimediale e non la rappresentazione di viene visualizzato nell'interfaccia Utente. È inoltre necessario considerare che la risoluzione del feed video dalla fotocamera può differire dalla risoluzione nell'interfaccia Utente. Per posizionare il rettangolo nella posizione appropriata, è necessario eseguire sia la posizione e scala le differenze nell'interfaccia Utente e il flusso video in considerazione. A tale scopo, si aggiungeranno due funzioni che verranno eseguite le operazioni: MapRectangleToDetectedFace e LocatePreviewStreamCoordinates.

Il primo passaggio consiste per recuperare informazioni sul flusso di anteprima. Si esegue il cast di _previewProperties ampia classe a un oggetto VideoEncodingProperties. VideoEncodingProperties descrive il formato di un flusso video. In primo luogo, si desidera conoscere altezza e larghezza del flusso. Con queste informazioni è possibile determinare le proporzioni del flusso di supporti e se è diverso rispetto al controllo CaptureElement.

Il metodo LocatePreviewStreamCoordinates Confronta multimediali flusso altezza e larghezza a quelle del controllo CaptureElement.  A seconda delle differenze tra le due proporzioni, uno dei tre casi, sono possibili: Le proporzioni sono uguali e non sarà presente alcuna rettifica. Se le proporzioni sono diversi, verrà aggiunto consegna. Se le proporzioni del CaptureElement è maggiore di proporzioni del flusso multimediale, consegna viene aggiunti ai lati.

Se consegna viene aggiunti ai lati, il coordinata X rettangolo faccia deve essere modificato. Se le proporzioni del flusso multimediale è maggiore di CaptureElement, consegna viene aggiunti sopra e sotto il video. In tal caso, quindi coordinata Y del rettangolo faccia deve essere modificato.

Posizionare con precisione la consegna presi in considerazione, è necessario determinare la differenza in proporzione tra il flusso multimediale e il controllo CaptureElement nell'interfaccia Utente. Con un rettangolo, sono disponibili quattro elementi per impostare: top, left, larghezza e altezza. Top e left sono proprietà di dipendenza. Per una panoramica delle proprietà di dipendenza, leggere l'articolo all'indirizzo bit.ly/2bqvsVY.

Eseguire nuovamente la soluzione, come illustrato nella Figura 4, dovrebbe essere possibile visualizzare la posizione del rettangolo di evidenziazione faccia ottenere risultati più accurati, come illustrato nel Figura 5.

Figura 4 codice per calcolare l'Offset corretto

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;
    }

Posizionamento più accurato del rettangolo di evidenziazione faccia
Figura 5 posizionamento più accurata del rettangolo di evidenziazione faccia

Arresto rilevamento faccia

Rilevamento faccia utilizza potenza di elaborazione e nei dispositivi mobili alimentato a batteria, può causare una significativa riduzione della batteria. Dopo aver creato il rilevamento faccia, si desidera offrire agli utenti la possibilità di disattivare tale funzionalità.

Fortunatamente, disattivare il rilevamento faccia è piuttosto semplice. In primo luogo, aggiungere un pulsante StackPanel nel file MainPage. XAML:

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

A questo punto, aggiungere il codice seguente al gestore eventi per il pulsante Arresta il rilevamento deve affrontare:

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

Essenzialmente, il codice Annulla il processo di installazione. L'effetto di rilevamento faccia è disabilitato, l'evento FaceDetected viene annullata dal gestore dell'evento e l'effetto viene cancellato l'oggetto di acquisizione di supporti. Infine, il _faceDetectionEffect è impostato su null per liberare memoria.

Eseguire ora il progetto. Fare clic sul pulsante Avvia fotocamera, quindi rilevare facce e, last, arrestare il rilevamento deve affrontare. Si noterà che anche se l'applicazione non è il rilevamento delle facce, esiste ancora un rettangolo nella posizione ultimo che è stata rilevata una faccia. Correggiamo.

Arrestare l'applicazione e tornare al gestore dell'evento btnStopDetection_Click e aggiungere la seguente riga di codice per cancellare il contenuto dell'area di disegno cvsFacesOverlay:

this.cvsFaceOverlay.Children.Clear();

Eseguire nuovamente la soluzione e ripetere tutti i passaggi. A questo punto, quando il rilevamento faccia è disattivato, sono non disponibili evidenziazioni rettangolo.

Conclusioni

Le API dei servizi cognitivo consentono di accedere agli algoritmi visione computer potente. Come tutti i servizi cloud, tuttavia, richiedono accesso a Internet per lavoro. Per alcuni casi che richiedono scenari non in linea, è comunque possibile eseguire rilevamento facciale base tramite le API di rilevamento faccia integrate nella piattaforma UWP. 

Casi di utilizzo non in linea possono includere l'inserimento di una webcam collegata a un Raspberry Pi 2 in esecuzione Windows IoT Core in una posizione remota. L'applicazione sarebbe quindi salvare immagini in locale quando rilevato una faccia. Quando vengono raccolti i dati dal dispositivo, le immagini potrebbero quindi essere caricate in cognitivo servizi per l'analisi avanzata.

Esegue il rilevamento di faccia localmente Ottimizza anche all'utilizzo del servizio cloud e la trasmissione della larghezza di banda consentendo agli sviluppatori di solo caricamento delle immagini con facce in essi contenuti. In breve, rilevamento faccia locale può aumentare scenari online e consentire utilizza offline, nonché.

Per un approfondimento, assicurarsi di esaminare l'esempio CameraFaceDetection in applicazioni di esempio UWP su GitHub (bit.ly/2b27gLk).


Frank La Vigne è un evangelist di tecnologia del team Microsoft Technology e l'interesse verso civico, in cui aiuta gli utenti utilizzano la tecnologia per creare una community migliorata.  Possiede un blog all'indirizzo FranksWorld.com e ha un YouTube canale TV al mondo chiamato Marco (youtube.com/FranksWorldTV).

Grazie al seguente esperto tecnico per la revisione dell'articolo: Rachel Appel