Riconoscimento della scrittura a mano libera degli utenti

L'API di riconoscimento della scrittura a mano libera ti consente di riconoscere il testo inserito a mano libera in tempo reale.

Christian Liebel
Christian Liebel
Thomas Steiner
Thomas Steiner

Che cos'è l'API di riconoscimento della scrittura a mano libera?

L'API di riconoscimento della scrittura a mano libera ti consente di convertire la scrittura a mano libera (ink) degli utenti in testo. Alcuni sistemi operativi includono da tempo tali API e, con questa nuova funzionalità, le app web possono e infine usare questa funzionalità. La conversione avviene direttamente sul dispositivo dell'utente e funziona anche in modalità offline, il tutto senza aggiungere librerie o servizi di terze parti.

Questa API implementa i sistemi cosiddetti "online" o quasi in tempo reale. Ciò significa che l'input scritto a mano viene riconosciuto mentre l'utente lo sta disegnando acquisendo e analizzando il singolo bracciate. A differenza di "off-line" come il riconoscimento ottico dei caratteri (OCR), per solo il prodotto finale è noto, gli algoritmi online possono fornire un livello di precisione maggiore grazie segnali aggiuntivi come la sequenza temporale e la pressione dei singoli tratti di inchiostro.

Casi d'uso suggeriti per l'API di riconoscimento della scrittura a mano libera

Esempi di utilizzo includono:

  • Applicazioni per prendere appunti in cui gli utenti vogliono acquisire note scritte a mano libera e tradurle in un testo.
  • Moduli le applicazioni in cui gli utenti possono utilizzare la penna o l'immissione con le dita a causa di limiti di tempo.
  • Giochi che richiedono l'inserimento di lettere o numeri, come cruciverba, impiccato o sudoku.

Stato attuale

L'API di riconoscimento della scrittura a mano libera è disponibile su (Chromium 99).

Come utilizzare l'API di riconoscimento della scrittura a mano libera

Rilevamento delle caratteristiche

Rileva il supporto del browser controllando l'esistenza del metodo createHandwritingRecognizer() sull'oggetto navigatore:

if ('createHandwritingRecognizer' in navigator) {
  // 🎉 The Handwriting Recognition API is supported!
}

Concetti principali

L'API di riconoscimento della scrittura a mano libera converte l'input scritto a mano libera in testo, indipendentemente dal metodo di immissione (mouse, tocco, penna). L'API ha quattro entità principali:

  1. Un punto rappresenta il punto in cui si trovava il puntatore in un determinato momento.
  2. Un tratto è costituito da uno o più punti. La registrazione di un ictus inizia quando l'utente mette il puntatore verso il basso (ad esempio quando fa clic sul pulsante principale del mouse o tocca lo schermo con la penna o dito) e terminano quando solleva di nuovo il puntatore.
  3. Un disegno è costituito da uno o più tratti. Il riconoscimento effettivo avviene a questo livello.
  4. Il riconoscimento viene configurato con la lingua di input prevista. Viene utilizzato per creare un'istanza di un disegno a cui è applicata la configurazione del riconoscimento.

Questi concetti vengono implementati come interfacce e dizionari specifici, di cui parleremo a breve.

Le entità principali dell'API di riconoscimento della scrittura a mano libera: uno o più punti compongono un tratto, uno o più tratti compongono un disegno, creato dal riconoscimento. Il riconoscimento effettivo avviene a livello di disegno.

Creazione di un riconoscimento in corso...

Per riconoscere un testo da un input scritto a mano, devi ottenere un'istanza di un HandwritingRecognizer chiamando navigator.createHandwritingRecognizer() e passando i vincoli che le sono assegnati. I vincoli determinano il modello di riconoscimento della scrittura a mano libera da utilizzare. Al momento, puoi specificare un elenco di lingue in ordine di preferenza:

const recognizer = await navigator.createHandwritingRecognizer({
  languages: ['en'],
});

Il metodo restituisce una promessa che viene risolta con un'istanza di HandwritingRecognizer quando browser può soddisfare la tua richiesta. In caso contrario, rifiuterà la promessa con un errore e il riconoscimento scrittura non sarà disponibile. Per questo motivo, ti consigliamo di eseguire una query il supporto del riconoscimento per determinate funzioni di riconoscimento.

Esecuzione di query sul supporto del riconoscimento

Chiamando navigator.queryHandwritingRecognizerSupport(), puoi verificare se la piattaforma di destinazione supporta le funzionalità di riconoscimento della scrittura che intendi utilizzare. Nell'esempio seguente, sviluppatore:

  • vuole rilevare i testi in inglese
  • ottenere previsioni alternative, meno probabili, se disponibili
  • ottenere l'accesso al risultato della segmentazione, ovvero i caratteri riconosciuti, inclusi punti e bracciate che li compongono
const { languages, alternatives, segmentationResults } =
  await navigator.queryHandwritingRecognizerSupport({
    languages: ['en'],
    alternatives: true,
    segmentationResult: true,
  });

console.log(languages); // true or false
console.log(alternatives); // true or false
console.log(segmentationResult); // true or false

Il metodo restituisce una promessa che viene risolta con un oggetto risultato. Se il browser supporta la funzionalità specificato dallo sviluppatore, il suo valore verrà impostato su true. In caso contrario, verrà impostato su false. Puoi usare queste informazioni per attivare o disattivare determinate funzioni all'interno della tua applicazione oppure per modificare la query e inviarne una nuova.

Inizia a disegnare

All'interno dell'applicazione, dovresti offrire un'area di input in cui l'utente esegue la propria scrittura a mano libera le voci corrispondenti. Ai fini delle prestazioni, si consiglia di implementare questa funzionalità con l'aiuto di una oggetto canvas. L'esatto di questa parte non rientra nell'ambito di questo articolo, ma puoi fare riferimento alla demo per capire come fare.

Per iniziare un nuovo disegno, chiama il metodo startDrawing() sul riconoscimento. Questo metodo prende un contenente diversi suggerimenti per perfezionare l'algoritmo di riconoscimento. Tutti i suggerimenti sono facoltativi:

  • Il tipo di testo inserito: testo, indirizzi email, numeri o un singolo carattere. (recognitionType)
  • Il tipo di dispositivo di input: mouse, tocco o input della penna (inputType)
  • Il testo precedente (textContext)
  • Il numero di previsioni alternative meno probabili che devono essere restituite (alternatives)
  • Un elenco di caratteri identificabili dall'utente ("grafemi") che l'utente probabilmente inserirà (graphemeSet)

L'API di riconoscimento della scrittura a mano libera funziona bene con Eventi puntatore, che offrono una un'interfaccia astratta per consumare input da qualsiasi dispositivo di puntamento. Gli argomenti dell'evento puntatore contengono il tipo di puntatore utilizzato. Ciò significa che puoi utilizzare eventi puntatore per determinare il tipo di input automaticamente. Nel seguente esempio, il disegno per il riconoscimento della scrittura a mano libera viene creato alla prima occorrenza di un evento pointerdown nell'area di scrittura a mano libera. Come pointerType può essere vuoto o impostato su un valore proprietario, ho introdotto un controllo di coerenza per rendere assicurati che siano impostati solo i valori supportati per il tipo di input del disegno.

let drawing;
let activeStroke;

canvas.addEventListener('pointerdown', (event) => {
  if (!drawing) {
    drawing = recognizer.startDrawing({
      recognitionType: 'text', // email, number, per-character
      inputType: ['mouse', 'touch', 'pen'].find((type) => type === event.pointerType),
      textContext: 'Hello, ',
      alternatives: 2,
      graphemeSet: ['f', 'i', 'z', 'b', 'u'], // for a fizz buzz entry form
    });
  }
  startStroke(event);
});

Aggiungi un tratto

L'evento pointerdown è anche il posto giusto per iniziare un nuovo tratto. Per farlo, crea un nuovo di HandwritingStroke. Inoltre, devi memorizzare l'ora corrente come punto di riferimento per i punti successivi aggiunti:

function startStroke(event) {
  activeStroke = {
    stroke: new HandwritingStroke(),
    startTime: Date.now(),
  };
  addPoint(event);
}

Aggiunge un punto

Dopo aver creato il tratto, devi aggiungere direttamente il primo punto. Man mano che ne aggiungerai altri in un secondo momento, ha senso implementare la logica di creazione dei punti in un metodo separato. Nella Nell'esempio seguente, il metodo addPoint() calcola il tempo trascorso dal timestamp di riferimento. Le informazioni sulla tempistica sono facoltative, ma possono migliorare la qualità del riconoscimento. Quindi legge la X e Coordinate Y dall'evento del puntatore e aggiungere il punto al tratto corrente.

function addPoint(event) {
  const timeElapsed = Date.now() - activeStroke.startTime;
  activeStroke.stroke.addPoint({
    x: event.offsetX,
    y: event.offsetY,
    t: timeElapsed,
  });
}

Il gestore di eventi pointermove viene chiamato quando il puntatore viene spostato sullo schermo. Questi punti devono essere aggiunti al tratto. L'evento può essere generato anche se il puntatore non si trova in una "verso il basso" , ad esempio quando sposti il cursore sullo schermo senza premere il mouse . Il gestore di eventi dell'esempio seguente controlla se esiste un tratto attivo e aggiunge il parametro un nuovo punto.

canvas.addEventListener('pointermove', (event) => {
  if (activeStroke) {
    addPoint(event);
  }
});

Riconoscimento del testo

Quando l'utente solleva nuovamente il puntatore, puoi aggiungere il tratto al disegno chiamando la relativa addStroke(). Anche l'esempio seguente reimposta activeStroke, quindi pointermove non aggiungerà punti al tratto completato.

A questo punto occorre riconoscere l'input dell'utente chiamando il metodo getPrediction() sulla disegno. Il riconoscimento richiede in genere meno di qualche centinaio di millisecondi, quindi puoi eseguire ripetutamente le previsioni, se necessario. L'esempio seguente esegue una nuova previsione dopo ogni tratto completato.

canvas.addEventListener('pointerup', async (event) => {
  drawing.addStroke(activeStroke.stroke);
  activeStroke = null;

  const [mostLikelyPrediction, ...lessLikelyAlternatives] = await drawing.getPrediction();
  if (mostLikelyPrediction) {
    console.log(mostLikelyPrediction.text);
  }
  lessLikelyAlternatives?.forEach((alternative) => console.log(alternative.text));
});

Questo metodo restituisce una promessa che si risolve con un array di previsioni ordinate in base al probabilità. Il numero di elementi dipende dal valore passato al suggerimento alternatives. Tu utilizzare questo array per offrire all'utente una scelta di possibili corrispondenze e chiedergli di selezionare . In alternativa, potete semplicemente scegliere la previsione più probabile, che è ciò che faccio nel esempio.

L'oggetto Prediction contiene il testo riconosciuto e un risultato di segmentazione facoltativo, che indicherò di cui parleremo nella sezione seguente.

Statistiche dettagliate con risultati di segmentazione

Se supportato dalla piattaforma di destinazione, l'oggetto di previsione può contenere anche un risultato di segmentazione. Si tratta di un array contenente tutti i segmenti di scrittura a mano libera riconosciuti, una combinazione dei carattere identificabile dall'utente (grapheme) insieme alla sua posizione nel testo riconosciuto (beginIndex, endIndex) e i tratti e i punti che l'hanno creato.

if (mostLikelyPrediction.segmentationResult) {
  mostLikelyPrediction.segmentationResult.forEach(
    ({ grapheme, beginIndex, endIndex, drawingSegments }) => {
      console.log(grapheme, beginIndex, endIndex);
      drawingSegments.forEach(({ strokeIndex, beginPointIndex, endPointIndex }) => {
        console.log(strokeIndex, beginPointIndex, endPointIndex);
      });
    },
  );
}

Puoi utilizzare queste informazioni per individuare di nuovo i grafemi riconosciuti sulla tela.

Intorno a ciascun grafema riconosciuto sono tracciate delle caselle

Riconoscimento completo

Una volta completato il riconoscimento, puoi liberare risorse chiamando il metodo clear() sul HandwritingDrawing e il metodo finish() su HandwritingRecognizer:

drawing.clear();
recognizer.finish();

Demo

Il componente web <handwriting-textarea> implementa una migliorati progressivamente, controllo di modifica in grado di scrivere a mano libera di riconoscimento dei volti delle celebrità basata su rigidi criteri di controllo. Se fai clic sul pulsante nell'angolo in basso a destra del controllo di modifica, attivi modalità disegno. Una volta completato il disegno, il componente web avvierà automaticamente la riconoscimento e aggiungere di nuovo il testo riconosciuto al controllo di modifica. Se la funzionalità di riconoscimento della scrittura L'API non è supportata oppure la piattaforma non supporta le funzionalità richieste, pulsante di modifica verrà nascosta. Tuttavia, il controllo di modifica di base rimane utilizzabile come <textarea>.

Il componente web offre proprietà e attributi per definire il comportamento di riconoscimento dalla esterni, inclusi languages e recognitiontype. Puoi impostare il contenuto del controllo tramite il Attributo value:

<handwriting-textarea languages="en" recognitiontype="text" value="Hello"></handwriting-textarea>

Per ricevere informazioni su eventuali modifiche al valore, puoi ascoltare l'evento input.

Puoi provare il componente utilizzando questa demo su Glitch. Dai anche un'occhiata alle codice sorgente. Per utilizzare il controllo ottienilo da npm.

Sicurezza e autorizzazioni

Il team di Chromium ha progettato e implementato l'API di riconoscimento della scrittura a mano libera utilizzando i principi fondamentali definita in Controllo dell'accesso a funzionalità avanzate della piattaforma web, tra cui le controllo, trasparenza ed ergonomia.

Controllo utenti

L'API di riconoscimento della scrittura a mano libera non può essere disattivata dall'utente. È disponibile solo per i siti web forniti tramite HTTPS e possono essere richiamati solo dal contesto di navigazione di primo livello.

Trasparenza

Non viene visualizzata alcuna indicazione relativa al fatto che il riconoscimento della scrittura a mano libera è attivo. Per impedire il fingerprinting, il browser implementa contromisure, ad esempio mostra una richiesta di autorizzazione all'utente quando rileva possibile abuso.

Persistenza dell'autorizzazione

L'API di riconoscimento della scrittura a mano libera attualmente non mostra richieste di autorizzazione. Pertanto, l'autorizzazione non deve essere mantenuto in alcun modo.

Feedback

Il team di Chromium vuole saperne di più sulla tua esperienza relativa all'API di riconoscimento della scrittura a mano libera.

Parlaci della progettazione dell'API

C'è qualcosa nell'API che non funziona come previsto? Oppure mancano metodi o le proprietà necessarie per implementare la tua idea? Hai una domanda o un commento sulla sicurezza modello? Segnala un problema relativo alle specifiche sul repository GitHub corrispondente o aggiungi le tue opinioni a un problema esistente.

Segnalare un problema con l'implementazione

Hai trovato un bug nell'implementazione di Chromium? Oppure l'implementazione è diversa dalle specifiche? Segnala un bug all'indirizzo new.crbug.com. Includi il maggior numero di dettagli possibile, semplici istruzioni per la riproduzione e inserisci Blink>Handwriting nella casella Componenti. Glitch è la soluzione perfetta per condividere riproduzioni in modo facile e veloce.

Mostra il supporto per l'API

Intendi utilizzare l'API di riconoscimento della scrittura a mano libera? Il tuo supporto pubblico aiuta il team di Chromium dare la priorità alle funzionalità e indica agli altri fornitori di browser quanto sia fondamentale supportarli.

Spiega come intendi utilizzarlo nel thread del discorso di WicG. Invia un tweet a @ChromiumDev utilizzando l'hashtag #HandwritingRecognition: e facci sapere dove e come lo utilizzi.

Ringraziamenti

Questo articolo è stato scritto da Joe Medley, Honglin Yu e Jiewei Qian. Immagine hero di Samir Bouaked il Rimuovi schermo.