Questo post è stato scritto da Massimo Bonanni, MVP Visual Basic

In questo post prenderemo in esame una nuova funzionalità esposta dai servizi di BING che può essere utile nelle applicazioni Windows Store App. Si tratta della possibilità di avere a disposizione un controllo OCR e dei servizi nella Cloud che consentano di analizzare una immagine alla ricerca del testo in essa contenuto.

Cosa è OCR

OCR è l'acronimo di Optical Character Recognition cioè "Riconoscimento Ottico di Caratteri" e identifica tutti quegli algoritmi, legati all'intelligenza artificiale, alla visione artificiale e al pattern recognition, che consentono di "scovare" del testo all'interno di immagini e di convertirlo in un normale testo utilizzabile in un editor o in un software.

Sistemi OCR sono utilizzati fin dagli anni 60. Il sistema postale USA li utilizza dal 1965 per catalogare automaticamente le lettere in base all'indirizzo riconosciuto tramite questi algoritmi.

Attivare il servizio BING

L'architettura per l'utilizzo della tecnologia OCR nelle nostre applicazioni si basa sull'uso di un controllo e di un servizio hostato su Azure.

L'accesso a tutte le informazioni relative sia al controllo che al servizio è attraverso il BING Developer Center all'indirizzo http://it.bing.com/dev

Il controllo è scaricabile all'indirizzo http://visualstudiogallery.msdn.microsoft.com/5434265c-683c-4bb9-adc2-2710f89c264a o tramite la funzione "Extensions and Updates..." di Visual Studio 2013.

clip_image002

Figure 1 : la pagina web di download del controllo

clip_image003

Figure 2 : la funzionalità Extensions and Updates di Visual Studio

Il controllo e il relativo SDK per l'interazione con il servizio di OCR, al momento, funzionano con Visual Studio 2013.

La documentazione relativa al controllo è disponibile all'indirizzo http://msdn.microsoft.com/en-us/library/dn261719.aspx.

Per poter finalmente utilizzare il controllo OCR all'interno della nostra applicazione, dobbiamo sottoscrivere un abbonamento al servizio di riconoscimento caratteri hostato su Azure e la cui pagina dell'Azure Marketplace è disponibile all'indirizzo https://datamarket.azure.com/dataset/bing/OCRControl

clip_image005

Figure 3 : La pagina dell'Azure Marketplace per il servizio di OCR

Esiste un abbonamento gratuito che ha come limite 5000 transazioni mensili (assolutamente sufficiente per eseguire dei test).

ClientSecret e ClientID

I servizi BING su Azure necessitano dei parametri ClientID e SecretClient per l'autenticazione.

Anche il controllo OCR ha la necessità di avere tali parametri e, per poterli generare dobbiamo registrare la nostra applicazione che farà uso del controllo alla pagina https://datamarket.azure.com/developer/applications utilizzando il tasto "Registra":

clip_image007

Figure 4 : La pagina delle applicazioni che utilizzano servizi Bing

La registrazione di una applicazione prevede che decidiamo noi il ClientId (che non deve esistere) e il sistema genera il SecretClient:

clip_image009

Figure 5 : Le impostazioni dell'applicazione

Una volta che abbiamo in mano i due parametri possiamo costruire l'applicazione.

Creiamo la nostra interfaccia

Prima di tutto, poiché il controllo OCR utilizza la webcam, dobbiamo abilitare nel manifest della nostra applicazione l'utilizzo della stessa:

clip_image010

Figure 6 : Le capability dell'app

A questo punto ci basta trascinare il controllo all'interno dello XAML per poterne utilizzare le funzionalità.

Per prima cosa, nel momento in cui viene caricata la nostra form, dobbiamo impostare i valori del ClientId e SecretClient di cui abbiamo parlato in precedenza:

Private Sub Page_Loaded(sender As Object, e As RoutedEventArgs)

ocrControl.ClientId = "<CLIENT ID>"

ocrControl.ClientSecret = "<CLIENT SECRET>"

AddHandler ocrControl.Completed, AddressOf ocrControl_Completed

AddHandler ocrControl.CameraChanged, AddressOf ocrControl_CameraChanged

AddHandler ocrControl.FrameCaptured, AddressOf ocrControl_FrameCaptured

AddHandler ocrControl.Failed, AddressOf ocrControl_Failed

End Sub

Nel precedente pezzo di codice possiamo anche vedere che il controllo ci mette a disposizione 4 eventi di cui ci occuperemo in seguito.

L'utilizzo del controllo OCR prevede due fasi:

· una fase di avvio della modalità di preview (quella che permette all'utente di vedere ciò che la sua webcam sta inquadrando prima di catturare l'immagine da digitalizzare) grazie al StartPreviewAsync() (ovviamente asincrono);

· una fase di effettiva cattura ed elaborazione dell'immagine che ha inizio con la chiamata del metodo CaptureFrame. La figura seguente mostra il meccanismo su cui si basa l'elaborazione dell'immagine:

clip_image012

Figure 7 : Il meccanismo di elaborazione dell'immagine OCR

Il tutto inizia con la chiamata al metodo CaptureFrame:

Private Sub ocrControl_Tapped(sender As Object, e As TappedRoutedEventArgs) Handles ocrControl.Tapped

ocrControl.CaptureLanguage = "it"

ocrControl.CaptureFrame()

End Sub

Osserviamo che si può impostare anche la lingua del testo che si sta elaboando. La lista dei linguaggi supportati dal controllo si può ottenere richiamando il metodo statico asincrono OcrControl.GetLanguagesAsync.

clip_image014

Figure 8 : L'elenco delle lingue supportate

Quando il frame della webcam è stato catturato dal controllo OCR e, prima che questo lo invii al servizio nel cloud, viene sollevato l'evento FrameCaptured:

Private Sub ocrControl_FrameCaptured(sender As Object, e As Bing.Ocr.FrameCapturedEventArgs)

Dim bitmap = New BitmapImage()

bitmap.SetSource(e.CapturedImage)

imgResult.Source = bitmap

End Sub

Nel caso di specie, recuperiamo l'immagine dallo stream fornito dalla proprietà CapturedImage dell'argomento dell'evento e la visualiziamo.

A questo punto, se c'è connettività, l'immagine è inviata al servizio fornito da Bing che, nel momento in cui termina l'operazione di analisi dell'immagine e se non accadono erori di alcun genere, resituisce il risultato e il controllo OCR solleva l'evento Completed:

Private Async Sub ocrControl_Completed(sender As Object, e As Bing.Ocr.OcrCompletedEventArgs)

Dim scalefactor = imgResult.ActualWidth / CType(imgResult.Source, BitmapImage).PixelWidth

gridResult.Children.Clear()

lstWords.Items.Clear()

For Each line In e.Result.Lines

For Each word In line.Words

Dim textBox = CreateTextBox(word)

Dim border = CreateBorder(word, scalefactor)

border.Child = textBox

gridResult.Children.Add(border)

lstWords.Items.Add(word.Value)

Next

Next

gridResult.RenderTransform = CreateTransformGroup(e.Result)

Await ocrControl.StartPreviewAsync(Nothing)

End Sub

L'argomento dell'evento fornisce nuovamente l'immagine catturata, un identificativo della transazione sul serve e la proprietà Result che espone i dati ricavati dall'elaborazione.

La proprietà Result, di tipo OcrResult, espone una collezione di oggetti Ocr.Line e la rotazione dell'immagine rispetto alla verticale.

Ogni oggetto di tipo Ocr.Line espone il rettangolo in cui la linea di testo è stata rilevata (proprietà Box) e l'elenco degli oggetti di tipo Ocr.Word che contengono i dati di ogni singola parola rilevata.

Ogni oggetto Ocr.Word espone, a sua volta il rettangolo che contiene la parola trovata (proprietà Box) e la parola stessa (proprietà Value).

In questo modo siamo in grado di utilizzare il testo ma anche di sapere dove si trovano, all'interno dell'immagine catturata, le parole stesse.

Per completare il giro possiamo riposizionare la camera in preview (richiamando il metodo StartPreviewAsync) oppure la disabilitiamo con il metodo ResetAsync. E' buona pratica quella di attivare la camera per il tempo strettamente necessario all'elaborazione.

Nella demo allegata posizioniamo un TextBlock circondato da un Border al di sopra della parola trovata.

clip_image016

Figure 9 : Esempio di utilizzo dell'OCR

Nel caso in cui non sia disponibile una connessione internet, o si verifichi un qualsiasi tipo di errore nell'operazione di riconoscimento, il controllo OCR solleva l'evento Failed.

L'argomento di questo evento ci consente di sapere esattamente cosa è accaduto poiché ci mette a disposizione le proprietà ErrorCode e ErrorMessage.

I possibili errori sono esposti dall'enumerazione Ocr.ErrorCode (http://msdn.microsoft.com/en-us/library/dn261728.aspx)

Un altro evento esposto dal controllo è l'evento CameraChanged che viene sollevato ogni volta che si cambia la camera (lo si può fare da codice o con il tasto che appare nel controllo OCR stesso).

Scarica il progetto