かずきのBlog@hatena

日本マイクロソフトに勤めています。XAML + C#の組み合わせをメインに、たまにASP.NETやJavaなどの.NET系以外のことも書いています。掲載内容は個人の見解であり、所属する企業を代表するものではありません。

Xamarin.Formsで笑顔測定をしよう(AndroidとUWP)

最近笑顔してますか?こんな感じの笑顔測定アプリを作ってみようと思います。これならボッチでも笑顔の練習できるよ!

左がニュートラルな顔、右が笑顔の場合です!スコアが変わってますね。

f:id:okazuki:20161121163608p:plain

ということで、Cognitive ServiceのFace APIを使って笑顔判定するものをXamarin.Formsで作ってみようと思います。 プロジェクトテンプレートは安定のPrism Tmeplate Packで作ります。 これだとおぜん立てとかがあって楽なので。

ということで、今回のお題を達成するにはカメラで写真を撮るということとCognitive ServiceのAPIを呼び出すという2つの段階を踏まないといけません。順番に見ていきましょう。

カメラにアクセスする

Xamarinには、Pluginという便利なクロスプラットフォームで各種プラットフォーム固有の機能にアクセスするためのライブラリがあったりします。 カメラもPluginがあったりします。

github.com

ということで、NuGetでXam.Plugin.Mediaをインストールしましょう。 するとreadme.txtが表示されます。

そこに書いてある通りに、以下の属性の追加とMainActivityのメソッドのオーバーライドを行います。

[assembly: UsesFeature("android.hardware.camera", Required = false)]
[assembly: UsesFeature("android.hardware.camera.autofocus", Required = false)]
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
{
    PermissionsImplementation.Current.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}

UWPは、Webカメラの機能にマニフェストでチェックを入れておきます。

カメラの下準備が整ったら以下のような初期化コードをApp.xaml.csに追加します。

Plugin.Media.CrossMedia.Current.Initialize();

これで下準備は完了です。 以下のようなコードで画像を取得してImageSource(画像のもと)を生成できます。

var file = await CrossMedia.Current.TakePhotoAsync(new Plugin.Media.Abstractions.StoreCameraMediaOptions
{
    DefaultCamera = Plugin.Media.Abstractions.CameraDevice.Front,
    AllowCropping = false,
});
if (file == null) { return; }

this.ImageSource = ImageSource.FromStream(() => file.GetStream());

Cognitive Serviceの呼び出し

次にCongnitive Serviceの呼び出しです。 Azureポータルから、Face APIとかで検索するとCongnitive Serviceが作成できるのでFace APIを選んでFreeプランあたりで作成しておきましょう。

ポータルのKeyからアクセスに必要になるキーを取得します。

f:id:okazuki:20161121155113p:plain

キーを取得したら、NuGetからMicrosoft.ProjectOxford.Faceをインストールしましょう。OxfordというのはCongnitive Serviceのプレビュー時代の名前になります。

Face APIの呼び出し自体は簡単で、返して欲しい属性(今回の場合は笑顔判定なのでスマイル)を指定してDetectAsyncを呼び出すだけです。クライアントの生成時に先ほど取得したキーを指定するのを忘れずに。

var client = new FaceServiceClient("ここにキーを設定する");
var result = await client.DetectAsync(file.GetStream(), returnFaceAttributes: new[]
{
    FaceAttributeType.Smile,
});

if (!result.Any()) { return; }

await this.PageDialogService.DisplayAlertAsync("Smile point", $"Your smile point is {result.First().FaceAttributes.Smile * 100}", "OK");

実行結果

UWPとAndroidしか持ってないのでiOSは試せてない(iOSはiOSでプラグインの設定が必要そう)のですがばっちり動きました。

Android

f:id:okazuki:20161121163922j:plain

UWP

f:id:okazuki:20161121163949p:plain

まとめ

ということでXamarinとMediaのPluginとCongnitive Serviceを使って簡単笑顔測定アプリが出来ました。 Xamarin.Formsで作ったからUWPでもAndroidでも動くので素敵ですね。

ということで、ソースコードは以下にあげています。

github.com

Xamarinはいいぞ。