Ottobre 2016

Volume 31 Numero 10

Il presente articolo è stato tradotto automaticamente.

Servizi cognitivi - Riconoscimento del viso e delle emozioni in Xamarin.Forms con i Servizi cognitivi Microsoft

Da Alessandro Del Del

In occasione della conferenza Build 2016, Microsoft ha annunciato una prima anteprima servizi cognitivo (microsoft.com/cognitivo-servizi), un'ampia gamma di piattaforme, API RESTful che è possibile utilizzare per creare la nuova generazione di App basate sull'interazione dell'utente naturale per qualsiasi piattaforma su qualsiasi dispositivo. Servizi cognitivi, noto anche come "Oxford progetto", sono basati su machine learning e adattata perfettamente la filosofia di conversazione come piattaforma in grado di rendere l'ecosistema di applicazioni Microsoft. A un livello superiore, le API dei servizi cognitivo sono disponibili tramite i servizi RESTful e attualmente offrono le seguenti categorie di API:

  • Obiettivi: I servizi visione offrono API che consentono di analizzare le immagini e video per identificare le facce ed emozioni e per rilevare informazioni utilizzabili. Questa categoria include la visione per Computer, di emozioni e API Video.
  • Riconoscimento vocale: I servizi di riconoscimento vocale offrono API che rendono più semplice per implementare sintesi vocale, riconoscimento vocale naturali e anche per riconoscere che comunica con il servizio di riconoscimento relatore. Includono il riconoscimento vocale di Bing, servizio intelligente di riconoscimento personalizzato e le API di riconoscimento di relatore.
  • Lingua: I servizi di linguaggio sono orientati a conoscenza di linguaggio naturale, ovvero il rilevamento e correzione degli errori di ortografia, informazioni sui comandi vocali e analisi di testo complesso inclusi valutazioni e frasi chiave. Essi includono Bing per il controllo ortografico, servizio intelligente conoscenza del linguaggio, l'analisi linguistica, analisi del testo e API del modello di linguaggio Web.
  • Knowledge Base: Servizi prolungare applicazioni conoscenza dei clienti mediante la ricerca di consigli sui prodotti personalizzati, eventi, percorsi e paper Education o registrazioni. Includono Education conoscenze, entità di collegamento Intelligence Service, servizio esplorazione Knowledge e API Recommendations.
  • Cerca: Servizi di ricerca sono basati su Bing e consentono di implementare i potenti strumenti di ricerca nelle proprie app. I nomi dei servizi inclusi sono realmente comprensibili: Suggerimenti automatici Bing Bing ricerca delle immagini, di ricerca Bing notizie, Video Cerca con Bing e le API di ricerca Web Bing.

In questo articolo spiegherò come combinare le facce emozione API e per recuperare dettagli faccia ed emozioni da immagini scattate da una videocamera o da un album su disco in un'app xamarin creata con c# e Visual Studio 2015 in esecuzione su Android, iOS o Windows 10. Figura 1 Mostra i risultati dell'esercitazione dell'articolo. È importante ricordare che, quando si usa xamarin per questo articolo, lo stesso può essere eseguito con App Xamarin tradizionali, nonché con qualsiasi altra piattaforma che supporti REST. Si suppone che si dispone di conoscenza di base di creazione di un'app di xamarin. Forms e i concetti di condivisione del codice; in caso contrario, assicurarsi che leggere i miei articoli precedenti: "Creare un'esperienza Utente multipiattaforma con xamarin. Forms" (msdn.com/magazine/mt595754) e "Condividere il codice dell'interfaccia Utente tra le piattaforme per dispositivi mobili con xamarin. Forms" (msdn.com/magazine/dn904669).

Faccia e riconoscimento emozione su un'App multipiattaforma con xamarin
Figura 1 carattere e il riconoscimento emozione su un'App multipiattaforma con xamarin. Forms (dispositivo Android a sinistra, Windows 10 Desktop a destra)

La sottoscrizione per le API dei servizi cognitivo

Per compilare applicazioni che sfruttano i vantaggi dei servizi Cognitive, è necessario sottoscrivere il servizio in cui si è interessati. Attualmente, Microsoft è gratuite offerta che è possibile attivare nella pagina sottoscrizioni (bit.ly/2b2rKDO), ma i piani correnti possono essere soggetti a modifiche in futuro. Quando nella pagina, registrare con un account Microsoft, quindi fare clic su "Richiedi nuove versioni di valutazione". Quindi verrà visualizzato un elenco dei servizi disponibili; Assicurarsi di selezionare liberare anteprime faccia sia emozione API. A questo punto, la pagina sottoscrizioni sarà visualizzato l'elenco dei servizi attivi; le sottoscrizioni faccia e API emozione dovrebbe. Figura 2 viene illustrato un esempio in base alle sottoscrizioni personali. Si noti che, per ogni servizio attivo, sono presenti due chiavi private. È necessario uno per richiamare le API. Per ora, è necessario tenerli nascosti. È necessario scoprire la chiave durante la creazione di app di xamarin. Forms.

L'attivazione di sottoscrizioni per le API di emozioni e faccia
Figura 2, l'attivazione di sottoscrizioni per le API di emozioni e faccia

In generale, cognitivo servizi forniscono le API REST, che significa che è possibile interagire con questi servizi tramite richieste HTTP su qualsiasi piattaforma e con qualsiasi linguaggio che supporta REST. Ad esempio, la richiesta HTTP POST seguente viene illustrato come inviare un'immagine per il servizio di riconoscimento emozione per il rilevamento emozione:

POST https://api.projectoxford.ai/emotion/v1.0/recognize HTTP/1.1
Content-Type: application/json
Host: api.projectoxford.ai
Content-Length: 107
Ocp-Apim-Subscription-Key: YOUR-KEY-GOES-HERE
{ "url": "http://www.samplewebsite.com/sampleimage.jpg" }

Naturalmente, è necessario sostituire l'Ocp-Apim-Subscription-Key con le proprie chiavi e l'URL dell'immagine fittizio con un indirizzo immagine reale. In exchange, il servizio di riconoscimento della emozioni restituirà il risultato di rilevamento come risposta JSON, come illustrato nella Figura 3.

Figura 3. la risposta di rilevamento del servizio di riconoscimento emozione

[
  {
    "faceRectangle": {
      "height": 70,
      "left": 26,
      "top": 35,
      "width": 70
    },
    "scores": {
      "anger": 2.012591E-11,
      "contempt": 1.95578984E-10,
      "disgust": 1.02281912E-10,
      "fear": 1.16242682E-13,
      "happiness": 1.0,
      "neutral": 9.79047E-09,
      "sadness": 2.91102975E-10,
      "surprise": 1.71011272E-09
    }
  }
]

La risposta di esempio nella figura 3 viene illustrato come il servizio emozione ha restituito il rettangolo in cui è stata rilevata una faccia e una matrice denominata punteggi contenente un elenco di emozioni e un valore compreso tra 0 e 1 che indica la probabilità di emozione è true. In generale, l'invio di richieste HTTP a servizi RESTful e prevede una risposta JSON è un approccio comune con tutti i servizi cognitivo. Tuttavia, per gli sviluppatori .NET funziona con c#, Microsoft inoltre offre client librerie portabili che è possibile scaricarlo da NuGet e di rendere più facile interagire con i servizi nel codice gestito e in modo completamente orientata agli oggetti. Ciò avviene faccia e sulle API emozione, di come si vedrà a breve. Non dimenticare di consultare la documentazione ufficiale, che contiene esempi in base all'approccio REST e librerie client in cui è disponibile (bit.ly/2b2KJrB). Ora che è registrato per entrambi i servizi e si dispongono delle chiavi, è necessario creare un'app multipiattaforma con xamarin e Microsoft Visual Studio 2015.

Creazione di un'applicazione xamarin

Come sapete, è possibile creare un'app multipiattaforma con xamarin. Forms scegliendo il computer portatile o il modello di progetto condiviso. Poiché verrà illustrato come sfruttare le librerie client per le API dei servizi Cognitive, l'applicazione di esempio è basata sul modello di libreria di classi portabile (PCL). In Visual Studio 2015, selezionare File | Nuovo progetto. Se sono stati installati gli aggiornamenti più recenti da Xamarin (xamarin.com/download), troverete un nuovo modello di progetto chiamato applicazione vuota Xaml (xamarin. Forms portabile) in di Visual c#, nodo multipiattaforma della finestra di dialogo Nuovo progetto. Si tratta di un modello interessano che fornisce una pagina XAML vuota ed evita la necessità di crearne uno manualmente. Figura 4 viene illustrato il nuovo modello.

Chiamare la soluzione FaceEmotionRecognition e fare clic su OK. Durante la generazione della soluzione, verrà chiesto di specificare la versione di destinazione minimo per il progetto Universal Windows Platform (UWP). Questo viene lasciato per la scelta, ma si consiglia di destinazione la versione più recente disponibile.

Crea una nuova applicazione xamarin
Figura 4 creazione di una nuova applicazione xamarin

Introduzione a Plug-in per Xamarin

L'applicazione di esempio utilizzerà le API dei servizi cognitivo riconosca i singoli dettagli faccia ed emozioni da immagini, utilizzo di immagini esistente dal dispositivo o che le nuove immagini dalla fotocamera. Ciò implica che l'app deve accedere a Internet per connettersi ai servizi e sarà necessario fornire la possibilità di recupero e la selezione di immagini. Mentre un'applicazione può facilmente connettersi a una rete, è responsabilità dell'utente, lo sviluppatore, per verificare la disponibilità di rete. In realtà, caratteristiche, ad esempio verifica la disponibilità della rete e scattare foto richiede la scrittura di codice specifico nei progetti Windows, iOS e Android. Per fortuna, Xamarin supporta plug-in che è possibile utilizzare in xamarin. Forms e che è possibile installare il progetto PCL, che è necessario eseguire il processo automaticamente. Un plug-in è una libreria installata da NuGet include le API native in un'implementazione di codice comune e richiamati nel progetto PCL. È un numero elevato di plug-in, alcuni sviluppata e supportata da Xamarin e ad altri utenti creati e pubblicati dalla community di sviluppatori. Plug-in sono tutti open source ed elencato in GitHub all'indirizzo bit.ly/29XZ3VM. In questo articolo verrà illustrato come utilizzare i plug-in connettività e la Media.

Installazione dei pacchetti NuGet

Quando la soluzione è pronta, la prima cosa che è necessario eseguire è installare i pacchetti NuGet seguenti:

  • Microsoft.ProjectOxford.Face: Consente di installare la libreria client per le API faccia e deve essere installato solo nel progetto PCL.
  • Microsoft.ProjectOxford.Emotion: Installa la libreria client per le API di emozioni e, come per la superficie API, deve essere installato solo nel progetto PCL.
  • Xam.Plugin.Connectivity: Contiene la connettività plug-in per xamarin. Forms e deve essere installato in tutti i progetti nella soluzione.
  • Xam.Plugin.Media: Contiene il supporto di plug-in per xamarin. Forms e, come l'API di connettività, deve essere installato in tutti i progetti nella soluzione.

Dopo aver installato i pacchetti NuGet, assicurarsi che si compila la soluzione prima di scrivere codice in modo che tutti i riferimenti verranno aggiornati.

Progettazione dell'interfaccia Utente

Interfaccia Utente dell'applicazione di esempio è costituito da una singola pagina. Per semplicità, si utilizzerà il file MainPage. XAML generato automaticamente. Questa pagina definisce due pulsanti, uno per l'esecuzione di un'immagine dalla fotocamera e uno per il caricamento di un'immagine esistente; un controllo ActivityIndicator che verrà visualizzato lo stato occupato durante l'attesa di una risposta dal servizio. un controllo immagine che verrà visualizzata l'immagine selezionata; numero di etichette, all'interno di pannelli StackLayout, che vengono associati a una classe personalizzata che conterrà il risultato di rilevamenti sull'immagine selezionata. Figura 5 viene illustrato il codice XAML completo per la pagina.

Figura 5 l'interfaccia Utente per il metodo Main pagina

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
  xmlns:x="https://schemas.microsoft.com/winfx/2009/xaml"
  xmlns:local="clr-namespace:FaceEmotionRecognition"
  xmlns:conv="clr-namespace:FaceEmotionRecognition. 
    Converters;assembly=FaceEmotionRecognition"
    x:Class="FaceEmotionRecognition.MainPage">
  <StackLayout Orientation="Vertical">
    <Button x:Name="TakePictureButton" Clicked="TakePictureButton_Clicked"
      Text="Take from camera"/>
    <Button x:Name="UploadPictureButton" Clicked="UploadPictureButton_Clicked"
      Text="Pick a photo"/>
    <ActivityIndicator x:Name="Indicator1" IsVisible="False" IsRunning="False" />
    <Image x:Name="Image1" HeightRequest="240" />
    <StackLayout Orientation="Horizontal" Padding="3">
      <Label Text="Gender: "/>
      <Label x:Name="GenderLabel" Text="{Binding Path=Gender}" />
    </StackLayout>
    <StackLayout Orientation="Horizontal" Padding="3">
      <Label Text="Age: "/>
      <Label x:Name="AgeLabel" Text="{Binding Path=Age}"/>
    </StackLayout>
    <StackLayout Orientation="Horizontal" Padding="3">
      <Label Text="Emotion: "/>
      <Label x:Name="EmotionLabel" Text="{Binding Path=Emotion}"/>
    </StackLayout>
    <StackLayout Orientation="Horizontal" Padding="3">
      <Label Text="Smile: "/>
      <Label x:Name="SmileLabel"
        Text="{Binding Path=Smile}"/>
    </StackLayout>
    <StackLayout Orientation="Horizontal" Padding="3">
      <Label Text="Glasses: "/>
      <Label x:Name="GlassesLabel" Text="{Binding Path=Glasses}"/>
    </StackLayout>
    <StackLayout Orientation="Horizontal" Padding="3">
      <Label Text="Beard: "/>
      <Label x:Name="BeardLabel"
        Text="{Binding Path=Beard}"/>
    </StackLayout>
    <StackLayout Orientation="Horizontal" Padding="3">
      <Label Text="Moustache: "/>
      <Label x:Name="MoustacheLabel"
        Text="{Binding Path=Moustache}"/>
    </StackLayout>
  </StackLayout>
</ContentPage>

Il passaggio successivo consiste nel preparare una posizione in cui archiviare il risultato di rilevamento faccia ed emozione.

Archiviazione dei risultati di rilevamento con una classe

Anziché inserire manualmente le etichette dell'interfaccia utente con i risultati del rilevamento faccia ed emozione, è consigliabile creare una classe personalizzata. Non solo si tratta di un approccio più orientato a oggetti, ma consente inoltre di associazione dati istanza della classe per l'interfaccia Utente. Detto ciò, creiamo una nuova classe denominata FaceEmotionDetection:

public class FaceEmotionDetection
{
  public string Emotion { get; set; }
  public double Smile { get; set; }
  public string Glasses { get; set; }
  public string Gender { get; set; }
  public double Age { get; set; }
  public double Beard { get; set; }
  public double Moustache { get; set; }
}

Ogni proprietà ha un nome facilmente comprensibile e di archiviare le informazioni provenienti dalla combinazione di entrambe le API emozione e faccia.

Dichiarare il client del servizio

Prima di scrivere qualsiasi altro codice, è consigliabile aggiungere le seguenti direttive using:

using Microsoft.ProjectOxford.Emotion;
using Microsoft.ProjectOxford.Emotion.Contract;
using Microsoft.ProjectOxford.Face;
using Microsoft.ProjectOxford.Face.Contract;
using Plugin.Connectivity;
using Plugin.Media;

Questi semplificherà la chiamata ai nomi degli oggetti per le API dei servizi cognitivo e i plug-in. Le API faccia e le API della emozioni forniscono il Microsoft.ProjectOxford.Face.FaceServiceClient e Microsoft.ProjectOxford.Emotion.EmotionServiceClient, che si connettono ai servizi cognitivo e rispettivamente restituiscono informazioni sui dettagli faccia ed emozione. Cosa è necessario innanzitutto eseguire è dichiarare un'istanza di entrambi, passare la chiave segreta nel costruttore, come illustrato di seguito:

private readonly IFaceServiceClient faceServiceClient;
private readonly EmotionServiceClient emotionServiceClient;
public MainPage()
{
  InitializeComponent();
  // Provides access to the Face APIs
  this.faceServiceClient = new FaceServiceClient("YOUR-KEY-GOES-HERE");
  // Provides access to the Emotion APIs
  this.emotionServiceClient = new EmotionServiceClient("YOUR-KEY-GOES-HERE");
}

Si noti che è necessario fornire le proprie chiavi segrete. Le chiavi segrete faccia sia emozione API sono reperibili nella pagina sottoscrizioni del portale di Microsoft Services cognitivo (bit.ly/2b2rKDO), come illustrato nella Figura 2.

Acquisizione e il caricamento delle immagini

In xamarin. Forms, l'accesso sia la fotocamera e il file system richiede la scrittura di codice specifico della piattaforma. Un approccio più semplice utilizza il supporto di plug-in xamarin. Forms, che consente di selezionare le immagini e video dal disco e copiare immagini e video con la fotocamera dal progetto PCL e con poche righe di codice. Questo plug-in espone una classe denominata CrossMedia, che espone i seguenti membri:

  • Corrente: Restituisce un'istanza singleton della classe CrossMedia.
  • IsPickPhotoSupported e IsPickVideoSupported: Proprietà booleane che restituiscono true se il dispositivo corrente supporta la selezione di immagini e video dal disco.
  • PickPhotoAsync e PickVideoAsync: Metodi che richiamano l'interfaccia Utente specifico della piattaforma per selezionare un'immagine locale o un video, rispettivamente e restituiscono un oggetto di tipo MediaFile.
  • IsCameraAvailable: Proprietà bool che restituisce true se il dispositivo dispone di una videocamera incorporata.
  • IsTakePhotoSupported e IsTakeVideoSupported: Proprietà booleane che restituiscono true se il dispositivo corrente supporta l'acquisizione delle immagini e video dalla fotocamera.
  • TakePhotoAsync e TakeVideoAsync: Metodi che avviano la fotocamera incorporata per richiedere un'immagine o video, rispettivamente e restituiscono un oggetto di tipo MediaFile.

Non dimenticare di impostare le autorizzazioni appropriate nel manifesto dell'applicazione per accedere alla fotocamera. Ad esempio, in un progetto UWP occorre autorizzazioni Webcam e di libreria di immagini, mentre in Android sono necessarie le autorizzazioni della FOTOCAMERA, READ_EXTERNAL_STORAGE e WRITE_EXTERNAL_STORAGE. Dimenticare di impostare le autorizzazioni necessarie genererà eccezioni di runtime. Ora scriviamo il gestore dell'evento Clicked per il UploadPictureButton, come illustrato nella Figura 6.

Figura 6 selezionando un'immagine disco

private async void UploadPictureButton_Clicked(object sender, EventArgs e)
{
  if (!CrossMedia.Current.IsPickPhotoSupported)
  {
    await DisplayAlert("No upload", "Picking a photo is not supported.", "OK");
    return;
  }
  var file = await CrossMedia.Current.PickPhotoAsync();
  if (file == null)
    return;
  this.Indicator1.IsVisible = true;
  this.Indicator1.IsRunning = true;
  Image1.Source = ImageSource.FromStream(() => file.GetStream());
  this.Indicator1.IsRunning = false;
  this.Indicator1.IsVisible = false;
}

Il codice controlla se la selezione di immagini è supportata, è visualizzato un errore del messaggio se IsPickPhotoSupported restituisce false. PickPhotoAsync (nonché PickVideoAsync) restituisce un oggetto di tipo MediaFile, che è una classe definita nello spazio dei nomi Plugin.Media e che rappresenta il file selezionato. È necessario richiamare il metodo GetStream per restituire un flusso che può essere utilizzato come origine per il controllo immagine tramite il relativo metodo FromStream. Scattata con la fotocamera è anche molto semplice, come illustrato nella Figura 7.

Figura 7 un'immagine con la fotocamera

private async void TakePictureButton_Clicked(object sender, EventArgs e)
{
  await CrossMedia.Current.Initialize();
  if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.
    IsTakePhotoSupported)
  {
    await DisplayAlert("No Camera", "No camera available.", "OK");
    return;
  }
  var file = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions
  {
    SaveToAlbum = true,
    Name = "test.jpg"
  });
  if (file == null)
    return;
  this.Indicator1.IsVisible = true;
  this.Indicator1.IsRunning = true;
  Image1.Source = ImageSource.FromStream(() => file.GetStream());
  this.Indicator1.IsRunning = false;
  this.Indicator1.IsVisible = false;
}

La notizia è che TakePhotoAsync accetta un parametro di tipo StoreCameraMediaOptions, un oggetto che consente di specificare dove e come salvare un'immagine. È possibile impostare la proprietà SaveToAlbum come true se si desidera che l'immagine da salvare per il lancio di una fotocamera locale o se si desidera salvare in una cartella diversa, è possibile impostare la proprietà della Directory. Come può notare, con uno sforzo molto limitato e con poche righe di codice, l'app può sfruttare facilmente un'importante funzionalità di tutte le piattaforme supportate.

Rilevamento di emozioni e implementazione di riconoscimento facciale

A questo punto è necessario implementare il riconoscimento faccia ed emozione. Poiché si tratta di un articolo introduttivo, mi concentrerò su semplicità. Verrà illustrato come implementare il rilevamento su un singolo carattere tipografico in un'immagine e descriverò gli oggetti e membri nelle API più importanti. Inoltre fornirò suggerimenti su come implementare rilevamenti più dettagliati dove appropriato. In base a questi presupposti, per iniziare la scrittura di un metodo asincrono che esegue i rilevamenti. La prima parte è informazioni sul rilevamento della emozioni ed è simile al seguente:

private async Task<FaceEmotionDetection> DetectFaceAndEmotionsAsync(MediaFile inputFile)
{
  try
  {
    // Get emotions from the specified stream
    Emotion[] emotionResult = await
      emotionServiceClient.RecognizeAsync(inputFile.GetStream());
    // Assuming the picture has one face, retrieve emotions for the
    // first item in the returned array
    var faceEmotion = emotionResult[0]?.Scores.ToRankedList();

Il metodo riceve MediaFile prodotto selezionando o un'immagine. Rilevamento di emozioni su facce su un'immagine è semplice, poiché è sufficiente richiamare il metodo RecognizeAsync dall'istanza della classe EmotionServiceClient. Questo metodo può ricevere un flusso o un URL come argomento. In questo caso, ottiene un flusso dall'oggetto MediaFile. RecognizeAsync restituisce una matrice di oggetti emozione. Un'emozione nella matrice memorizza emozioni rilevati su un singolo carattere tipografico in un'immagine. Supponendo che l'immagine selezionata ha un solo carattere, il codice recupera il primo elemento nella matrice. Il tipo della emozioni espone una proprietà denominata punteggi, che contiene un elenco di nomi di otto emozioni e al relativo valore approssimativo. In particolare, si ottiene un oggetto IEnumerable < string, float >. Richiamando il metodo ToRankedList, è possibile ottenere un elenco ordinato di emozioni rilevati. Le API in grado di rilevare un'emozione singolo con precisione. Al contrario, rilevano un numero di possibili emozioni. Il valore massimo restituito è di circa l'emozione effettivo sulla superficie, ma esistono altri valori che potrebbero essere controllati.  Il valore più alto nell'elenco rappresenta l'emozione con il massimo livello di probabilità stimata, che è probabilmente l'emozione effettivo in una faccia. Per una migliore comprensione, prendere in considerazione il seguente elenco della emozioni classificate recuperati con l'aiuto di suggerimenti per i dati del debugger, che è basato su immagine di esempio illustrato Figura 1:

[0] = {[Happiness, 1]}
[1] = {[Neutral, 1.089301E-09]}
[2] = {[Surprise, 7.085784E-10]}
[3] = {[Sadness, 9.352855E-11]}
[4] = {[Disgust, 4.52789E-11]}
[5] = {[Contempt, 1.431213E-11]}
[6] = {[Anger, 1.25112E-11]}
[7] = {[Fear, 5.629648E-14]}

Come si può vedere, "Happiness" ha un valore di 1, che è il più alto nell'elenco e la probabilità stimata della emozioni effettiva. Il passaggio successivo è il rilevamento di attributi di immagine. La classe FaceServiceClient espone il metodo DetectAsync, che è molto potente. Non solo è possibile recuperare faccia gli attributi, ad esempio sesso, età e smile, ma è anche possibile riconoscere persone, restituire il rettangolo faccia (l'area dell'immagine in cui è stato rilevato l'immagine) e punti di riferimento 27 faccia che consentono un'app per individuare informazioni quali la posizione del naso, bocca, orecchio e occhi sull'immagine. DetectAsync ha la firma seguente:

Task<Contract.Face[]> DetectAsync(Stream imageStream,
  bool returnFaceId = true, bool returnFaceLandmarks = false,
  IEnumerable<FaceAttributeType> returnFaceAttributes = null);

Nella chiamata di base, DetectAsync richiede un flusso che punta a un'immagine o un URL e restituisce che il rettangolo di carattere, mentre i parametri facoltativi returnFaceId e returnFaceLandmarks, rispettivamente, consentono di identificare una persona e restituire i punti di faccia riferimento. Le API faccia consentono di creare gruppi di utenti e assegnare un id a ogni persona in modo che è possibile eseguire facilmente il riconoscimento. Punti di riferimento faccia invece sono utili per identificare le caratteristiche dell'immagine e sarà disponibile tramite la proprietà FaceLandmarks dell'oggetto immagine. Identificazione e punti di riferimento non rientrano nell'ambito di questo articolo, ma è possibile trovare ulteriori informazioni su questi argomenti in bit.ly/2adPvoP e bit.ly/2ai9WjV, rispettivamente. Analogamente, è non verrà mostrato come utilizzare i punti di riferimento di carattere, ma sono memorizzati nella proprietà FaceLandmarks dell'oggetto immagine. Nello scenario di esempio corrente, l'obiettivo consiste nel recuperare gli attributi di immagine. La prima cosa che occorre è una matrice di enumerazione FaceAttributeType, che definisce l'elenco di attributi che si desidera recuperare:

// Create a list of face attributes that the
// app will need to retrieve
var requiredFaceAttributes = new FaceAttributeType[] {
  FaceAttributeType.Age,
  FaceAttributeType.Gender,
  FaceAttributeType.Smile,
  FaceAttributeType.FacialHair,
  FaceAttributeType.HeadPose,
  FaceAttributeType.Glasses
  };

Quindi, richiamare DetectAsync, passando il flusso di immagini e l'elenco degli attributi di immagine. Gli argomenti returnFaceId e returnFaceLandmarks sono false perché le informazioni correlate a questo punto sono necessarie. La chiamata al metodo è simile al seguente:

// Get a list of faces in a picture
var faces = await faceServiceClient.DetectAsync(inputFile.GetStream(),
  false, false, requiredFaceAttributes);
// Assuming there is only one face, store its attributes
var faceAttributes = faces[0]?.FaceAttributes;

DetectAsync restituisce una matrice di oggetti faccia, ognuno dei quali rappresenta una faccia nell'immagine. Il codice accetta il primo elemento nella matrice, che rappresenta un singolo carattere tipografico e recupera gli attributi di immagine. Si noti come l'ultima riga utilizza l'operatore condizionale (?), null introdotta con c# 6, che restituisce null se il primo elemento nella matrice è null, anziché generare un'eccezione NullReferenceException. Ulteriori informazioni su questo operatore è reperibile in bit.ly/2bc8VZ3. Ora che si dispongano di informazioni sia faccia emozione, è possibile creare un'istanza della classe FaceEmotionDetection e popolare le proprietà, come illustrato nel codice seguente:

FaceEmotionDetection faceEmotionDetection = new FaceEmotionDetection();
faceEmotionDetection.Age = faceAttributes.Age;
faceEmotionDetection.Emotion = faceEmotion.FirstOrDefault().Key;
faceEmotionDetection.Glasses = faceAttributes.Glasses.ToString();
faceEmotionDetection.Smile = faceAttributes.Smile;
faceEmotionDetection.Gender = faceAttributes.Gender;
faceEmotionDetection.Moustache = faceAttributes.FacialHair.Moustache;
faceEmotionDetection.Beard = faceAttributes.FacialHair.Beard;

A questo punto alcune considerazioni:

  • Il valore più alto nell'elenco di emozioni viene eseguito richiamando FirstOrDefault al risultato della chiamata al metodo Scores.ToRankedList, che restituisce un oggetto IEnumerable < string, float >.
  • Il valore restituito da FirstOrDefault qui è un oggetto di tipo KeyValuePair < string, float > e la chiave di tipo stringa archivia il nome di emozioni in un testo leggibile che verrà visualizzato nell'interfaccia Utente.
  • Bicchieri è un'enumerazione che specifica se la superficie rilevata è indossare bicchieri e il tipo. Il codice richiama ToString per ragioni di semplicità, ma è certamente possibile implementare un convertitore per la formattazione della stringa diversi.

Il blocco finale nel corpo del metodo restituisce l'istanza della classe FaceEmotionDetection e implementa la gestione delle eccezioni:

return faceEmotionDetection;
  }
  catch (Exception ex)
  {
    await DisplayAlert("Error", ex.Message, "OK");
    return null;
  }
}

L'ultima operazione che è necessario effettuare è richiamare il metodo DetectFaceAndEmotionAsync personalizzato. È possibile farlo in entrambi i gestori eventi Clicked, appena prima di impostare su false la proprietà IsRunning e IsVisible del controllo ActivityIndicator:

FaceEmotionDetection theData = await DetectFaceAndEmotionsAsync(file);
this.BindingContext = theData;
this.Indicator1.IsRunning = false;
this.Indicator1.IsVisible = false;

La proprietà BindingContext della pagina riceve un'istanza della classe FaceEmotionDetection come origine dati e controlli con associazione a dati figli verranno visualizzate automaticamente le informazioni correlate. Con i modelli come Model-View-ViewModel, includete il risultato con una classe ViewModel. Dopo avere molte operazioni, si è pronti per testare l'applicazione.

Test dell'applicazione

Selezionare la piattaforma di propria scelta e premere F5. Se si utilizzano gli emulatori di Microsoft, è possibile sfruttare gli strumenti dell'emulatore per selezionare una webcam fisica di scattare fotografie ed è possibile simulare una scheda SD per caricare i file. Figura 1 indica il risultato del rilevamento di un'immagine di me, nei dispositivi Android e Windows 10 in esecuzione in modalità desktop.

Le API di emozioni e faccia ha un'incredibile processo perché i valori restituiti sono molto vicino la verità, sebbene ancora approssimativo. Vale la pena sottolineare che la classe FaceEmotionDetection ha alcune proprietà di tipo double, ad esempio Smile, Beard e Moustache. Restituiscono valori numerici, che potrebbero non ha molto senso per l'utente finale in un'applicazione reale. Quindi, nel caso in cui si desidera convertire i valori numerici in stringhe leggibili, è possibile considerare l'implementazione convertitori di valore e l'interfaccia IValueConverter (bit.ly/2bZn01J).

Implementazione di controllo di connettività di rete

Un'applicazione progettata correttamente che deve accedere a risorse su Internet deve innanzitutto sempre verificare la disponibilità di connessione. Per l'accesso della fotocamera e il file system, in xamarin. Forms controllo per la disponibilità di connessione dovrebbe richiedere codice specifico della piattaforma. Fortunatamente, la connettività plug-in è disponibile in consentono, offrendo un metodo condiviso per eseguire questo controllo dal progetto PCL direttamente. Il plug-in offre una classe denominata CrossConnectivity con la proprietà corrente che rappresenta un'istanza singleton della classe. Espone una proprietà bool denominata IsConnected che semplicemente restituisce true se è disponibile una connessione. Per verificare la disponibilità di rete nell'applicazione di esempio, è sufficiente inserire il codice seguente dopo la dichiarazione del metodo DetectFaceAndEmotionAsync:

private async Task<FaceEmotionDetection>
  DetectFaceAndEmotionsAsync(MediaFile inputFile)
{
  if(!CrossConnectivity.Current.IsConnected)
  {
    await DisplayAlert("Network error",
      "Please check your network connection and retry.", "OK");
    return null;
  }

La classe espone anche i seguenti membri interessanti:

  • ConnectivityChanged: Un evento viene generato quando cambia lo stato della connessione. È possibile sottoscrivere questo evento e ottenere informazioni sullo stato di connettività tramite un oggetto di tipo ConnectivityChangedEventArgs.
  • Larghezze di banda: Una proprietà che restituisce un elenco di larghezze di banda disponibile per la piattaforma corrente.

Informazioni aggiuntive relative alla connettività plug-in sono reperibile in bit.ly/2bbU7wu.

Conclusioni

Servizi cognitivo Microsoft fornisce servizi RESTful e le API avanzate basate su machine learning che consentono di creare una nuova generazione di applicazioni. Combinando la potenza di questi servizi con Xamarin, sarà in grado di portare l'interazione dell'utente naturale per le app multipiattaforma per Android, iOS e Windows, offrendo ai clienti un'esperienza straordinaria.


Alessandro Del Sole è stato un MVP Microsoft dal 2008.  Assegnati MVP di cinque volte l'anno, egli ha scritto molti libri, eBook, video didattici e articoli sullo sviluppo .NET con Visual Studio. Del Sole funziona come un esperto sviluppatore soluzione per cervello Sys (cervello sys.it), messa a fuoco sullo sviluppo .NET, consulenza e formazione. È possibile seguirlo su Twitter: @progalex.

Grazie a seguenti esperti tecnici per la revisione dell'articolo: James McCaffrey e James Montemagno