タッチパネルを生かしてフリーハンドの文字を認識させるアプリを作ろう

2012年11月12日(月)
薬師寺 国安

要素内で、プレス アクションを開始したポインター デバイスが離された時に発生するイベント

イベントデータを提供するPointerIdが、入力ポインターの一意の識別子と同じである場合の処理です。

GetCurrentPointメソッドで、Canvas内の現在のポインターを取得します。

InkManagerクラスのProcessPointerUpメソッドで、ポインターの位置と圧力の傾きを処理します。このメソッドは ProcessPointerUpdateメソッドを呼び出した後で呼び出す必要があります。

入力ポインターの一意の識別子を取得していたメンバ変数myPenIDを0で初期化します。

  Private Sub myCanvas_PointerReleased(sender As Object, e As PointerRoutedEventArgs)
    If e.Pointer.PointerId = myPenID Then
      Dim myPointer As PointerPoint = e.GetCurrentPoint(myCanvas)
      myInkManager.ProcessPointerUp(myPointer)
    End If
    myPenID = 0
    e.Handled = True
  End Sub

[クリア]ボタンがクリックされた時の処理

InkManagerクラスのModeプロパティで、インク入力モードをInkManipulationMode.Erasingに指定します。ストロークが削除モードになります。InkManagerのGetStrokesメソッドで、InkManager の管理するコレクション内のすべての InkStroke オブジェクトを取得し、変数myStrokeに格納します。

InkStrokeのコレクションの数だけ繰り返し処理を行います。すべてのInkStrokeを選択状態にします。DeleteSelectedメソッドで、選択されたInkStroke オブジェクトを InkManager の管理する InkStroke のコレクションから削除します。Canvasの背景色をWhiteに指定し、Canvas内をクリアします。その後、InkManagerのModeをInkManipulationMode.Inkingにしておきます。再びインクストロークが可能な状態になります。[文字認識]ボタンの使用を不可とします。

  Private Sub clearButton_Click(sender As Object, e As RoutedEventArgs) Handles clearButton.Click
    TextBox1.Text = String.Empty
    myInkManager.Mode = InkManipulationMode.Erasing
    Dim myStroke As IReadOnlyList(Of InkStroke) = myInkManager.GetStrokes
    For i As Integer = 0 To myStroke.Count - 1
      myStroke(i).Selected = True
    Next
    myInkManager.DeleteSelected()
    myCanvas.Background = New SolidColorBrush(Colors.White)
    myCanvas.Children.Clear()
    myInkManager.Mode = InkManipulationMode.Inking
    recognizeButton.IsEnabled = False  
  End Sub

[文字認識]ボタンをクリックした時の処理

InkManagerのGetStrokesメソッドで、InkManager のを管理するコレクション内のすべての InkStroke オブジェクトを取得し、変数myStrokeに格納します。InkStrokeのコレクションの数だけ繰り返し処理を行います。すべてのInkStrokeを選択状態にします。

文字列変数myRecNameを「Microsoft 日本語手書き認識エンジン」と初期化しておきます。

英語の認識エンジンを使用する場合は「Microsoft English (US) Handwriting Recognizer」と指定します。

InkManagerのGetRecognizersメソッドで、手書き認識エンジンのコレクションを取得します。

取得したコレクションの数だけ反復処理を行います。変数myRecNameの値が、手書き認識エンジンのコレクションのNameと一致する場合は、その手書き認識エンジンを、SetDefaultRecognizerメソッドで規定値として設定します。「Microsoft 日本語手書き認識エンジン」が規定値に設定されます。

RecognizeAsyncメソッドで、一つまたは複数のInkStrokeオブジェクトに対して手書き認識を実行します。InkRecognitionTarget.Allで、ストロークコレクション内のすべてのストロークを認識エンジンに渡します。UpdateRecognitionResultsメソッドで、潜在的なテキストのコレクションが、手書きの認識からマッチするよう更新します。

認識された手書きの結果テキストのコレクション内を反復処理しながら、以下の処理を行います。

InkRecognitionResult.GetTextCandidatesメソッドで、手書き認識と一致する可能性のある候補として識別された、文字列のコレクションを取得して、変数myTextに格納します。認識された文字列をTextBoxに表示します。

非同期処理で行われますので、メソッドの先頭にAsyncを追加します。

  Private Async Sub recognizeButton_Click(sender As Object, e As RoutedEventArgs) Handles recognizeButton.Click
    Dim myStroke As IReadOnlyList(Of InkStroke) = myInkManager.GetStrokes
    For i As Integer = 0 To myStroke.Count - 1
      myStroke(i).Selected = True
    Next
 
    Dim myRecName = "Microsoft 日本語手書き認識エンジン"
    Dim myRecognizer As IReadOnlyList(Of InkRecognizer) = myInkManager.GetRecognizers
 
    For i As Integer = 0 To myRecognizer.Count - 1
      If myRecName = myRecognizer(i).Name Then
        myInkManager.SetDefaultRecognizer(myRecognizer(i))
      End If
    Next
 
    Dim result As IReadOnlyList(Of InkRecognitionResult) = Await myInkManager.RecognizeAsync(InkRecognitionTarget.All)
      myInkManager.UpdateRecognitionResults(result)
    
    Dim myAlternate = String.Empty
    For Each myResult In result
      Dim myText = myResult.GetTextCandidates
      myAlternate = myAlternate & " " & myText(0)
      TextBox1.Text = myAlternate
    Next
  End Sub
End Class

このサンプルを応用したストアアプリが下記のリンク先で公開されています。
手書き住所読み取り

今回はここまでです。ありがとうございました。

編集部より:サンプルプログラムへのリンクが誤っていたため、修正しました。(2012.11.16)

  • フリーハンドの文字を認識させるサンプルアプリ

薬師寺国安事務所

薬師寺国安事務所代表。Visual Basic プログラミングと、マイクロソフト系の技術をテーマとした、書籍や記事の執筆を行う。
1950年生まれ。事務系のサラリーマンだった40歳から趣味でプログラミングを始め、1996年より独学でActiveXに取り組む。1997年に薬師寺聖とコラボレーション・ユニット PROJECT KySS を結成。2003年よりフリーになり、PROJECT KySS の活動に本格的に参加、.NETやRIAに関する書籍や記事を多数執筆する傍ら、受託案件のプログラミングも手掛ける。Windows Phoneアプリ開発を経て、現在はWindows ストア アプリを多数公開中

Microsoft MVP for Development Platforms - Client App Dev (Oct 2003-Sep 2012)。Microsoft MVP for Development Platforms - Windows Phone Development(Oct 2012-Sep 2013)。Microsoft MVP for Development Platforms - Client Development(Oct 2013-Sep 2014)。Microsoft MVP for Development Platforms-Windows Platform Development (Oct 2014-Sep 2015)。

連載バックナンバー

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています