Ink Recognizerを使ってみよう ( Cognitive Services 復習 )
こんばんは!
コロナウイルスの影響で各地のイベントは自粛ムード…
我が家は出来るだけ人が多い所を避けて、前々から嫁に頼まれてたやつをDIYしています。
さて、勉強会も中々開催できないので、時間がある時に Microosoft Azure のサービスで一番好きな Cognitive Services について不定期でのんびりブログに書いていこうと思います。
Cognitive Services
Microsoft の提供するサービスである、 Cognitive Services は人間の認知する機能の一部(見たり、聞いたり、話したり、意思決定したり、検索したり)を機械で擬似的に再現したサービスで Web API として利用できる AI パーツ。
2020.02.26 現在のサービス一覧 (27 Services ※5 preview)
- 決定:よりスマートな意思決定をすばやく行う
- Anomaly Detector(preview):発生する可能性のある問題を早期に識別
- Content Moderator:不快または望ましくない可能性のあるコンテンツを検出
- Personalizer:パーソナライズされ、優れたエクスペリエンスを提供
- 言語:非構造化テキストから意味を取り出す
- Immersive Reader(preview):音声や視覚的な合図を使用して、あらゆる能力の読み手がテキストを理解できるようにする
- Language Understanding:自然言語を解釈する機能を提供
- QnA Maker:ナレッジベースから質疑応答を、会話形式で行うことができる
- Text Analytics:センチメント、キー フレーズ、名前付きエンティティを検出
- Translator Text:60 を超えるサポート言語を検出し、リアルタイムで翻訳
- 音声:音声処理をアプリやサービスに統合する
- Speech to Text:音声を、読み取れる検索可能なテキストに書き起こす
- Text to Speech:テキストを本物のような音声に変換し、より自然なインターフェイスを実現
- Speech Translation:リアルタイムの音声翻訳をアプリに統合
- Speaker Recognition(preview):音声に基づいて人々の話を識別し、検証
- 視覚:画像、ビデオ、デジタル インク内のコンテンツを識別し、分析する
- Computer Vision:画像内のコンテンツを分析
- Custom Vision:ビジネス上のニーズに合うよう画像認識をカスタマイズ
- Face:イメージ内の人物とその感情を検出して識別
- Form Recognizer(preview):ドキュメントからテキスト、キーと値のペア、テーブルを抽出
- Ink Recognizer(preview):デジタル インクや手書き入力を認識し、一般的なシェイプの位置特定
- Video Indexer:ビデオのビジュアルとオーディオ チャネルを分析し、そのコンテンツにインデックスを設定
- 検索:World Wide Web から探しているものを見つける
- Bing Autosuggest:インテリジェントな先行入力機能が追加され、ユーザーはよりすばやくクエリを入力する
- Bing Custom Search:検索結果に広告が表示されないカスタムの検索エンジンを作成
- Bing Entity Search:名前付きエンティティを識別して分類し、それに基づいて検索結果を探す
- Bing Image Search:さまざまな画像検索オプションをアプリに追加
- Bing News Search:アプリをニュースの検索リソースに変更
- Bing Spell Check:ユーザーが単語の切れ目、スラング、名前、同音異義語、ブランドを識別して修正
- Bing Video Search:高度なビデオ検索機能をアプリに追加
- Bing Visual Search:ユーザーが画像を使用して検索
- Bing Web Search:安全で広告なしの、位置認識機能を備えた検索をユーザーが利用できるようにし、Web の検索結果、画像、ニュース、ビデオ、ビジュアルから関連情報を表示
Ink Recognizer
初回となる今回は、タイトル通り Ink Recognizer API についてです。
手書きの文字、図形、インク ドキュメントのレイアウトなどのデジタル インク コンテンツを認識できる AI サービス
ちょっと何言ってるかわかりませんね。
要は Ink Recognizer API を使用すると、アプリケーション内の手書きコンテンツを簡単に認識する事ができるんです。
あぁ、OCRかw と思われる方もいらっしゃるかと思いますが(僕もそう思いました)、タブレットPCなどにペンや手書きで書いた文字の軌跡を時間軸で並べ渡してあげる事で、図形や文字を認識してくれるというものらしいです。
できる事
手書き認識
63 の主要な言語とロケールの手書きコンテンツを認識
レイアウト認識
コンテンツを手書き領域、段落、行、単語、箇条書きに分割します。 これにより、お使いのアプリケーションでそのレイアウト情報を使用して、リストの自動書式設定や図形の配置などの追加機能を構築
図形認識
一般的な幾何学図形を認識
図形とテキストの認識
どのインク ストロークが図形または手書きコンテンツに属しているかを認識し、それらを個別に分類
価格
現在 Preview 中なので価格設定は変わる事があるかもしれませんが以下となっています。
こちら、200 ストロークの要求で 1 トランザクションでして、例えば『石橋裕太』という文字の場合、合計 37 ストロークという感じだと思います。
なので Free プランでも十分に楽しめるかと!!
実際に使ってみる
Azure Portal で Ink Recoognizer のリソースを作成
サンプルコード
こちらのコードをローカルに git clone して VS Code で開きます。
git clone https://github.com/Azure-Samples/cognitive-services-REST-api-samples cd SampleCode\cognitive-services-REST-api-samples\javascript\InkRecognition\javascript-app\src code .
あとは sample.html を開けば良いのですが、ここまで来て気づいた事としてペンで入力出来る端末がない事でしたww (Macbookなのでタッチついてない…)
とりあえず、App Service に GitHub からデプロイして iPad で動作を確認してみましょう。
動作を確認
Request
ストローク毎にポイントが時系列順で渡されてますね
{ "version": 1, "language": "ja-JP", "strokes": [ { "id": 63, "points": "48.6895,163.1115,47.3666,163.1115,46.0437,162.1193,46.0437,161.8015,45.3822,161.4630,45.3822,161.1452,46.7052,160.4682,50.0125,159.8145,55.9656,158.8198,63.2416,157.4891,73.1635,156.4943,83.0854,155.1843,91.6843,153.8511,100.2833,152.8589,105.5750,152.2026,108.2208,152.2026,109.5437,152.2026,109.5437,152.2026,108.2208,152.8589,106.8979,154.1896" }, { "id": 64, "points": "78.4552,159.1582,78.4552,158.8198,77.7937,159.1582,77.1322,160.1504,76.4708,162.4552,75.8093,166.0932,74.4864,171.3797,71.8406,177.0021,67.2104,184.2937,61.9187,191.5671,55.9656,200.1687,48.6895,206.7677,44.0593,211.7338,40.0906,215.0515,37.4447,216.3641,36.1218,216.7025,36.1218,216.0256" }, { "id": 65, "points": "65.8875,197.1895,65.8875,196.1973,65.8875,195.8588,65.8875,196.8510,65.8875,198.8406,67.2104,203.1323,68.5333,207.7625,70.5177,212.3901,73.1635,216.0256,74.4864,218.6895,75.8093,220.6765,77.1322,221.9865,77.7937,222.6427,78.4552,222.9812" }, { "id": 66, "points": "74.4864,199.8328,73.1635,198.8406,73.1635,198.8406,74.4864,198.8406,77.1322,198.1843,83.0854,197.5073,88.3770,196.5151,94.3302,195.5410,99.6218,195.2026,102.9291,196.1973,104.2520,197.1895,105.5750,198.1843,105.5750,199.8328,104.9135,201.8171,103.5906,204.1245,101.6062,206.7677,100.2833,209.4291,99.6218,211.0776,98.2989,213.7208,96.9760,215.7078,96.3145,217.0203" }, { "id": 67, "points": "85.7312,219.0073,83.0854,219.0073,82.4239,219.0073,83.0854,219.3458,85.0697,219.3458,89.7000,217.6947,96.9760,216.3641,102.9291,215.7078,104.2520,215.7078" }, { "id": 68, "points": "115.4968,171.3797,115.4968,171.0619,114.1739,170.4030,114.1739,170.0671,115.4968,169.7287,118.1427,168.7365,124.0958,168.0802,131.3718,167.4239,136.6635,166.0932,140.6322,165.0984,141.2937,164.7806,140.6322,164.7806,137.3250,164.4447,134.0177,163.4500,131.3718,161.8015,130.0489,160.1504,129.3875,158.1635,129.3875,156.8328,129.3875,156.4943,129.3875,157.1713,129.3875,159.8145,129.3875,167.0854,128.7260,174.6948,128.0645,182.9604,128.0645,191.2286,128.0645,199.1739,128.0645,205.1193,128.0645,210.0854,128.7260,213.0645,129.3875,214.3771,129.3875,214.3771,129.3875,214.0593" }, { "id": 69, "points": "131.3718,176.3458,131.3718,176.3458,130.7104,176.0254,130.0489,176.0254,129.3875,176.3458,129.3875,177.3380,128.0645,179.3250,128.0645,181.6323,125.4187,186.5984,122.1114,190.5723,118.8041,193.8719,116.1583,196.8510,114.1739,198.5021,112.8510,198.8406,112.1895,197.5073" }, { "id": 70, "points": "129.3875,175.6895,128.0645,175.0332,127.4031,174.6948,126.7416,174.6948,128.0645,174.6948,129.3875,175.6895,132.6947,177.9969,135.3406,179.9813,138.6479,181.9682,141.2937,183.6167,142.6166,184.2937" }, ...長いので省略 ] }
Response
こちらは alternates の recognizedString に候補となる文字列が帰ってきてたり、一致率が一番高い文字列がわかったり、文字のある場所が座標として帰ってきてますね
{ "recognitionUnits": [ { "alternates": [ { "category": "inkWord", "recognizedString": "右" }, { "category": "inkWord", "recognizedString": "后" }, { "category": "inkWord", "recognizedString": "谷" }, { "category": "inkWord", "recognizedString": "厄" }, { "category": "inkWord", "recognizedString": "名" }, { "category": "inkWord", "recognizedString": "古" }, { "category": "inkWord", "recognizedString": "百" }, { "category": "inkWord", "recognizedString": "召" }, { "category": "inkWord", "recognizedString": "不" } ], "boundingRectangle": { "height": 70.79000091552734, "topX": 36.119998931884766, "topY": 152.1999969482422, "width": 73.43000030517578 }, "category": "inkWord", "class": "leaf", "id": 4, "parentId": 3, "recognizedText": "石", "rotatedBoundingRectangle": [ { "x": 38.619998931884766, "y": 149.52999877929688 }, { "x": 109.52999877929688, "y": 152.1999969482422 }, { "x": 106.83000183105469, "y": 224.0399932861328 }, { "x": 35.90999984741211, "y": 221.3699951171875 } ], "strokeIds": [ 63, 64, 65, 66, 67 ] }, { "alternates": [ { "category": "inkWord", "recognizedString": "槗" }, { "category": "inkWord", "recognizedString": "楿" }, { "category": "inkWord", "recognizedString": "橎" }, ...長いので省略 ] }