Come estrarre il testo dalle immagini con l'SDK di Machine Learning di Google

Autore: John Stephens
Data Della Creazione: 27 Gennaio 2021
Data Di Aggiornamento: 5 Luglio 2024
Anonim
Come estrarre il testo dalle immagini con l'SDK di Machine Learning di Google - Applicazioni
Come estrarre il testo dalle immagini con l'SDK di Machine Learning di Google - Applicazioni

Contenuto


Potresti anche utilizzare l'API di riconoscimento del testo come base per le app di traduzione o servizi di accessibilità in cui l'utente può puntare la propria videocamera su qualsiasi testo con cui sta lottando e farlo leggere ad alta voce.

In questo tutorial, getteremo le basi per una vasta gamma di funzioni innovative, creando un'app in grado di estrarre il testo da qualsiasi immagine nella galleria dell'utente. Anche se non lo tratteremo in questo tutorial, potresti anche catturare il testo dall'ambiente dell'utente in tempo reale, collegando questa applicazione alla fotocamera del dispositivo.

Sul dispositivo o nel cloud?

Alcune API del kit ML sono disponibili solo sul dispositivo, ma alcune sono disponibili sul dispositivo e nel cloud, inclusa l'API di riconoscimento del testo.

L'API di testo basata su cloud è in grado di identificare una gamma più ampia di lingue e caratteri e promette una maggiore precisione rispetto alla sua controparte sul dispositivo. Comunque fa richiede una connessione Internet attiva ed è disponibile solo per progetti di livello Blaze.


In questo articolo, eseguiremo l'API di riconoscimento del testo localmente, in modo da poter seguire indipendentemente dal fatto che tu abbia eseguito l'upgrade a Blaze o che tu sia nel piano Firebase Spark gratuito.

Creazione di un'app di riconoscimento del testo con ML Kit

Crea un'applicazione con le impostazioni che preferisci, ma quando richiesto seleziona il modello "Svuota attività".

ML Kit SDK fa parte di Firebase, quindi dovrai connettere il tuo progetto a Firebase, usando il suo certificato di firma SHA-1. Per ottenere SHA-1 del tuo progetto:

  • Seleziona la scheda "Gradle" di Android Studio.
  • Nel pannello "Progetti pendenza", fai doppio clic per espandere la "radice" del progetto, quindi seleziona "Attività> Android> Rapporto firma".
  • Il pannello nella parte inferiore della finestra di Android Studio dovrebbe essere aggiornato per visualizzare alcune informazioni su questo progetto, incluso il certificato di firma SHA-1.


Per connettere il tuo progetto a Firebase:

  • Nel tuo browser web, avvia Firebase Console.
  • Seleziona "Aggiungi progetto".
  • Dai un nome al tuo progetto; Sto usando "ML Test".
  • Leggi i termini e le condizioni e, se sei felice di procedere, seleziona "Accetto ..." seguito da "Crea progetto".
  • Seleziona "Aggiungi Firebase alla tua app Android".
  • Inserisci il nome del pacchetto del tuo progetto, che troverai nella parte superiore del file MainActivity e all'interno del Manifest.
  • Inserisci il certificato di firma SHA-1 del tuo progetto.
  • Fai clic su "Registra app".
  • Seleziona "Scarica google-services.json". Questo file contiene tutti i metadati Firebase necessari per il tuo progetto, inclusa la chiave API.
  • In Android Studio, trascina e rilascia il file google-services.json nella directory "app" del tuo progetto.

  • Apri il tuo file build.gradle a livello di progetto e aggiungi il percorso di classe dei servizi Google:

classpath com.google.gms: google-services: 4.0.1

  • Apri il tuo file build.gradle a livello di app e aggiungi dipendenze per Firebase Core, Firebase ML Vision e l'interprete dei modelli, oltre al plug-in dei servizi di Google:

applica plugin: com.google.gms.google-services ... ... ... dipendenze {implementazione fileTree (dir: libs, include:) implementazione com.google.firebase: firebase-core: 16.0.1 implementazione com. google.firebase: firebase-ml-vision: implementazione 16.0.0 com.google.firebase: firebase-ml-modello-interprete: 16.0.0

A questo punto, dovrai eseguire il tuo progetto in modo che possa connettersi ai server Firebase:

  • Installa la tua app su uno smartphone o tablet Android fisico o su un dispositivo virtuale Android (AVD).
  • In Firebase Console, seleziona "Esegui app per verificare l'installazione".
  • Dopo alcuni istanti, dovresti vedere un "Congratulazioni"; seleziona "Continua con la console".

Scarica i modelli di apprendimento automatico pre-addestrati di Google

Per impostazione predefinita, ML Kit scarica i modelli solo quando e quando sono necessari, quindi la nostra app scaricherà il modello OCR quando l'utente tenta di estrarre il testo per la prima volta.

Ciò potrebbe potenzialmente avere un impatto negativo sull'esperienza dell'utente: immagina di provare ad accedere a una funzione, solo per scoprire che l'app deve scaricare più risorse prima di poter effettivamente offrire questa funzione. Nel peggiore dei casi, la tua app potrebbe non essere nemmeno in grado di scaricare le risorse di cui ha bisogno, quando ne ha bisogno, ad esempio se il dispositivo non ha una connessione Internet.

Per assicurarmi che ciò non accada con la nostra app, ho intenzione di scaricare il modello OCR necessario al momento dell'installazione, il che richiede alcune modifiche a Maniest.

Mentre il Manifest è aperto, aggiungerò anche l'autorizzazione WRITE_EXTERNAL_STORAGE, che useremo più avanti in questo tutorial.

// Aggiungi l'autorizzazione WRITE_EXTERNAL_STORAGE // // Aggiungi quanto segue //

Costruire il layout

Togliamo le cose semplici e creiamo un layout composto da:

  • Un ImageView. Inizialmente, verrà visualizzato un segnaposto, ma verrà aggiornato una volta che l'utente seleziona un'immagine dalla propria galleria.
  • Un pulsante, che attiva l'estrazione del testo.
  • Un TextView, in cui visualizzeremo il testo estratto.
  • A ScrollView. Poiché non vi è alcuna garanzia che il testo estratto si adatti perfettamente allo schermo, inserirò TextView all'interno di ScrollView.

Ecco il file completato activity_main.xml:

Questo layout fa riferimento a un disegno "ic_placeholder", quindi creiamo questo ora:

  • Seleziona "File> Nuovo> Risorse immagine" dalla barra degli strumenti di Android Studio.
  • Apri il menu a discesa "Tipo icona" e seleziona "Barra delle azioni e icone della scheda".
  • Assicurarsi che il pulsante di opzione "Clip Art" sia selezionato.
  • Fai un clic sul pulsante "Clip Art".
  • Seleziona l'immagine che desideri utilizzare come segnaposto; Sto usando "Aggiungi alle foto".
  • Fai clic su "OK".
  • Apri il menu a discesa "Tema" e seleziona "HOLO_LIGHT".
  • Nel campo "Nome", inserisci "ic_placeholder".
  • Fai clic su "Avanti". Leggi le informazioni e, se sei felice di procedere, fai clic su "Fine".

Icone della barra delle azioni: avvio dell'app Galleria

Successivamente, creerò un elemento della barra delle azioni che avvierà la galleria dell'utente, pronto per consentire loro di selezionare un'immagine.

Si definiscono le icone della barra delle azioni all'interno di un file di risorse del menu, che si trova all'interno della directory "res / menu". Se il tuo progetto non contiene questa directory, dovrai crearla:

  • Fai clic tenendo premuto il tasto Ctrl sulla directory "res" del tuo progetto e seleziona "Nuovo> Directory risorse Android".
  • Apri il menu a discesa "Tipo di risorsa" e seleziona "menu".
  • Il "Nome directory" dovrebbe aggiornarsi automaticamente al "menu", ma in caso contrario dovrai rinominarlo manualmente.
  • Fai clic su "OK".

Ora sei pronto per creare il file di risorse del menu:

  • Fai clic tenendo premuto il tasto Ctrl sulla directory "menu" del progetto e seleziona "Nuovo> File delle risorse del menu".
  • Denominare questo file "my_menu".
  • Fai clic su "OK".
  • Apri il file "my_menu.xml" e aggiungi quanto segue:

//Creare un elemento per ogni azione //

Il file di menu fa riferimento a una stringa "action_gallery", quindi apri il file res / valori / strings.xml del tuo progetto e crea questa risorsa. Mentre sono qui, sto anche definendo le altre stringhe che utilizzeremo durante questo progetto.

Galleria Questa app deve accedere ai file sul tuo dispositivo. Nessun testo trovato

Successivamente, utilizza Image Asset Studio per creare l'icona "ic_gallery" della barra delle azioni:

  • Seleziona "File> Nuovo> Risorse immagine".
  • Imposta il menu a discesa "Tipo di icona" su "Barra delle azioni e icone delle schede".
  • Fai clic sul pulsante "Clip Art".
  • Scegli un disegno; Sto usando "immagine".
  • Fai clic su "OK".
  • Per assicurarti che questa icona sia chiaramente visibile nella barra delle azioni, apri il menu a discesa "Tema" e seleziona "HOLO_DARK".
  • Denominare questa icona "ic_gallery".
  • "Fai clic su" Avanti ", quindi su" Fine ".

Gestione delle richieste di autorizzazione e degli eventi clic

Eseguirò tutte le attività che non sono direttamente correlate all'API di riconoscimento del testo in una classe BaseActivity separata, tra cui l'istanza del menu, la gestione degli eventi di clic sulla barra delle azioni e la richiesta di accesso all'archiviazione del dispositivo.

  • Seleziona "File> Nuovo> Classe Java" dalla barra degli strumenti di Android Studio.
  • Denominare questa classe "BaseActivity".
  • Fai clic su "OK".
  • Apri BaseActivity e aggiungi quanto segue:

import android.app.Activity; import android.support.v4.app.ActivityCompat; import android.support.v7.app.ActionBar; import android.support.v7.app.AlertDialog; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.content.DialogInterface; import android.content.Intent; import android.Manifest; import android.provider.MediaStore; import android.view.Menu; import android.view.MenuItem; import android.content.pm.PackageManager; import android.net.Uri; import android.provider.Settings; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import java.io.File; classe pubblica BaseActivity estende AppCompatActivity {public static final int WRITE_STORAGE = 100; pubblico statico finale int SELECT_PHOTO = 102; public static final String ACTION_BAR_TITLE = "action_bar_title"; foto di file pubblica; @Override protetto void onCreate (@Nullable Bundle savedInstanceState) {super.onCreate (savedInstanceState); ActionBar actionBar = getSupportActionBar (); if (actionBar! = null) {actionBar.setDisplayHomeAsUpEnabled (true); actionBar.setTitle (getIntent () getStringExtra (ACTION_BAR_TITLE).); }} @Override pubblico booleano onCreateOptionsMenu (menu Menu) {getMenuInflater (). Inflate (R.menu.my_menu, menu); ritorno vero; } @Override pubblica booleana onOptionsItemSelected (voce MenuItem) {switch (item.getItemId ()) {// Se è selezionato “gallery_action”, allora ... // case R.id.gallery_action: //...check abbiamo l'autorizzazione WRITE_STORAGE // checkPermission (WRITE_STORAGE); rompere; } return super.onOptionsItemSelected (oggetto); } @Override public void onRequestPermissionsResult (int requestCode, autorizzazioni @NonNull String, @NonNull int grantResults) {super.onRequestPermissionsResult (requestCode, autorizzazioni, grantResults); switch (requestCode) {case WRITE_STORAGE: // Se la richiesta di autorizzazione è concessa, allora ... // if (grantResults.length> 0 && grantResults == PackageManager.PERMISSION_GRANTED) {//...call selectPicture // selectPicture ( ); // Se la richiesta di autorizzazione viene rifiutata, allora ... //} else {//...display la stringa “consent_request” // requestPermission (this, requestCode, R.string.permission_request); } rompere; }} // Visualizza la finestra di dialogo della richiesta di autorizzazione // public void requestPermission (attività di attività finale, finalC requestCode, int msg) {AlertDialog.Builder alert = new AlertDialog.Builder (activity); alert.set (msg); alert.setPositiveButton (android.R.string.ok, nuovo DialogInterface.OnClickListener () {@Override public void onClick (DialogInterface dialogInterface, int i) {dialogInterface.dismiss (); Intent permissonIntent = new Intent (Settings.ACTION_APPLICTS_T_IFS_SIF;) .setData (Uri.parse ("package:" + activity.getPackageName ())); activity.startActivityForResult (permissonIntent, requestCode);}}); alert.setNegativeButton (android.R.string.cancel, nuovo DialogInterface.OnClickListener () {@Override public void onClick (DialogInterface dialogInterface, int i) {dialogInterface.dismiss ();}}); alert.setCancelable (false); alert.show (); } // Verifica se l'utente ha concesso l'autorizzazione WRITE_STORAGE // public void checkPermission (int requestCode) {switch (requestCode) {case WRITE_STORAGE: int hasWriteExternalStoragePermission = ActivityCompat.checkSelfPermission (this, Manifest.permission.WRITE_EXTERNAL_STORAGE); // Se abbiamo accesso all'archivio esterno ... // if (hasWriteExternalStoragePermission == PackageManager.PERMISSION_GRANTED) {//...call selectPicture, che avvia un'attività in cui l'utente può selezionare un'immagine // selectPicture (); // Se l'autorizzazione non è stata concessa, allora ... //} altrimenti {//... richiedi l'autorizzazione // ActivityCompat.requestPermissions (questa, nuova stringa {Manifest.permission.WRITE_EXTERNAL_STORAGE}, requestCode); } rompere; }} void privato selectPicture () {photo = MyHelper.createTempFile (foto); Intent intent = new Intent (Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI); // Avvia un'attività in cui l'utente può scegliere un'immagine // startActivityForResult (intent, SELECT_PHOTO); }}

A questo punto, il tuo progetto dovrebbe lamentarsi del fatto che non è possibile risolvere MyHelper.createTempFile. Ora implementiamo questo!

Ridimensionamento delle immagini con createTempFile

Crea una nuova classe "MyHelper". In questa classe, ridimensioneremo l'immagine scelta dall'utente, pronta per essere elaborata dall'API di riconoscimento del testo.

import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.content.Context; import android.database.Cursor; import android.os.Environment; import android.widget.ImageView; import android.provider.MediaStore; import android.net.Uri; import static android.graphics.BitmapFactory.decodeFile; importare android.graphics.BitmapFactory.decodeStream statico; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class MyHelper {public static String getPath (Context context, Uri uri) {String path = ""; String projection = {MediaStore.Images.Media.DATA}; Cursore cursore = context.getContentResolver (). Query (uri, proiezione, null, null, null); int column_index; if (cursore! = null) {column_index = cursor.getColumnIndexOrThrow (MediaStore.Images.Media.DATA); cursor.moveToFirst (); path = cursor.getString (column_index); cursor.close (); } sentiero di ritorno; } public static File createTempFile (File file) {Directory file = new File (Environment.getExternalStorageDirectory (). getPath () + "/com.jessicathornsby.myapplication"); if (! directory.exists () ||! directory.isDirectory ()) {directory.mkdirs (); } if (file == null) {file = new File (directory, "orig.jpg"); } file di ritorno; } pubblico Bitmap resizePhoto (File imageFile, Context context, Uri uri, vista ImageView) {BitmapFactory.Options newOptions = new BitmapFactory.Options (); try {decodeStream (context.getContentResolver (). openInputStream (uri), null, newOptions); int photoHeight = newOptions.outHeight; int photoWidth = newOptions.outWidth; newOptions.inSampleSize = Math.min (photoWidth / view.getWidth (), photoHeight / view.getHeight ()); return compressPhoto (imageFile, BitmapFactory.decodeStream (context.getContentResolver (). openInputStream (uri), null, newOptions)); } catch (eccezione FileNotFoundException) {exception.printStackTrace (); restituisce null; }} pubblico Bitmap resizePhoto (File imageFile, percorso String, vista ImageView) {Opzioni BitmapFactory.Options = new BitmapFactory.Options (); decodeFile (percorso, opzioni); int photoHeight = options.outHeight; int photoWidth = options.outWidth; options.inSampleSize = Math.min (photoWidth / view.getWidth (), photoHeight / view.getHeight ()); return compressPhoto (imageFile, BitmapFactory.decodeFile (percorso, opzioni)); } private Bitmap compressPhoto (File photoFile, Bitmap bitmap) {try {FileOutputStream fOutput = new FileOutputStream (photoFile); bitofortepress (Bitmap.CompressFormat.JPEG, 70, fOutput); fOutput.close (); } catch (eccezione IOException) {exception.printStackTrace (); } restituisce bitmap; }}

Imposta l'immagine su ImageView

Successivamente, dobbiamo implementare onActivityResult () nella nostra classe MainActivity e impostare l'immagine scelta dall'utente su ImageView.

import android.graphics.Bitmap; import android.os.Bundle; import android.widget.ImageView; import android.content.Intent; import android.widget.TextView; import android.net.Uri; classe pubblica MainActivity estende BaseActivity {private Bitmap myBitmap; privato ImageView myImageView; private TextView myTextView; @Override protetto void onCreate (Bundle savedInstanceState) {super.onCreate (savedInstanceState); setContentView (R.layout.activity_main); myTextView = findViewById (R.id.textView); myImageView = findViewById (R.id.imageView); } @Override protetto void onActivityResult (int requestCode, int resultCode, Intent data) {super.onActivityResult (requestCode, resultCode, data); if (resultCode == RESULT_OK) {switch (requestCode) {case WRITE_STORAGE: checkPermission (requestCode); rompere; case SELECT_PHOTO: Uri dataUri = data.getData (); String path = MyHelper.getPath (this, dataUri); if (path == null) {myBitmap = MyHelper.resizePhoto (foto, questo, dataUri, myImageView); } else {myBitmap = MyHelper.resizePhoto (foto, percorso, myImageView); } if (myBitmap! = null) {myTextView.setText (null); myImageView.setImageBitmap (myBitmap); } rompere; }}}}

Esegui questo progetto su un dispositivo Android fisico o AVD e fai clic sull'icona della barra delle azioni. Quando richiesto, concedi l'autorizzazione WRITE_STORAGE e scegli un'immagine dalla galleria; questa immagine dovrebbe ora essere visualizzata nell'interfaccia utente della tua app.

Ora abbiamo gettato le basi, siamo pronti per iniziare a estrarre del testo!

Insegnare a un'app a riconoscere il testo

Voglio attivare il riconoscimento del testo in risposta a un evento click, quindi dobbiamo implementare un OnClickListener:

import android.graphics.Bitmap; import android.os.Bundle; import android.widget.ImageView; import android.content.Intent; import android.widget.TextView; import android.view.View; import android.net.Uri; la classe pubblica MainActivity estende BaseActivity implementa View.OnClickListener {private Bitmap myBitmap; privato ImageView myImageView; private TextView myTextView; @Override protetto void onCreate (Bundle savedInstanceState) {super.onCreate (savedInstanceState); setContentView (R.layout.activity_main); myTextView = findViewById (R.id.textView); myImageView = findViewById (R.id.imageView); findViewById (R.id.checkText) .setOnClickListener (questo); } @Override public void onClick (Visualizza vista) {switch (view.getId ()) {case R.id.checkText: if (myBitmap! = Null) {// Implementeremo runTextRecog nel passaggio successivo // runTextRecog (); } rompere; }}

ML Kit può elaborare le immagini solo quando sono nel formato FirebaseVisionImage, quindi dobbiamo convertire la nostra immagine in un oggetto FirebaseVisionImage. È possibile creare FirebaseVisionImage da una bitmap, media.Image, ByteBuffer o una matrice di byte. Poiché stiamo lavorando con Bitmap, dobbiamo chiamare il metodo di utilità fromBitmap () della classe FirebaseVisionImage e passarlo alla nostra Bitmap.

private void runTextRecog () {FirebaseVisionImage image = FirebaseVisionImage.fromBitmap (myBitmap);

ML Kit ha diverse classi di rivelatori per ciascuna delle sue operazioni di riconoscimento delle immagini. Per il testo, è necessario utilizzare la classe FirebaseVisionTextDetector, che esegue il riconoscimento ottico dei caratteri (OCR) su un'immagine.

Creiamo un'istanza di FirebaseVisionTextDetector, utilizzando getVisionTextDetector:

FirebaseVisionTextDetector detector = FirebaseVision.getInstance (). GetVisionTextDetector ();

Successivamente, dobbiamo controllare FirebaseVisionImage per il testo, chiamando il metodo detectInImage () e passandogli l'oggetto FirebaseVisionImage. Dobbiamo anche implementare i callback onSuccess e onFailure, oltre ai listener corrispondenti, in modo che la nostra app venga avvisata ogni volta che i risultati diventano disponibili.

detector.detectInImage (image) .addOnSuccessListener (new OnSuccessListener() {@Override // To do //}}). AddOnFailureListener (new OnFailureListener () {@Override public void onFailure (eccezione eccezione @NonNull) {// Attività non riuscita con un'eccezione //}}); }

Se questa operazione fallisce, allora mostrerò un brindisi, ma se l'operazione ha esito positivo, chiamerò processExtractedText con la risposta.

A questo punto, il mio codice di rilevamento del testo è simile al seguente:

// Crea un FirebaseVisionImage // private void runTextRecog () {FirebaseVisionImage image = FirebaseVisionImage.fromBitmap (myBitmap); // Crea un'istanza di FirebaseVisionCloudTextDetector // FirebaseVisionTextDetector detector = FirebaseVision.getInstance (). GetVisionTextDetector (); // Registra un OnSuccessListener // detector.detectInImage (immagine) .addOnSuccessListener (nuovo OnSuccessListener() {@Override // Implementa il callback onSuccess // public void onSuccess (testi FirebaseVisionText) {// Chiama processExtractedText con la risposta // processExtractedText (text); }}). addOnFailureListener (new OnFailureListener () {@Override // Implementa il calback onFailure // public void onFailure (eccezione eccezione @NonNull) {Toast.makeText (MainActivity.this, "Exception", Toast.LENGTH_LONG). );}}); }

Ogni volta che la nostra app riceve una notifica onSuccess, dobbiamo analizzare i risultati.

Un oggetto FirebaseVisionText può contenere elementi, linee e blocchi, in cui ciascun blocco corrisponde in genere a un singolo paragrafo di testo. Se FirebaseVisionText restituisce 0 blocchi, visualizzeremo la stringa "no_text", ma se contiene uno o più blocchi, visualizzeremo il testo recuperato come parte del nostro TextView.

private void processExtractedText (FirebaseVisionText firebaseVisionText) {myTextView.setText (null); if (firebaseVisionText.getBlocks (). size () == 0) {myTextView.setText (R.string.no_text); ritorno; } per (blocco FirebaseVisionText.Block: firebaseVisionText.getBlocks ()) {myTextView.append (block.getText ()); }}}

Ecco il codice MainActivity completato:

import android.graphics.Bitmap; import android.os.Bundle; import android.widget.ImageView; import android.content.Intent; import android.widget.TextView; import android.widget.Toast; import android.view.View; import android.net.Uri; import android.support.annotation.NonNull; import com.google.firebase.ml.vision.common.FirebaseVisionImage; import com.google.firebase.ml.vision.text.FirebaseVisionText; import com.google.firebase.ml.vision.text.FirebaseVisionTextDetector; import com.google.firebase.ml.vision.FirebaseVision; import com.google.android.gms.tasks.OnSuccessListener; import com.google.android.gms.tasks.OnFailureListener; la classe pubblica MainActivity estende BaseActivity implementa View.OnClickListener {private Bitmap myBitmap; privato ImageView myImageView; private TextView myTextView; @Override protetto void onCreate (Bundle savedInstanceState) {super.onCreate (savedInstanceState); setContentView (R.layout.activity_main); myTextView = findViewById (R.id.textView); myImageView = findViewById (R.id.imageView); findViewById (R.id.checkText) .setOnClickListener (questo); } @Override public void onClick (Visualizza vista) {switch (view.getId ()) {case R.id.checkText: if (myBitmap! = Null) {runTextRecog (); } rompere; }} @Override protetto void onActivityResult (int requestCode, int resultCode, Intent data) {super.onActivityResult (requestCode, resultCode, data); if (resultCode == RESULT_OK) {switch (requestCode) {case WRITE_STORAGE: checkPermission (requestCode); rompere; case SELECT_PHOTO: Uri dataUri = data.getData (); String path = MyHelper.getPath (this, dataUri); if (path == null) {myBitmap = MyHelper.resizePhoto (foto, questo, dataUri, myImageView); } else {myBitmap = MyHelper.resizePhoto (foto, percorso, myImageView); } if (myBitmap! = null) {myTextView.setText (null); myImageView.setImageBitmap (myBitmap); } rompere; }}} private void runTextRecog () {FirebaseVisionImage image = FirebaseVisionImage.fromBitmap (myBitmap); FirebaseVisionTextDetector detector = FirebaseVision.getInstance (). GetVisionTextDetector (); detector.detectInImage (image) .addOnSuccessListener (new OnSuccessListener() {@Override public void onSuccess (testi FirebaseVisionText) {processExtractedText (testi); }}). addOnFailureListener (new OnFailureListener () {@Override public void onFailure (eccezione eccezione @NonNull) {Toast.makeText (MainActivity.this, "Exception", Toast.LENGTH_LONG) .show ();}}); } private void processExtractedText (FirebaseVisionText firebaseVisionText) {myTextView.setText (null); if (firebaseVisionText.getBlocks (). size () == 0) {myTextView.setText (R.string.no_text); ritorno; } per (blocco FirebaseVisionText.Block: firebaseVisionText.getBlocks ()) {myTextView.append (block.getText ()); }}}

Test del progetto

Ora è il momento di vedere il riconoscimento del testo di ML Kit in azione! Installa questo progetto su un dispositivo Android o AVD, scegli un'immagine dalla galleria, quindi tocca il pulsante "Controlla il testo". L'app dovrebbe rispondere estraendo tutto il testo dall'immagine e quindi visualizzandolo in TextView.

Tieni presente che, a seconda delle dimensioni dell'immagine e della quantità di testo che contiene, potrebbe essere necessario scorrere per visualizzare tutto il testo estratto.

Puoi anche scaricare il progetto completato da GitHub.

Avvolgendo

Ora sai come rilevare ed estrarre il testo da un'immagine, usando ML Kit.

L'API di riconoscimento del testo è solo una parte del kit ML. Questo SDK offre anche la scansione di codici a barre, il rilevamento dei volti, l'etichettatura delle immagini e il riconoscimento dei punti di riferimento, con piani per aggiungere più API per i comuni casi di utilizzo mobile, tra cui Smart Reply e un'API per contorni del viso ad alta densità.

Quale API del kit ML sei la più interessata a provare? Fateci sapere nei commenti qui sotto!

Il CE 2019 inizia ufficialmente oggi, ma il vero pettacolo è iniziato giorni prima con la prima erie di conferenze tampa CE 2019 ricche di annunci dai più grandi nomi del ettore della tecnol...

Gli martphone ono un modo importante per i governi, le aziende tecnologiche e i cattivi attori di curioare u di te mentre laci una cia di carta digitale. Ma come uccede?...

Interessante Oggi