Xamarin で Watson Visual Recognition を使ってみた
IBM Watson には .NET Standard 用の SDK があります(α版).
しかし、残念ながら現状では Xamarin で使用することはできません.
(Issue を上げたのでそのうち改善されるかと思います)
そこで今回は、Web API を直接叩く形で Watson API を Xamarin で使ってみます.
使用する Watson API は画像認識を行う Visual Recognition で、画像中の文字を認識する Recognize Text を使ってみます.
Bluemix 上で Watson Visual Recognition の作成
Bluemix で サービズの中の Watson を選びます.
Watson サービスの作成ボタンをクリックします.
一覧の中から Visual Recognition を選びます.
価格プランを選んで作成ボタンを押します.
作成したインスタンスのサービス資格情報の中の API KEY を控えておきましょう.
以上が Bluemix 上の操作です.
Xamarin の実装
Xamarin の実装として、今回はカメラで撮影した画像に対し文字認識を行います.
以下 MainPage のコードビハインドです.
using System;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using Plugin.Media;
using Plugin.Media.Abstractions;
using Xamarin.Forms;
namespace FlipChartRecognitionApp
{
public partial class FlipChartRecognitionAppPage : ContentPage
{
private static readonly string Url = "https://gateway-a.watsonplatform.net/visual-recognition/api/v3/recognize_text?api_key=...&version=2016-05-20";
public FlipChartRecognitionAppPage()
{
InitializeComponent();
}
public async void Handle_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
{
Directory = "Sample",
Name = $"{DateTime.Now.ToString("yyMMdd-hhmmss")}.jpg",
PhotoSize = PhotoSize.Small
});
if (file == null)
return;
RecognizeImage(file);
image.Source = ImageSource.FromStream(() =>
{
var stream = file.GetStream();
file.Dispose();
return stream;
});
}
void RecognizeImage(MediaFile file)
{
var content = new MultipartFormDataContent();
var imageContent = new ByteArrayContent(ReadFully(file.GetStream()));
imageContent.Headers.ContentType = MediaTypeHeaderValue.Parse("image/jpeg");
content.Add(imageContent);
var httpClient = new HttpClient();
var response = httpClient.PostAsync(Url, content).Result;
DisplayAlert("Result", response.Content.ReadAsStringAsync().Result, "OK");
}
byte[] ReadFully(Stream input)
{
using (MemoryStream ms = new MemoryStream())
{
input.CopyTo(ms);
return ms.ToArray();
}
}
}
}
ひとつずつ解説していきます.
コールする API は下記のようになっているので、{API KEY} の部分を先ほど作成したインスタンスの API KEY に書き換えてください
private static readonly string Url = "https://gateway-a.watsonplatform.net/visual-recognition/api/v3/recognize_text?api_key={API KEY}&version=2016-05-20";
カメラの撮影部分では拡張子に .jpg を指定します.また、PhotoSize を Samll にしたほうが無難です.(Medium の場合、何度か送信に失敗しました)
var file = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions
{
Directory = "Sample",
Name = $"{DateTime.Now.ToString("yyMMdd-hhmmss")}.jpg",
PhotoSize = PhotoSize.Small
});
画像認識部分です.
送信するファイルは、Image を Byte配列に変換した上で ByteArrayContent に渡します.
ByteArrayContent.Headers.ContentType には、先ほど保存した .jpg ファイルと整合を取る形で、image/jpeg を指定します.
MultipartFormDataContent に ByteArrayContent を追加し、HttpClient.PostAsync をコールすれば画像認識が行えます.
void RecognizeImage(MediaFile file)
{
var content = new MultipartFormDataContent();
var imageContent = new ByteArrayContent(ReadFully(file.GetStream()));
imageContent.Headers.ContentType = MediaTypeHeaderValue.Parse("image/jpeg");
content.Add(imageContent);
var httpClient = new HttpClient();
var response = httpClient.PostAsync(Url, content).Result;
DisplayAlert("Result", response.Content.ReadAsStringAsync().Result, "OK");
}
実装結果
こちらが実装結果です.
VOX のアンプラグを撮影してみました.
JSON の score という部分は Watson の回答に対する自信度を表しています.
- VOX のロゴは装飾が入っていて判別しずらい
- NIGHT は塗装が剥がれて判別しずらい
上記2点が score に表れていますね.反対に TRAIN はかなりの自信度で判別しているようです.
まとめ
今回は Watson API を Xamarin で使ってみました.
Web API なので特に工夫なく、普通に使えることがお分かりいただけたかと思います.
通信部やモデルを自前で書かないといけないのは多少おっくうですが、冒頭でも述べたように、近い将来 Xamarin に対応した .NET Standard の SDK がリリースされると思いますので、ぜひそれを楽しみにしていただければと思います!
以上です.
ディスカッション
コメント一覧
まだ、コメントがありません