Tablet PC: Performing Ink layout analysis with the Divider object

In my last few posts, I’ve talked about various handwriting recognition scenarios using the Tablet PC Platform SDK 1.7. While handwriting recognition is perhaps the most common analysis activity with Ink, there’s another interesting way we can interpret Ink- “Layout Analysis”. Layout analysis involves interpreting the type of content the handwritten in is comprised of. First off, there’s a fundamental distinction between drawings and handwriting. Within the handwriting category, there’s a few subcategories.

Categories of ink:

- Drawing

- Handwriting

o Paragraphs

o Lines

o Segments (Words)

Using the existing Tablet PC Platform SDK 1.7 API you can perform layout analysis using the Microsoft.Ink.Divider object. To get started with a Divider, first instantiate the Divider, associate strokes with the divider, then call the Divide() method which will return a DivisionResult object. You can then call DivisionResults.ResultsByType() to obtain the division results for a particular type of ink category (See enum values below)

 

InkDivisionType enumeration:

InkDivisionType.Drawing

InkDivisionType.Paragraph

InkDivisionType.Line

InkDivisionType.Segment

In the following code sample, I’ve updated our evolving basic ink application to perform layout analysis on the ink collected by the InkOverlay when the user clicks a button. In this case, I create a Divider object, call Divider.Divide(), then call ResultByType() for each of the InkDivisionType enum values, and finally display the statistics to the user.

Example Code:

//

// Basic Ink enabled Windows Forms application with

// handwriting recognition using RecognizerContext

// Gavin Gear - https://blogs.msdn.com/gavingear

// 08/2006

//

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Text;

using System.Windows.Forms;

using Microsoft.Ink; // The managed Tablet PC API

namespace BasicInkApplication

{

    public partial class BasicInkApplication : Form

    {

        // The InkOverlay that we'll attach to our Form

        private InkOverlay inkOverlay;

        public BasicInkApplication()

   {

            InitializeComponent();

            // Create an InkOverlay object that's attached to the Form

            this.inkOverlay = new InkOverlay(this);

            // Enable the InkOverlay (default is Enabled == false)

            this.inkOverlay.Enabled = true;

            // The InkOverlay needs to be disposed due to unmanaged resources

            // used by the InkOverlay

            this.FormClosing += new FormClosingEventHandler(BasicInkApplication_FormClosing);

        }

      void BasicInkApplication_FormClosing(object sender, FormClosingEventArgs e)

        {

            this.inkOverlay.Dispose();

        }

        private void buttonRecognize_Click(object sender, EventArgs e)

        {

            // Instantiate a Divider object passing the strokes

            // collected by the InkOverlay

            Divider divider = new Divider(this.inkOverlay.Ink.Strokes);

            // Perform the layout analysis

            DivisionResult result = divider.Divide();

            // Get the division units by type

            DivisionUnits drawings = result.ResultByType(InkDivisionType.Drawing);

            DivisionUnits paragraphs = result.ResultByType(InkDivisionType.Paragraph);

            DivisionUnits lines = result.ResultByType(InkDivisionType.Line);

            DivisionUnits words = result.ResultByType(InkDivisionType.Segment);

            MessageBox.Show(

                "Found " + drawings.Count.ToString() + " drawings" + Environment.NewLine +

                "Found " + paragraphs.Count.ToString() + " paragraphs" + Environment.NewLine +

                "Found " + lines.Count.ToString() + " lines" + Environment.NewLine +

                "Found " + words.Count.ToString() + " words");

            // Free unmanaged resources associated with the Divider object

            divider.Dispose();

        }

    }

}

 

   

Check out the screenshot attachments demonstrating the results produced by using the example code above. Note that in order for ink to be classified as drawings the size of the strokes should be large. Also note that the Divider does not support asynchronous division.

See Ya-

Gavin

divider_test.jpg