Xamarin.FormsからCognitive ServiceのComputer Visionを使う
今回やりたいのは,カメラで撮影した画像からテキストを抽出するもの.
参考は,
アプリ内でカメラを使って,撮影し,画像データを取得するには.
MontemagnoさんのMediaPluginを使っている.
カメラの使い方(Android)
カメラを使って画像を取得するためにはXam.Plugin.Media
というパッケージを使います.
セットアップの手順は公式サイトのとおりに行えば問題ありません.
このパッケージはカメラからの画像取得だけでなく,フォルダ内の画像を選択することもできます.
Xam.Plugin.Mediaをインストール
Xam.Plugin.Media
をNugetでインストールする.
AndroidManifest.xmlを編集
AndroidManifest.xmlを以下のように編集する.
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.companyname.xfazuretextrecognization" android:installLocation="auto"> <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="28" /> <application android:label="XFAzureTextRecognization.Android"> <!--ここから--> <provider android:name="android.support.v4.content.FileProvider" android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths"></meta-data> </provider> <!--ここまで--> </application> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> </manifest>
file_paths.xmlを追加
Resources
フォルダの下にxmlフォルダを作成し,そこに
file_paths.xml`を追加します.
file_paths.xmlには以下の内容を記述します.
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-files-path name="my_images" path="Pictures" /> <external-files-path name="my_movies" path="Movies" /> </paths>
使う
ボタンのイベントハンドラなどの中で以下のように記述します.
var photo = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions { PhotoSize = PhotoSize.Small }); //撮影画面から戻るボタンなどで戻った場合にはnullになるのでチェックする if (_photo is null) return;
処理がこの行に達した時点で以下のようにカメラが起動します.
カメラを初めて使用するときに許可を求められるのでそれでもOkですが,コードで以下のようにカメラの有無や許可の有無などのチェック及び許可のリクエストなどを行うとよいでしょう.
//カメラの有無と撮影の許可の有無をチェック if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported) { await DisplayAlert("No Camera", ":( No camera available.", "OK"); return; } //カメラ利用許可の有無を確認 if (await Permissions.CheckStatusAsync<Permissions.Camera>() != PermissionStatus.Granted) { //カメラ利用許可をリクエスト if(await Permissions.RequestAsync<Permissions.Camera>()!=PermissionStatus.Granted) { return; } }
AzureでComputer Visionのインスタンスを作成
こちらの説明のとおりに作成します.
まずリソースグループを作成します.
az group create -l westus2 -g YOUR-RESOURCE-GROUP-NAME-GOES-HERE
次にComputer Visionのインスタンスを作ります.
az cognitiveservices account create \ --kind ComputerVision \ --location westus2 \ --sku F0 \ --resource-group RESOURCE-GROUP-NAME-FROM-FIRST-STEP \ --name YOUR-SERVICE-NAME-GOES-HERE
最後にAPIキーとエンドポイントをメモしておきます.
Microsoft.Azure.CognitiveServices.Vision.ComputerVisionをインストール
Nugetからインストールします.
使い方
ComputerVisionClientのインスタンスを作成します.
private readonly ComputerVisionClient _computerVisionClient = new ComputerVisionClient(new ApiKeyServiceClientCredentials({COMPUTER-VISION-APIKEY})) { Endpoint = {COMPUTER-VISION-ENDPOINT} };
CoumputerVisionClientクラスにはComuputer Visionを使うための様々なクラスが用意されています.
今回は画像内の文字を抽出するのでRecognizePrintedTextInStreamAsync
メソッドを使います.
var result = await _computerVisionClient.RecognizePrintedTextInStreamAsync(detectOrientation: true, image: pictureStream);
得られる結果はOcrResult
オブジェクトで,以下のJSONと同じ構造になっています.
このように,テキストだけでなく,画像上のテキストの位置も取得できます.
実際に使ってみる
以下のように写真を撮影して「✔」ボタンを押すと,
テキストの抽出結果が表示される,
という簡単なアプリを作成.
ソースコードは以下.