2016 年 11 月

第 31 卷,第 11 期

本文章是由機器翻譯。

辨識服務 - 透過 Xamarin 與 Microsoft Computer Vision API 觀看世界

Alessandro Del Del

在最後一篇文章中,我會提供 Microsoft 認知服務,描述可用的 RESTful Api,並使用 Xamarin.Forms 和 C# 撰寫的跨平台應用程式中展示的正面和情緒 Api 的簡介 (msdn.microsoft.com/magazine/mt742868)。在本文中,我將討論另一組重要的 Api,稱為電腦願景。您會想要讀取前一篇文章,您在開始一個因為我假設您熟悉認知服務,我說明了某些概念之前,而且因為某些 NuGet 封裝和從先前的範例應用程式的程式碼片段會重複使用。這說過,讓我們開始討論 Microsoft 電腦願景 Api。

開始使用電腦願景 Api

電腦願景 Api 可讓影像是描述,使用自然語言分析。您可以將圖片上傳到 Computer Vision 服務或指向影片 URL,不需要自行建構或設定描述的格式,即可得到非常自然的描述。但不止於此,電腦版本可以包含文字、 影像執行光學字元辨識 (OCR),它會掃描要偵測名人表面的影像。如同其他服務,電腦版本為基礎的機器學習,並支援其他部分,這表示您執行 HTTP 要求,並取得 JSON 回應。在 JSON [圖 1 摘錄自電腦願景分析的回應會顯示圖片,取自的官方文件 bit.ly/2a45kQI

[圖 1 的映像的電腦願景分析的結果

{
  "description": {
    "tags": [
      "person",
      "man",
      "outdoor",
      "window",
    ],
    "captions": [
      {
        "text": "Satya Nadella sitting in front of a building",
        "confidence": 0.38035155997373377
      }
    ]
  },
  "requestId": "ed2de1c6-fb55-4686-b0da-4da6e05d283f",
  "metadata": {
    "width": 1500,
    "height": 1000,
    "format": "Jpeg"
  }
}

如您所見,回應會包含一位名人分配在做什麼的圖片,以列出的其他資訊,例如標記和圖片的大小和格式的自然語言描述。而這是一些您可以從電腦願景服務取得的資訊。

執行 HTTP 要求肯定的運作方式,但身為.NET 開發人員,您可能會偏好不同的方法。如同朝和情緒 Api 中,Microsoft 也提供可攜式的用戶端程式庫 (PCL,) 您可以使用 C# 應用程式,包括.NET 和 Xamarin,這可讓您透過使用物件導向的方法很方便的方法叫用此服務中的電腦版本的。稍後我將使用此程式庫。

訂閱電腦願景 Api

如同其他認知的服務,若要使用電腦願景 Api 必須註冊服務,並取得密碼金鑰,以在您的程式碼中使用。若要完成此動作,直接前往 [訂閱] 頁面 (bit.ly/2b2rKDO),並要求新的試用版的電腦願景 api。[圖 2 顯示您的訂閱註冊之後。

註冊電腦願景 Api
[圖 2 註冊電腦願景 Api

如您所見,您會取得兩個密鑰。您將需要一個稍後就可以撰寫 C# 程式碼。

建立 Xamarin.Forms 應用程式並安裝 NuGet 封裝

啟動 Visual Studio 2015,並建立新的 Xamarin.Forms 專案使用空白 XAML 應用程式 (Xamarin.Forms 可攜式)] 專案範本。呼叫 ComputerVisionSample 的新專案,然後按一下 [確定]。準備好時,安裝下列 NuGet 封裝︰

Microsoft.ProjectOxford.Vision 電腦願景 api 安裝用戶端程式庫,而且必須安裝至只 PCL 專案。

Xam.Plugin.Connectivity Xamarin.Forms 包含外掛程式的連線,而且必須安裝到方案中的所有專案。它會用來檢查有網路連線,然後再嘗試將透過網際網路提出要求。

Xam.Plugin.Mediacontains Xamarin.Forms 外掛程式的媒體,必須安裝到方案中的所有專案。它將會用來選取圖片共用的程式碼,而不必撰寫平台特定程式碼。

確定您在此時建置方案,因此將會重新整理所有參考。現在讓我們深入了解電腦願景 Api,分析三個主要案例。

描述分析 Api 的圖片

電腦版本的用戶端程式庫公開 (expose) 名為 Microsoft.ProjectOxford.Vision.VisionServiceClient,也就是物件的類別可用來將要求傳送至服務,而且,公開屬性包含分析結果。這個類別會用於我為目標的所有案例。第一個案例描述的圖片,我是指所取得的圖片的代表,描述依據人們可讀取的自然語言。此服務會傳回的回應也包含主控項的色彩、 偵測到的表面、 標記、 映像類型和大小等資訊,以及也是否圖片包含成人或賊內容。為了描述圖片,VisionServiceClient 類別會公開兩種方法︰ AnalyzeImageAsync 和 DescribeAsync。後者提供較少的詳細資訊,以及通常用來擷取只自然語言描述的圖片,則 AnalyzeImageAsync 傳回更多詳細資訊。這兩種方法會將其回應存入 Microsoft.ProjectOxford.Vision.Contract.AnalysisResult 型別的物件。我將在本文中使用 AnalyzeImageAsync。這個方法有兩個多載、 一個接受資料流和一個接受 URL,指向 [映像。這兩個多載需要指定一組您想要擷取與圖片的資訊。這組資訊會以從 Microsoft.ProjectOxford.Vision.VisualFeature 列舉值的陣列。在 MainPage.xaml 頁面的範例應用程式中,我將實作圖片的描述。[圖 3 示範如何實作詳細的分析方法。

圖 3 說明分析圖片

private async Task<AnalysisResult> AnalyzePictureAsync(Stream inputFile)
{
  // Use the connectivity plug-in to detect
  // if a network connection is available
  // Remember using Plugin.Connectivity directive
  if (!CrossConnectivity.Current.IsConnected)
  {
    await DisplayAlert("Network error",
      "Please check your network connection and retry.", "OK");
    return null;
  }
  VisualFeature[] visualFeatures = new VisualFeature[] { VisualFeature.Adult,
    VisualFeature.Categories, VisualFeature.Color, VisualFeature.Description,
    VisualFeature.Faces, VisualFeature.ImageType, VisualFeature.Tags };
  AnalysisResult analysisResult =
    await visionClient.AnalyzeImageAsync(inputFile,
    visualFeatures);
  return analysisResult;           
}

請注意程式碼如何使用外掛程式的連線來偵測網路連線,如我在前一篇文章中所述。有三個關鍵點 [圖 3。第一個點有關,您想要擷取的資訊。VisualFeature 值的陣列包含的資訊,最詳細的清單,並包含來自 VisualFeature 列舉的值。這些簡單易懂的名稱,也會偵測成人和賊內容、 圖片、 主控項的色彩、 自然語言描述、 表面、 映像的資訊和標記的清單一份分類清單。我所提供的表面值為了完整起見,但我不會實際使用此結果因為您可以擷取使用朝 API 的詳細的資訊。第二個重點是 AnalyzeImageAsync,將資料流傳送至服務與您想要擷取的資訊清單中,引動過程,並將回應儲存成 AnalysisResult 型別的物件。這個類別是第三個關鍵點,定義於 [圖 4

圖 4] AnalysisResult 類別定義

namespace Microsoft.ProjectOxford.Vision.Contract
{
  public class AnalysisResult
  {
    public AnalysisResult();
    public Adult Adult { get; set; }
    public Category[] Categories { get; set; }
    public Color Color { get; set; }
    public Description Description { get; set; }
    public Face[] Faces { get; set; }
    public ImageType ImageType { get; set; }
    public Metadata Metadata { get; set; }
    public Guid RequestId { get; set; }
    public Tag[] Tags { get; set; }
  }
}

若要查看此定義,AnalysisResult 型別,程式碼編輯器中的以滑鼠右鍵按一下並選取移至定義 (或查看定義,如果您不想要保留使用中視窗)。如您所見,定義會公開包含所需的資訊,透過特定物件的屬性。使用 [移至定義每個屬性的型別,您可以了解每個特定的物件的定義方式,因此,如何使用它在您的應用程式 (與資料繫結,例如)。比方說,描述型別定義,如下所示︰

public class Description
{
  public Description();
  public Caption[] Captions { get; set; }
  public string[] Tags { get; set; }
}

這裡最重要的屬性是標題,標題物件的陣列。每個標題包含服務從圖片,提供透過其 Text 屬性擷取的人們可讀取描述。成人類別定義,如下所示︰

public class Adult
 {
   public Adult();
   public double AdultScore { get; set; }
   public bool IsAdultContent { get; set; }
   public bool IsRacyContent { get; set; }
   public double RacyScore { get; set; }
 }

這是簡單的類別,而且會公開兩個屬性,傳回 true,如果圖片包含成人或賊內容,再加上兩個其他屬性代表該結果的信心。當您想要限制的內容可用性,這是特別有用。現在看一下色彩類別定義︰

public class Color
{
  public Color();
  public string AccentColor { get; set; }
  public string DominantColorBackground { get; set; }
  public string DominantColorForeground { get; set; }
  public string[] DominantColors { get; set; }
  public bool IsBWImg { get; set; }
}

這個類別用來儲存圖片,例如輔色、 主控項的前景和背景色彩和主控項的色彩的陣列中偵測到的色彩清單。它也會公開一個稱為 IsBWImg,型別 bool,則傳回 true,如果黑白圖片的屬性。當您想要透過資料繫結 UI 中呈現的資訊,將協助了解如何定義這些物件和它們公開的屬性。我會讓您瀏覽 AnalysisResult 用來儲存分析資訊的其他類別的定義。因為它是,AnalysisResult 執行個體可以是資料繫結至一些 UI 項目來顯示資訊非常容易,並會對此短時間內。請考慮 [圖 5, ,其中顯示的 XAML 定義所需的範例應用程式的 UI 的完整清單。

[圖 5 UI 定義的映像描述]

<?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:ComputerVisionSample"
             x:Class="ComputerVisionSample.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" />
  <ScrollView Padding="10">
    <StackLayout>
      <StackLayout Orientation="Horizontal">
        <Label Text="Adult content: "/>
        <Label Text="{Binding Adult.IsAdultContent}"/>
      </StackLayout>
      <StackLayout Orientation="Horizontal">
        <Label Text="Racy content: "/>
        <Label Text="{Binding Adult.IsRacyContent}"/>
      </StackLayout>
      <StackLayout Orientation="Horizontal">
        <Label Text="Description: "/>
        <Label Text="{Binding Description.Captions[0].Text}"/>
      </StackLayout>
      <StackLayout Orientation="Horizontal">
        <Label Text="Accent color: "/>
        <Label Text="{Binding Color.AccentColor}"/>
      </StackLayout>
      <StackLayout Orientation="Horizontal">
        <Label Text="Tags: "/>
        <ListView ItemsSource="{Binding Tags}">
          <ListView.ItemTemplate>
            <DataTemplate>
              <ViewCell>
                <Label Text="{Binding Name}"/>
              </ViewCell>
            </DataTemplate>
          </ListView.ItemTemplate>
        </ListView>
      </StackLayout>      
    </StackLayout>
  </ScrollView>
</ContentPage>

UI 會定義兩個按鈕,一個用於選擇圖片從裝置和另一個用於圖片從相機、 加上顯示的作業正在進行中 ActivityIndicator。在選取的圖片會顯示影像控制項內。(我使用這些控制項在前一篇文章,太)。 請注意,資料繫結 Label 控制項中的表示方式。例如,您可以繫結的 Text 屬性直接 Adult.IsAdultContent 和 Adult.IsRacyContent AnalysisResult 執行個體,而不是執行複雜的繫結。同樣地,您可以擷取圖片直接繫結至 AnalysisResult.Description 屬性所公開的標題集合中的第一個標題物件的 Text 屬性的自然語言描述。當然,這是正常如果只有一個標題,或如果您只想看到的第一個結果。不過,標題可能包含多個標題物件並在此情況下,您可能想要選擇不同的資料繫結。相同的直接繫結會對 Color.AccentColor 屬性。標記,UI 會顯示標記使用 ListView 控制項,顯示每個標記名稱的標籤的資料範本的清單。在程式碼後置中,您必須先實作兩個按鈕的事件處理常式中所示 [圖 6。程式碼會使用我已經提過在前一篇文章中,因此我將不會在這裡討論的媒體外掛程式。

[圖 6] 按鈕點選事件處理常式

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());
  var analysisResult = await AnalyzePictureAsync(file.GetStream());
  this.BindingContext = analysisResult;
  this.Indicator1.IsRunning = false;
  this.Indicator1.IsVisible = false;
}
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());
  var analysisResult = await AnalyzePictureAsync(file.GetStream());
  this.BindingContext = analysisResult;
  this.Indicator1.IsRunning = false;
  this.Indicator1.IsVisible = false;
}

此處的重點是 AnalyzePictureAsync 方法,其結果的引動過程 (AnalysisResult 的執行個體) 指派給做為資料來源] 頁面。這可讓資料繫結中所示的 UI 項目 [圖 6。接著您必須宣告並具現化 VisionServiceClient 類別,如下所示︰

private readonly VisionServiceClient visionClient;
public MainPage()
{
  InitializeComponent();
  this.visionClient =
    new VisionServiceClient("YOUR-KEY-GOES-HERE");
}

請注意,您必須提供一個秘密金鑰註冊電腦願景 api 時,您得到的結果。最後,請務必在應用程式的資訊清單中加入適當的權限。比方說,通用 Windows 平台 (UWP) 專案所需的網際網路、 網路攝影機和圖片庫的功能。和 Android 專案所需的網際網路、 相機、 READ_EXTERNAL_STORAGE 和 WRITE_EXTERNAL_STORAGE 權限。您現在可以在您最愛的裝置或模擬器上啟動應用程式。[圖 7 會顯示在桌面模式中,使用映像和所需執行的 UWP 版本。

描述與電腦願景 Api 的圖片
[圖 7 說明與電腦的圖片 Vision Api

在所有可用的資訊,您將可能是最對的印象深刻 AnalysisResult 類別提供不費吹灰之力自動產生,人們可讀取描述的描述屬性的內容。

擷取文字從 ocr 的圖片

OCR 是文字的電子影像轉換成可編輯的文字。大部份的掃描器隨附 OCR 軟體,可讓您產生從映像包含文字,例如雜誌頁面可以讓您編輯文件。電腦願景 Api 組提供 OCR 服務,可擷取映像,無論文字的語言內的文字。OCR 基本上會導致字串物件。若要了解 OCR Api 的運作方式,讓我們來加入新的 XAML 頁面 PCL 專案。在 [方案總管中以滑鼠右鍵按一下 ComputerVisionSample (可攜式) 專案中,選取 [新增] |新的項目,然後在 [加入新項目] 對話方塊中,選取 [跨平台] 節點中的表單 Xaml 頁面項目。呼叫新的視窗 OcrRecognitionPage。VisionServiceClient 類別會公開一個稱為 RecognizeTextAsync,OCR 對映像的方法。這個方法會接受資料流或指向影像的 URL,您可以選擇性地指定語言。如果您未指定語言,RecognizeTextAsync 會嘗試自動偵測語言。它會傳回物件的型別 Microsoft.ProjectOxford.Vision.Contract.OcrResults,這是有點複雜,需要更多說明。現在,請考慮下列程式碼會在資料流上叫用 OCR 服務和自動偵測語言︰

private async Task<OcrResults> AnalyzePictureAsync(Stream inputFile)
{
  if (!CrossConnectivity.Current.IsConnected)
  {
    await DisplayAlert("Network error",
      "Please check your network connection and retry.", "OK");
    return null;
  }
  OcrResults ocrResult = await visionClient.RecognizeTextAsync(inputFile);
  return ocrResult;
}

請注意如何您一定要檢查網路連線的第一次。如果您想要指定語言,您傳遞給 RecognizeTextAsync RecognizeLanguage 類別的執行個體,如下所示︰

OcrResults ocrResult =
  await visionClient.RecognizeTextAsync(inputFile,
  new RecognizeLanguage(){ ShortCode = "it", LongName = "Italian"  }

在 WPF 的正式範例應用程式 bit.ly/2ahHum3 顯示支援的語言和程式碼的完整清單。OcrResults 類別定義,如下所示︰

public class OcrResults
{
  public OcrResults();
  public string Language { get; set; }
  public string Orientation { get; set; }
  public Region[] Regions { get; set; }
  public double? TextAngle { get; set; }
}

語言、 方向和 TextAngle 屬性表示偵測到的語言、 方向和已辨識文字的角度。區域是區域物件的陣列。每個區域代表包含文字、 影像區域和區域類型具有名線條列物件的陣列,每個均代表單行文字區域中。每個列物件有一個屬性稱為每個均代表單一文字行中的字,Word 物件的陣列。這是稍微複雜的階層架構中,但它提供非常精確的結果,您可以使用 API 偵測到每一個文字。別忘了要移至定義用來調查每個類別定義。這種複雜性,因為 UI 的某些部分將會產生執行階段。現在,在 XAML 中的新頁面,加入顯示的程式碼 [圖 8, ,它會宣告一些熟悉控制 (兩個按鈕,映像,ActivityIndicator),並將會收到的直線和單字清單 StackLayout 偵測到。請注意如何程式碼也會將標籤控制項來顯示偵測到的語言。

[圖 8 UI 準備光學字元辨識

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="https://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="ComputerVisionSample.OcrRecognitionPage">
  <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">
      <Label Text="Language: "/>
      <Label Text="{Binding Language}"/>
    </StackLayout>
    <ScrollView>
      <StackLayout x:Name="DetectedText">
      </StackLayout>
    </ScrollView>
  </StackLayout>
</ContentPage>

我之前提過,就會在執行階段建構 UI 的某些部分。更具體來說,我需要逐一查看區域陣列,然後其巢狀線條陣列,以偵測文字陣列中的每一個文字。這示範於 [圖 9, 、 StackLayout 產生的每一行的位置。

[圖 9 逐一查看文字區域和線條

private void PopulateUIWithRegions(OcrResults ocrResult)
{
  // Iterate the regions
  foreach (var region in ocrResult.Regions)
  {
    // Iterate lines per region
    foreach (var line in region.Lines)
    {
      // For each line, add a panel
      // to present words horizontally
      var lineStack = new StackLayout
      { Orientation = StackOrientation.Horizontal };
      // Iterate words per line and add the word
      // to the StackLayout
      foreach (var word in line.Words)
      {
        var textLabel = new Label { Text = word.Text };
        lineStack.Children.Add(textLabel);
      }
      // Add the StackLayout to the UI
      this.DetectedText.Children.Add(lineStack);
    }
  }
}

其餘的程式碼就非常簡單。首先,宣告並具現化 VisionServiceClient 類別,如下所示︰

private readonly VisionServiceClient visionClient;
public OcrRecognitionPage()
{
  InitializeComponent();
  this.visionClient =
    new VisionServiceClient("YOUR-KEY-GOES-HERE");
}

當然,您可以使用您先前使用相同的索引鍵。接下來,您可以重複使用這兩個事件處理常式中所示 [圖 6, ,您必須取代下列程式碼行︰

var analysisResult = await AnalyzePictureAsync(
  file.GetStream());
this.BindingContext = analysisResult;

使用下列新的程式行︰

var ocrResult = await AnalyzePictureAsync(
  file.GetStream());
this.BindingContext = ocrResult;
PopulateUIWithRegions(ocrResult);

如此一來,您可以將 OcrResults 執行個體繫結至 UI,則 PopulateUIWithRegions 方法將會產生新行,以偵測到的文字。為了簡單起見,而不是實作頁面巡覽,您只要可以如下所示變更 App.xaml.cs 建構函式中的起始頁︰

MainPage = new OcrRecognitionPage();

現在啟動應用程式,選擇您最愛的模擬器或裝置。如果您選取或拍照,您就能夠讀取它,在列印的文字中所示 圖 10

對影像執行光學字元辨識
[圖 10 對影像執行光學字元辨識

在此情況下,在 Android 模擬器上執行範例應用程式。請注意如何語言正確偵測到已英文 (en)。務必要注意 OCR 服務很適合處理高品質的影像。如果影像解析度不佳,影像模糊,或者它包含手寫或草寫文字,此服務可能傳回不正確的結果。另外值得一提的是 OCR 服務可以偵測到更多色彩背景,不只是單色的映像上的文字。比方說,您可以分析文字日落圖片。

尋找與特定的網域模型的名人

在發行項的第一個部分中,我說明了電腦願景 Api 提供描述映像。描述是指發生在非常高的層級,並傳回從映像的一般資訊。Microsoft 也在處理透過所謂的網域特定模型的特殊的辨識供應項目。允許特定資訊的傳回,從映像,可以結合的映像的描述。撰寫本文時,只有特定的網域模型是熱門話題辨識。藉由使用此模型,您可以利用電腦願景 Api,來偵測名人圖片中。一般而言,模型中,您可以執行特定的分析透過特定類別的映像。因此我下一個和最後一個範例辨識名人圖片內。我無法顯示熱門話題圖片著作權原因,但您不需要任何測試程式碼的問題。現在就開始稱為 CelebrityRecognitionPage 的 PCL 專案中加入新的 XAML 頁面。請參閱上一節中的 [新增] 頁面所需的步驟。此頁面的 UI 是非常簡單︰ 您只需要在標籤中顯示的熱門話題名稱,當然,它會提供一般的 UI 項目,如所示 [圖 11

[圖 11 準備熱門話題辨識 UI

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="https://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="ComputerVisionSample.CelebrityRecognitionPage">
  <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" />
    <Label x:Name="CelebrityName"/>
  </StackLayout>
</ContentPage>

熱門話題辨識被透過呼叫 AnalyzeImageInDomainAsync 的 VisionServiceClient 類別中的方法。此方法需要使用的影像資料流或 URL 和網域特定模型來偵測。您可以藉由叫用 VisionServiceClient.ListModelsAsync; 擷取可用模型的清單雖然我之前提過,只有熱門話題辨識模型目前可以使用。下列程式碼示範如何擷取模型和一個特定模型的清單︰

private async Task<Model> GetDomainModel()
{
  ModelResult modelResult = await visionClient.ListModelsAsync();
  // At this writing, only celebrity recognition
  // is available. It is the first model in the list
  return modelResult.Models.First();
}

下一個步驟是執行辨識,如下列的自訂方法呼叫 AnalyzePictureAsync 所示的程式碼︰

private async Task<AnalysisInDomainResult> AnalyzePictureAsync(Stream inputFile)
{
  if (!CrossConnectivity.Current.IsConnected)
  {
    await DisplayAlert("Network error",
      "Please check your network connection and retry.", "OK");
    return null;
  }
  AnalysisInDomainResult analysisResult =
    await visionClient.AnalyzeImageInDomainAsync(inputFile, await GetDomainModel());
  return analysisResult;
}

影像分析的結果是以下列定義的 AnalysisInDomainResult 型別的物件︰

public class AnalysisInDomainResult
{
  public AnalysisInDomainResult();
  public Metadata Metadata { get; set; }
  public Guid RequestId { get; set; }
  public object Result { get; set; }
}

Result 屬性包含辨識的實際結果。如您所見,它是型別 System.Object,這表示它包含原始資料。更具體來說,結果會儲存電腦願景服務所傳回的 JSON 回應。根據偵測到的名人數目,此 JSON 可能很複雜,而且這就是它是物件,而不是更具特製化類型的原因。它基本上會定義一個陣列的項目,每一個都會包含熱門話題名稱、 朝矩形大小和值,表示結果的精確度。比方說,如果結果包含一個熱門話題,JSON 看起來類似下面的 (其中 CelebrityName 代表實際的熱門話題名稱)︰

{"celebrities": [
  {
    "name": "CelebrityName",
    "faceRectangle": {
      "left": 169,
      "top": 148,
      "width": 186,
      "height": 186
    },
    "confidence": 0.9064959
  }
]}

如果 JSON 包含多個名人,您可以想像它可以是複雜。因此這裡解決重要的問題從物件型別擷取熱門話題名稱。這可以經由使用熱門 Newtonsoft.Json 程式庫,這是 Microsoft.ProjectOxford.Vision 程式庫的相依性,因此,已可供使用 PCL 專案中。程式庫提供一個稱為 JObject,從 Netwonsoft.Json.Linq 的命名空間,可讓剖析 JSON 標記儲存在 System.Object 內,與呼叫剖析方法的物件。您可以將結果視為 JSON 字串,並擷取與索引所需的項目。下列方法示範如何擷取分析結果的熱門話題名稱︰

private string ParseCelebrityName(object analysisResult)
{
  JObject parsedJSONresult = JObject.Parse(analysisResult.ToString());
  var celebrities = from celebrity in parsedJSONresult["celebrities"]
                    select (string)celebrity["name"];
  return celebrities.FirstOrDefault();
}

在此情況下,我假設圖片會包含只有一個熱門話題,因此程式碼呼叫 FirstOrDefault LINQ 查詢的結果,但您可以使用查詢結果,以查看已偵測到多少名人。下一個步驟是宣告,並將類別執行個體化 VisionServiceClient,一次與秘密金鑰︰

private readonly VisionServiceClient visionClient;
public CelebrityRecognitionPage()
{
  InitializeComponent();
  this.visionClient = new VisionServiceClient("YOUR-KEY-GOES-HERE");
}

此時,您可以加入按鈕 Clicked 事件的兩個事件處理常式。您仍然可以重複使用中的程式碼 [圖 6, ,只是取代下列這一行︰

this.BindingContext = analysisResult;

下列這行︰

this.CelebrityName.Text = ParseCelebrityName(analysisResult.Result);

您現在可以測試應用程式,請選取您最愛的熱門話題的圖片,並查看電腦願景 Api 傳回的確切結果的方式。

總結

開啟新的機會,不可思議多電腦願景 Api,並提供一個非常簡單的方式來描述世界中,使用您的應用程式,在任何平台和任何裝置上。在組建 2016年會議,Microsoft 呈現看到 AI 專案中,根據數個認知的服務,包括電腦願景,說明在短片,可讓您可以執行的真實觀感。在觀賞 bit.ly/1qk5ZkJ


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

感謝下列 Microsoft 技術專家來檢閱這份文件︰ James McCaffrey
Dr。James McCaffrey 適用於在美國華盛頓州 Redmond 的 Microsoft Research他曾在數個 Microsoft 產品,包括 Internet Explorer 和 Bing。Dr。可以連線到 McCaffrey jammc@microsoft.com