Watson Developer Cloud .NET Standard SDK を Xamarin で使ってみた(Visual Recognition 編)

前回に引き続き、Watson Developer Cloud .NET Standard SDK の内容です.
今回は、Visual Recognition の Detect Faces を使ってみます.

実装環境

  • macOS Sierra 10.12.5 (16F73)
  • Visual Studio for Mac 7.0.1 (build 24)
  • IBM.WatsonDeveloperCloud.VisualRecognition.v3 1.1.0
  • Xamarin.Forms 2.3.4.247

XAML

Image に選択した画像を表示し、Label に画像認識の結果を表示します.

XAML.cs

using System;
using System.Diagnostics;
using System.IO;
using IBM.WatsonDeveloperCloud.VisualRecognition.v3;
using Plugin.Media;
using Xamarin.Forms;

namespace WatsonSdkSample.VisualRecognition
{
	public partial class VisualRecognitionPage1 : ContentPage
	{
		private const string ApiKey = "XXXXXXXXXXXXXXXXXXX";
		private readonly VisualRecognitionService _visualRecognition;

		public VisualRecognitionPage1()
		{
			InitializeComponent();

			_visualRecognition = new VisualRecognitionService();
			_visualRecognition.SetCredential(ApiKey);
		}

		public async void Handle_Clicked(object sender, EventArgs e)
		{
			image.Source = null;
			indicator.IsVisible = true;

			await CrossMedia.Current.Initialize();

			if (!CrossMedia.Current.IsPickPhotoSupported)
			{
				await DisplayAlert("No Auth", "Picking images denied.", "OK");
				return;
			}

			var file = await CrossMedia.Current.PickPhotoAsync();

			if (file == null)
				return;

			/** 画像認識 **/
			var imageByteArray = ReadFully(file.GetStream());

			var result = _visualRecognition.DetectFaces(imageData: imageByteArray, imageDataName: file.AlbumPath,
				imageDataMimeType: "image/jpeg");

			var text = "";
			foreach (var face in result.Images[0].Faces)
			{
				text += string.Format("Left: {0}, Top: {1}, Width: {2}, Height: {3}, " +
									  "Gender: {4}, GenderScore: {5}, AgeMax: {6}, AgeMin: {7}, AgeScore: {8}, " +
									  "IdentifyName: {9}, IdentifyScore: {10}, IdentifyHierarchy: {11}",
							face.FaceLocation.Left,
							face.FaceLocation.Top,
							face.FaceLocation.Width,
							face.FaceLocation.Height,
							face.Gender.Gender,
							face.Gender.Score,
							face.Age.Max,
							face.Age.Min,
							face.Age.Score,
							face.Identity?.Name,
							face.Identity?.Score,
							face.Identity?.TypeHierarchy) + System.Environment.NewLine;
			}

			image.Source = ImageSource.FromStream(() =>
			{
				var stream = file.GetStream();
				file.Dispose();
				return stream;
			});
			label.Text = text;
			indicator.IsVisible = false;
		}

		private static byte[] ReadFully(Stream input)
		{
			using (var ms = new MemoryStream())
			{
				input.CopyTo(ms);
				return ms.ToArray();
			}
		}
	}
}

Visual Recognition の部分を抜粋して説明します.

_visualRecognition = new VisualRecognitionService();
_visualRecognition.SetCredential(ApiKey);

VisualRecognitionService を初期化します.
SetCredential で VisualRecognition の API KEY を設定します.

var result = _visualRecognition.DetectFaces(imageData: imageByteArray, imageDataName: file.AlbumPath,
				imageDataMimeType: "image/jpeg");

imageData に Plugin.Media で取得した Stream を byte[] に変換したものを渡します.

imageDataName にファイルパスを、imageDataMimeType に “image/jpeg” を渡します.
(本来は、imageDataName, imageDataMimeType どちらかを指定すればいい気がしますが、この辺はもう少しソースを読んで確認します)

foreach (var face in result.Images[0].Faces)
{
	text += string.Format("Left: {0}, Top: {1}, Width: {2}, Height: {3}, " +
						"Gender: {4}, GenderScore: {5}, AgeMax: {6}, AgeMin: {7}, AgeScore: {8}, " +
						"IdentifyName: {9}, IdentifyScore: {10}, IdentifyHierarchy: {11}",
				face.FaceLocation.Left,
				face.FaceLocation.Top,
				face.FaceLocation.Width,
				face.FaceLocation.Height,
				face.Gender.Gender,
				face.Gender.Score,
				face.Age.Max,
				face.Age.Min,
				face.Age.Score,
				face.Identity?.Name,
				face.Identity?.Score,
				face.Identity?.TypeHierarchy) + System.Environment.NewLine;
}

取得できる要素として、以下の情報が取得できます.

  • 認識した顔の座標情報
  • 性別
  • 年齢
  • 有名人の場合は名前およびタグ情報

実装結果

ソースコードはこちらでご確認いただけます.

まとめ

今回は Watson Developer Cloud .NET Standard SDK の Visual Recognition の中の DetectFaces を使ってみました.

SDK が使えることで、余計な POCO を実装しなくてよかったり、HttpClient 回りを書かなくてよいので、スピーディーに実装できますね.

一つ気になったところとしては、async メソッドがあるとより使い方の幅が広がる気がしました.

以上です.