2016 年 10 月

第 31 卷,第 10 期

本文章是由機器翻譯。

Cognitive Services - Xamarin.Forms 中搭配 Microsoft Cognitive Services 的人臉與情緒辨識

Alessandro Del Del

在組建 2016年會議,Microsoft 已宣佈的認知服務的第一次預覽 (microsoft.com/認知服務),一組豐富的跨平台,您可以利用它來建立新一代的自然的使用者互動的任何裝置上的任何平台為基礎的應用程式的 RESTful Api。認知的服務,也就是 「 專案 Oxford 」,都根據機器學習和完全符合交談以-a-平台原理,Microsoft 也願意帶入應用程式生態系統。在較高的層級,認知服務 Api 都是透過 RESTful 服務,以及目前提供下列 Api 的類別︰

  • 目標︰ 目標服務會提供 Api,讓您分析影像和影片辨識表情與工程學,並偵測可採取動作的資訊。此類別包括電腦願景、 圖示、 情緒和視訊的 Api。
  • 語音︰ 語音服務提供 Api,讓您更容易實作文字轉換語音,自然的語音辨識,並甚至辨識人員演講者備忘辨識服務進行通訊。其中包括 Bing 語音、 自訂辨識智慧型服務和喇叭辨識 Api。
  • 語言: 語言服務會自然語言了解,這表示偵測並修正拼字錯誤、 了解語音命令,以及分析包括情感和關鍵片語的複雜文字導向。其中包括 Bing 拼字檢查、 語言了解智慧型服務、 語言分析、 文字分析和語言模型的 Web Api。
  • 知識︰ 知識服務協助應用程式藉由尋找個人化的產品建議、 事件、 位置和學術論文或日誌擴充客戶的知識。其中包括學術知識、 實體連結智慧服務、 知識探索服務和建議 Api。
  • 搜尋: 搜尋服務會根據 Bing,並可讓您在自己的應用程式中實作功能強大的搜尋工具。內含的服務名稱是真正懂︰ [自動建議 Bing,映像到 Bing 搜尋、 Bing 新聞搜尋、 視訊到 Bing 搜尋和 Bing 網頁搜尋服務 Api。

在本文中我將說明如何結合朝詳細資料和情緒擷取圖片從相機或專輯在磁碟中建立的 C# 和 Visual Studio 2015 Android、 iOS 或 Windows 10 上執行的 Xamarin.Forms 應用程式中,您可以採取的正面和情緒 Api。[圖 1 顯示發行項的教學課程的結果。值得一提,雖然本文使用 Xamarin.Forms,可以完成相同與傳統的 Xamarin 應用程式,以及其他任何支援 REST 的平台。我假設您有基本知識,建立 Xamarin.Forms 應用程式和概念的相關程式碼共用。如果沒有,請確定您閱讀我先前的文章︰ 「 建置跨平台 UX 使用 Xamarin.Forms 」 (msdn.com/magazine/mt595754) 和 「 使用 Xamarin.Forms 行動平台共用的 UI 程式碼 」 (msdn.com/magazine/dn904669)。

圖示和使用 Xamarin.Forms 的跨平台應用程式上的情緒辨識
[圖 1 面和使用 Xamarin.Forms (左側的 Android 裝置、 Windows 10 Desktop 右邊) 的跨平台應用程式上的情緒辨識

訂閱的認知服務 Api

若要建置可利用的認知服務的應用程式,您必須訂閱您感興趣的服務。目前,Microsoft 會提供您可以在 [訂閱] 頁面中啟用的免費試用 (bit.ly/2b2rKDO),但目前的計劃可能會受到變更未來。當在頁面上,向 Microsoft 帳戶,然後按一下 [「 要求新的試用版 」。 然後,您會看到一份可用的服務。請確定您選取的表面和情緒 Api 的免費預覽。此時,您的訂閱] 頁面會顯示作用中服務; 的清單您應該會看到朝和情緒 Api 訂閱。[圖 2 示範根據我的訂閱。請注意,針對每個作用中的服務,有兩個密碼金鑰。您將需要一個用來叫用 Api。現在,將它們保存在隱藏。建立 Xamarin.Forms 應用程式時,會取消隱藏索引鍵。

啟動訂閱,朝和情緒 Api
[圖 2 啟動訂閱,朝和情緒 Api

一般而言,認知的服務提供 RESTful Api,這表示您可以在任何平台上的 HTTP 要求這些服務與支援其他任何語言互動。例如,下列 HTTP POST 要求示範如何將影像傳送至情緒偵測情緒辨識服務︰

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

當然,您必須使用自己的索引鍵與真正的映像位址假影像 URL 的其中一個取代 Ocp Apim-訂閱-索引鍵。在 exchange 中,辨識表情服務就會傳送回偵測的結果做為 JSON 回應,如所示 [圖 3

[圖 3 情緒辨識服務偵測回應

[
  {
    "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
    }
  }
]

[圖 3] 中的範例回應會顯示如何情緒服務傳回的矩形中偵測到表面,且陣列呼叫包含一份情緒和介於 0 和 1,指出有多少情緒分數就是為 true。一般情況下,將 HTTP 要求傳送至 RESTful 服務,而預期的 JSON 回應是常見的方法與所有認知的服務。不過,對於使用 C#.NET 開發人員,Microsoft 也提供用戶端可攜式類別庫,您可以從 NuGet,該讓它更輕鬆地與服務互動以 managed 程式碼和物件導向的方式。這是您很快面臨和情緒 Api 的案例。別忘了瞧正式文件,其中包含以 REST 方法和用戶端程式庫提供的範例 (bit.ly/2b2KJrB)。既然您已經註冊了這兩項服務,並可讓您的金鑰,它是使用 Xamarin.Forms 和 Microsoft Visual Studio 2015 建立跨平台應用程式的時間。

建立 Xamarin.Forms 應用程式

如您所知,您可以跨平台應用程式使用 Xamarin.Forms 選擇建立可移植或共用專案範本。我將說明如何利用用戶端程式庫的認知服務 api,因為範例應用程式會被可攜式類別庫 (PCL) 模型為基礎。在 Visual Studio 2015 中,選取 [檔案 |新的專案。如果您已安裝最新的更新從 Xamarin (xamarin.com/download),您會發現新的專案範本,稱為空白 Xaml 應用程式 (Xamarin.Forms 可攜式) 下的 Visual C#、 跨平台] 節點的 [新增專案] 對話方塊。這是有趣的範本可提供空白的 XAML 網頁,並可避免需要手動建立一個。[圖 4 顯示新的範本。

呼叫 FaceEmotionRecognition 方案,然後按一下 [確定]。在產生期間的方案,將會要求您指定之最小的目標版本的通用 Windows 平台 (UWP) 專案。這就交給您的選擇,但建議您以最高可用的版本為目標。

建立新的 Xamarin.Forms 應用程式
[圖 4 建立新的 Xamarin.Forms 應用程式

為 Xamarin 簡介外掛程式

範例應用程式將使用的認知的服務 Api,辨識朝詳細資料以及從使用現有圖片從裝置或拍攝新相片從相機的圖片的情緒。這表示應用程式將會需要存取網際網路,以連接到服務,並將需要提供納入,並選取圖片的能力。雖然應用程式可以輕鬆地連線到網路,您必須負責,身為開發人員,以檢查網路可用性。實際上,檢查網路狀態等功能,並拍攝圖片在 Android、 iOS 和 Windows 專案中撰寫特定程式碼需要。幸好,Xamarin 支援外掛程式,您可以使用 Xamarin.Forms 在您可以安裝到 PCL 專案中,因此它們會為您執行此作業。外掛程式是從 NuGet,原生 Api 包裝成一般的程式碼實作,並叫用的 PCL 專案中安裝的程式庫。還有大量的外掛程式,開發和 Xamarin 和其他人建立並發佈的開發人員社群所支援的部分。是所有開放原始碼外掛程式,以及列出 GitHub 上的 bit.ly/29XZ3VM。在本文中我將示範如何使用連線和媒體外掛程式。

安裝 NuGet 封裝

方案已準備就緒,的首先您需要執行時,安裝下列 NuGet 封裝︰

  • Microsoft.ProjectOxford.Face: 安裝用戶端程式庫的表面 api,而且必須安裝至 PCL 專案只。
  • Microsoft.ProjectOxford.Emotion: 情緒 api 和 like 朝 API,必須安裝至 PCL 專案只,安裝用戶端程式庫。
  • Xam.Plugin.Connectivity: Xamarin.Forms 包含外掛程式的連線,並必須安裝到方案中的所有專案。
  • Xam.Plugin.Media: Xamarin.Forms 包含媒體外掛程式,而連接 API,例如必須安裝到方案中的所有專案。

一旦您已安裝必要的 NuGet 封裝,請確定您撰寫程式碼,以便將重新整理所有參考之前建置方案。

設計 UI

範例應用程式的 UI 是由單一網頁所組成。為了簡單起見,我將使用自動產生的 MainPage.xaml 檔案。此頁面會定義兩個按鈕,一個用於圖片從相機,一個用於上傳現有的映像。將顯示忙碌狀態,等待回應的服務; ActivityIndicator 控制項影像控制項將會顯示選取的映像。StackLayout 面板資料繫結至選取的圖片會包含偵測結果的自訂類別內的標籤數目。[圖 5 顯示頁面的完整 XAML 程式碼。

圖 5 主要的 UI 頁面

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
  xmlns:x="http://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>

下一個步驟是準備儲存表面和情緒偵測結果的位置。

儲存偵測結果的類別

手動擴展的正面和情緒偵測結果 UI 中的標籤,但已建立的自訂類別的最佳作法。這是較為物件導向的方法,不僅也可讓資料繫結至 UI 的類別的執行個體。話雖如此,我們要建立新的類別稱為 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; }
}

每個屬性都有簡單易懂的名稱,並會儲存來自朝和情緒 Api 組合的資訊。

宣告服務用戶端

撰寫任何程式碼之前,最好在其中新增下列 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;

這些會簡化認知服務 Api 和外掛程式的物件名稱的引動過程。朝 Api 和情緒 Api 提供 Microsoft.ProjectOxford.Face.FaceServiceClient 和 Microsoft.ProjectOxford.Emotion.EmotionServiceClient 類別,以連線到認知的服務,並分別傳回朝和情緒詳細資料的相關資訊。您第一次需要執行的是宣告執行個體的同時,將您的秘密金鑰傳遞至建構函式,如下所示︰

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

請注意,您必須提供您自己的秘密金鑰。表面和情緒 API 的秘密金鑰,請參閱 Microsoft 認知服務入口網站的 [訂閱] 頁面 (bit.ly/2b2rKDO),如下所示 [圖 2

擷取和載入影像

Xamarin.Forms,存取網路攝影機和檔案系統需要撰寫平台特定程式碼。更簡單的方法正在使用 Xamarin.Forms,可讓您挑選圖片及視訊從磁碟和 PCL 專案中,從數位相機與幾行程式碼取得圖片及視訊媒體外掛程式。此外掛程式會公開一個稱為 CrossMedia 會公開下列成員的類別︰

  • 目前的︰ 傳回 CrossMedia 類別的單一執行個體。
  • IsPickPhotoSupported 和 IsPickVideoSupported: Bool 屬性會傳回 true,如果目前的裝置支援選取的圖片及視訊從磁碟。
  • PickPhotoAsync 和 PickVideoAsync: 方法會叫用平台特定的 UI,以分別選取本機圖片或視訊,並傳回的物件型別 f i l e。
  • IsCameraAvailable: Bool 屬性則傳回 true,如果裝置具有內建的攝影機。
  • IsTakePhotoSupported 和 IsTakeVideoSupported: Bool 屬性會傳回 true,如果目前的裝置支援製作圖片及視訊從攝影機。
  • TakePhotoAsync 和 TakeVideoAsync: 方法可啟動,才會將圖片或視訊,內建的攝影機和傳回的物件型別 f i l e。

請不要忘記在存取相機應用程式資訊清單中設定適當的權限。比方說,UWP 專案中您需要將 [網路攝影機] 與 [圖片庫的權限,而在 Android 上,您需要相機、 READ_EXTERNAL_STORAGE 和 WRITE_EXTERNAL_STORAGE 權限。忘了將設定必要的權限,將會導致執行階段例外狀況。現在讓我們編寫 Clicked 事件處理常式 UploadPictureButton 所示的 [圖 6

[圖 6 從磁碟中選取圖片

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

程式碼會先檢查是否選取的圖片支援,則會顯示錯誤訊息,如果 IsPickPhotoSupported 傳回 false。PickPhotoAsync (以及 PickVideoAsync) 傳回的 MediaFile Plugin.Media 命名空間中定義的類別,表示選取的檔案類型的物件。您必須叫用其 GetStream 方法傳回的資料流,可以用於做為來源影像控制項透過其 FromStream 方法。使用相機拍照也是非常簡單,如所示 [圖 7

[圖 7 使用相機拍照

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

此處值得注意的一點是 TakePhotoAsync 採用 StoreCameraMediaOptions,可讓您指定的位置的物件類型的參數,以及如何儲存圖片。如果您想要儲存到本機的相簿,圖片,或如果您想要儲存到不同的資料夾,您可以設定 [目錄] 屬性,您可以 SaveToAlbum 屬性設為 true。如您所見,非常有限的精力與幾行程式碼,您的應用程式可以輕鬆地利用支援的平台的一項重要功能。

偵測情緒和實作朝辨識

現在就開始實作表面和情緒辨識。因為這是必備的文章,我將著重在簡化。我將示範如何實作上一個單一的面圖片中的偵測和我將說明最重要的物件和 Api 中的成員。我也會提供您建議如何實作更詳細的偵測,適當的位置。根據這些假設,我們要開始寫入的非同步方法,會執行偵測。第一段有關情緒偵測,而且它看起來像這樣︰

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();

方法會接收由選取或拍照 MediaFile。透過在圖片上的表面偵測情感很簡單,因為您只需叫用 RecognizeAsync 方法,從 EmotionServiceClient 類別的執行個體。這個方法可以接收資料流或 URL,做為引數。在此情況下,它會從 MediaFile 物件取得資料流。RecognizeAsync 傳回情緒物件的陣列。陣列中的各種情緒會儲存在圖片中的單一朝上偵測到的情感。假設在選取的圖片具有一個圖示,程式碼會擷取陣列中的第一個項目。情緒型別公開 (expose) 名為分數,其中包含八個情緒名稱的清單以及其近似的值的屬性。更具體來說,您會得到 IEnumerable < 字串、 float >。藉由叫用其 ToRankedList 方法,就可以偵測到的情感的排序的清單。Api 無法精確地偵測到單一的情緒。相反地,它們偵測到許多可能的情感。大約實際的情緒上表面,但仍可以檢查其他值,就會傳回最高的值。  此清單中最高的值表示最高的層級的估計的可能性,可能是朝上實際的情緒情緒。進一步了解,請考慮下列排名的情感清單擷取的偵錯工具資料提示,這依據所示的範例圖片協助 [圖 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]}

如您所見,快樂具有值為 1,這是最高的清單中的實際情緒估計的可能性。下一個步驟偵測朝屬性。FaceServiceClient 類別會公開的功能極為強大的 DetectAsync 方法。它要不只擷取朝屬性,例如性別、 年齡,和嘴,但也可辨識的人、 傳回朝矩形 (區域圖偵測圖示) 和 27 朝地標點,可讓識別資訊例如位置鼻子、 說話、 耳朵和眼睛的圖片上的應用程式。DetectAsync 具有下列簽章︰

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

在其最基本的引動過程,DetectAsync 需要一張圖片或 URL 所指向的資料流,並傳回朝矩形中的,同時 returnFaceId 和 returnFaceLandmarks 選擇性參數,分別可讓您識別個人,並傳回朝地標。朝 Api 可讓您建立群組的人,並將 id 指派給每個人,讓您可以輕鬆地執行辨識。朝地標改為可用來識別的字體特性,並可透過朝物件的 FaceLandmarks 屬性。識別和地標已超出本文的範圍,但您可以深入了解這些主題,在 bit.ly/2adPvoPbit.ly/2ai9WjV, 分別。同樣地,我不會說明如何使用朝地標,但這些儲存在 FaceLandmarks 朝物件屬性。在目前的範例案例中,目標是擷取朝屬性。首先您必須是 FaceAttributeType 列舉型別,定義您想要擷取的屬性清單的陣列︰

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

接下來,叫用 DetectAsync,傳遞的影像資料流和朝屬性清單。ReturnFaceId 和 returnFaceLandmarks 引數為 false,因為此時是不必要的相關的資訊。方法引動過程看起來像這樣︰

// 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 傳回每個都代表在圖片中的正面朝物件的陣列。程式碼則需要第一個項目陣列,代表一個單一的形象,並且擷取其表面屬性中。請注意最後一行使用 null 條件運算子 (?),所導入的 C# 6,會傳回 null,如果陣列中的第一個項目也是 null,而非擲回 NullReferenceException 的方式。有關這個運算子的詳細資訊,請參閱 bit.ly/2bc8VZ3。有正面和情緒資訊之後,您可以建立 FaceEmotionDetection 類別的執行個體,並填入其屬性,如下列程式碼所示︰

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;

此時一些考量︰

  • 情感清單中的最高值所傳回 IEnumerable < 字串、 float > Scores.ToRankedList 方法引動過程的結果上叫用 FirstOrDefault。
  • 以下是 KeyValuePair < 字串、 float > 型別的物件和字串類型的索引鍵儲存情緒名稱將顯示在 UI 中以人們可讀取文字 FirstOrDefault 所傳回的值。
  • 眼鏡是一種列舉,指定是否偵測到的朝穿著眼鏡和類型。為了簡單起見,程式碼叫用的 ToString,但您可以明確地實作不同的字串格式的轉換子。

在方法主體中的最後一個區塊傳回 FaceEmotionDetection 類別的執行個體,並實作例外狀況處理︰

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

您必須執行的最後一件事是叫用自訂 DetectFaceAndEmotionAsync 方法。您可以在這兩個 Clicked 事件處理常式中,內部之前將 ActivityIndicator 控制項的 IsRunning 和 IsVisible 屬性設定為 false:

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

Messageencodingbindingelement 屬性頁面的接收 FaceEmotionDetection 類別,做為資料來源的執行個體,並資料繫結的子系控制項將會自動顯示相關的資訊。利用像是 Model View ViewModel 模式,您會包裝 ViewModel 類別的結果。在許多工作之後, 就可以測試應用程式。

測試應用程式

選取您所選擇的平台,然後按 F5。如果您使用的 Microsoft 模擬器,您可以利用模擬器的工具,來選取實體網路攝影機以拍照,並可讓您模擬檔案上傳到 SD 卡。[圖 1 顯示偵測的結果,我的圖片、 Android 裝置和桌面模式執行的 Windows 10。

表面和情緒 Api 沒有令人讚嘆的作業因為傳回的值已經非常接近坦白說,雖然仍近似。值得一提的是 FaceEmotionDetection 類別具有一些屬性的型別上雙線笑臉、 鬍子等鬍髭。它們會傳回數字的值,可能不太合理的實際的應用程式中的使用者。因此,如果您想要將這些數字的值轉換成人們可讀取的字串,您可以考慮實作值轉換器和 IValueConverter 介面 (bit.ly/2bZn01J)。

實作網路連線能力檢查

設計良好的應用程式需要存取網際網路上的資源,請務必檢查連線可用性第一次。至於相機和檔案系統存取,請在 Xamarin.Forms 連線可用性檢查應該需要平台特定程式碼。所幸,外掛程式的連線有協助,提供直接從 PCL 專案執行這項檢查的共用的方式。外掛程式提供稱為 CrossConnectivity 目前內容,表示此類別的單一執行個體的類別。它會公開一個稱為 IsConnected,只會傳回連接是否可用,則為 true 的 bool 屬性。若要檢查的範例應用程式中的網路可用性,只要將下列程式碼之後 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;
  }

這個類別也會公開下列值得注意的成員︰

  • ConnectivityChanged: 連線狀態變更時引發的事件。您可以訂閱此事件,並取得有關透過 ConnectivityChangedEventArgs 型別的物件的連線狀態。
  • 頻寬︰ 此屬性,傳回目前的平台的可用頻寬的清單。

外掛程式的連線能力的其他資訊,請參閱 bit.ly/2bbU7wu

總結

Microsoft 認知服務提供 RESTful 服務和豐富的 Api 可讓您的機器學習服務為基礎建立新一代應用程式。藉由使用 Xamarin 結合這些服務的強大功能,您可以讓您跨平台應用程式的自然使用者互動,Android、 iOS 和 Windows,讓您的客戶令人讚嘆的經驗。


Alessandro Del Sole 2008年之後已經是 Microsoft MVP。 獲得一年五倍的 MVP,他著有許多書籍、 電子書,說明影片和使用 Visual Studio.NET 開發相關的文件。Del Sole 擔任大腦 Sys 方案開發人員專家 (大腦 sys.it)、.NET 開發訓練和諮詢焦。您也可以關注他的 Twitter: @progalex

感謝閱本篇文章的下列技術專家︰ James McCaffrey 以及 James Montemagno