Com extreure text de les imatges amb el SDK Machine Learning de Google

Autora: John Stephens
Data De La Creació: 27 Gener 2021
Data D’Actualització: 5 Juliol 2024
Anonim
Com extreure text de les imatges amb el SDK Machine Learning de Google - Aplicacions
Com extreure text de les imatges amb el SDK Machine Learning de Google - Aplicacions

Content


També podeu utilitzar l'API de reconeixement de textos com a base per a aplicacions de traducció o serveis d'accessibilitat on l'usuari pugui assenyalar la càmera a qualsevol text amb el que estigui lluitant i fer-la llegir en veu alta.

En aquest tutorial, establirem les bases per a una àmplia gamma de funcions innovadores, creant una aplicació que pugui extreure text de qualsevol imatge de la galeria de l’usuari. Tot i que no el tractarem en aquest tutorial, també podeu capturar text dels voltants de l’usuari en temps real, connectant aquesta aplicació a la càmera del dispositiu.

Al dispositiu o al núvol?

Algunes de les API de ML Kit només estan disponibles al dispositiu, però algunes estan disponibles al dispositiu i al núvol, inclosa l'API de reconeixement de text.

L'API de text basada en núvol pot identificar una gamma més àmplia de llenguatges i caràcters i promet una precisió més gran que la seva contrapart del dispositiu. Tot i això, sí ho fa requereixen una connexió a Internet activa i només està disponible per als projectes del nivell Blaze.


En aquest article, publicarem l'API de reconeixement de text localment, de manera que podreu seguir-la independentment de si heu actualitzat a Blaze o bé esteu al pla gratuït Firebase Spark.

Creació d'una aplicació de reconeixement de text amb ML Kit

Creeu una aplicació amb la configuració que trieu, però quan se us demani, seleccioneu la plantilla "Activitat buida".

El ML Kit SDK és part de Firebase, per la qual cosa haureu de connectar el vostre projecte a Firebase mitjançant el certificat de signatura SHA-1. Per obtenir el SHA-1 del vostre projecte:

  • Seleccioneu la pestanya "Gradle" d'Android Studio.
  • Al tauler "Projecta Gradle", feu doble clic per ampliar el "root" del vostre projecte i, a continuació, seleccioneu "Tasques> Android> Informe de signatura".
  • El tauler situat a la part inferior de la finestra d'Android Studio s'ha d'actualitzar per mostrar informació sobre aquest projecte, inclòs el certificat de signatura SHA-1.


Per connectar el projecte a Firebase:

  • Al seu navegador web, llança la consola Firebase.
  • Seleccioneu "Afegir projecte".
  • Posa un nom al teu projecte; Estic fent servir "Test ML".
  • Llegiu els termes i les condicions, i si esteu contents de continuar, seleccioneu "Accepto ..." seguit de "Crear projecte".
  • Seleccioneu "Afegeix Firebase a la vostra aplicació Android".
  • Introduïu el nom del paquet del vostre projecte, que trobareu a la part superior del fitxer MainActivity i al manifest.
  • Introduïu el certificat de signatura SHA-1 del vostre projecte.
  • Feu clic a "Registra l'aplicació".
  • Seleccioneu "Descarregueu google-services.json". Aquest fitxer conté tots els metadats de Firebase necessaris per al vostre projecte, inclosa la clau API.
  • A Android Studio, arrossegueu i deixeu anar el fitxer google-services.json al directori "aplicació" del vostre projecte.

  • Obriu el fitxer build.gradle a nivell de projecte i afegiu la ruta de serveis de Google:

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

  • Obriu el fitxer build.gradle a nivell d'aplicació i afegiu dependències per a Firebase Core, Firebase ML Vision i l'intèrpret de model, a més del complement de serveis de Google:

apply plugin: com.google.gms.google-services ... ... ... dependències {file file implementationTree (dir: libs, include:) implementació com.google.firebase: firebase-core: 16.0.1 com implementació. google.firebase: firebase-ml-vision: 16.0.0 implementació com.google.firebase: firebase-ml-model-intèrpret: 16.0.0

En aquest moment, haureu d’executar el vostre projecte perquè es pugui connectar als servidors Firebase:

  • Instal·leu l'aplicació en un smartphone o tauleta Android físic o en un dispositiu virtual Android (AVD).
  • A la consola Firebase, seleccioneu "Executar aplicació per verificar la instal·lació."
  • Al cap d’uns moments, hauríeu de veure una “felicitació”; seleccioneu "Continua a la consola".

Baixeu els models d'aprenentatge automàtic pre-format de Google

De manera predeterminada, el Kit ML només descarrega els models segons quan siguin necessaris, de manera que la nostra aplicació descarregarà el model OCR quan l’usuari intenti extreure text per primera vegada.

Això podria tenir un impacte negatiu en l'experiència de l'usuari; imagineu-vos que intenteu accedir a una funció, només per descobrir que l'aplicació ha de descarregar més recursos abans que realitzi aquesta funció. En el pitjor dels casos, és possible que la vostra aplicació ni tan sols pugui descarregar els recursos que necessita quan els necessiti, per exemple, si el dispositiu no té connexió a Internet.

Per assegurar-me que això no passi amb la nostra aplicació, descarregaré el model OCR necessari a l'hora d'instal·lació, que requereix alguns canvis al Maniest.

Mentre tinguem obert el manifest, també afegiré el permís WRITE_EXTERNAL_STORAGE, que el farem servir més endavant en aquest tutorial.

// Afegiu el permís WRITE_EXTERNAL_STORAGE // // Afegiu el següent //

Construcció del disseny

Anem a la sortida del material fàcil i creem una disposició que consta de:

  • Una ImageView. Inicialment, es mostrarà un marcador de posició, però s'actualitzarà un cop l'usuari seleccioni una imatge de la seva galeria.
  • Un botó, que desencadena l'extracció de text.
  • Una TextView, on mostrarem el text extret.
  • A ScrollView. Com que no hi ha cap garantia que el text extret s’ajusti perfectament a la pantalla, vaig a col·locar TextView dins d’un ScrollView.

Aquí teniu el fitxer finalitzat Activity_main.xml:

Aquesta disposició fa referència a un "ic_placeholder" dibuixable, per tant creem això ara:

  • Seleccioneu "Fitxer> Nou> Actiu d'imatge" a la barra d'eines d'Android Studio.
  • Obriu el menú desplegable "Tipus d'icona" i seleccioneu "Icones de la barra d'acció i de la pestanya".
  • Assegureu-vos que està seleccionat el botó de ràdio "Clip Art".
  • Feu clic al botó "Clip Art".
  • Seleccioneu la imatge que vulgueu utilitzar com a marcador de posició; Estic fent servir "Afegeix a les fotos".
  • Feu clic a "D'acord".
  • Obriu el menú desplegable "Tema" i seleccioneu "HOLO_LIGHT".
  • Al camp "Nom", introduïu "ic_placeholder".
  • Feu clic a "Següent". Llegiu la informació i, si us ve de gust continuar, feu clic a "Finalitzar".

Icones de la barra d’acció: llançament de l’aplicació Galeria

A continuació, crearé un element de barra d’acció que llançarà la galeria de l’usuari i estigui a punt per seleccionar-ne una imatge.

Definiu les icones de la barra d’acció dins d’un fitxer de recursos del menú, que es troba dins del directori “res / menu”. Si el vostre projecte no conté aquest directori, haureu de crear-lo:

  • Feu clic amb el botó de control al directori "res" del vostre projecte i seleccioneu "Nou> Directori de recursos d'Android".
  • Obriu el menú desplegable "Tipus de recurs" i seleccioneu "menú".
  • El "nom de directori" s'ha d'actualitzar automàticament a "menú", però si no és així, haureu de canviar el nom manualment.
  • Feu clic a "D'acord".

Ja estàs preparat per crear el fitxer de recursos del menú:

  • Feu clic amb el botó de control al directori "menú" del vostre projecte i seleccioneu "Nou> Fitxer de recursos de menú".
  • Poseu un nom al fitxer "my_menu".
  • Feu clic a "D'acord".
  • Obriu el fitxer "my_menu.xml" i afegiu el següent:

// Crea un element per a cada acció //

El fitxer de menú fa referència a una cadena "action_gallery", de manera que obriu el fitxer res / values ​​/ strings.xml del vostre projecte i creeu aquest recurs. Mentre estic aquí, també estic definint les altres cadenes que utilitzarem durant tot aquest projecte.

Galeria Aquesta aplicació ha d’accedir als fitxers del dispositiu. No s'ha trobat text

A continuació, utilitzeu Image Asset Studio per crear la icona “ic_gallery” de la barra d’acció:

  • Seleccioneu "Fitxer> Nou> Actiu d'imatge."
  • Configureu el menú desplegable "Tipus d'icona" a "Barra d'acció i icones de pestanya".
  • Feu clic al botó "Clip Art".
  • Trieu un dibuix; Estic fent servir "imatge"
  • Feu clic a "D'acord".
  • Per assegurar-vos que aquesta icona sigui clarament visible a la barra d’acció, obriu el menú desplegable “Tema” i seleccioneu “HOLO_DARK”.
  • Poseu un nom a aquesta icona "ic_gallery".
  • "Feu clic a" Següent ", seguit de" Finalitzar ".

Gestió de sol·licituds de permís i esdeveniments de clic

Faré totes les tasques que no estiguin directament relacionades amb l'API de reconeixement de text en una classe BaseActivity independent, inclosa la instanciació del menú, la gestió dels esdeveniments dels clics de la barra d'acció i la sol·licitud d'accés a l'emmagatzematge del dispositiu.

  • Seleccioneu "Fitxer> Nou> classe Java" a la barra d'eines d'Android Studio.
  • Poseu un nom a aquesta classe "BaseActivity".
  • Feu clic a "D'acord".
  • Obriu BaseActivity i afegiu el següent:

importa android.app.Activitat; importa android.support.v4.app.ActivityCompat; importa android.support.v7.app.ActionBar; importa android.support.v7.app.AlertDialog; importa android.support.v7.app.AppCompatActivity; importa android.os.Bundle; importa android.content.DialogInterface; importa android.content.Intent; importa Android.Manifest; importa android.provider.MediaStore; importa android.view.Menu; importa android.view.MenuItem; importa android.content.pm.PackageManager; importa android.net.Uri; importa android.provider.Settings; importa android.support.annotation.NonNull; importa android.support.annotation.Nullable; importa java.io.File; public class BaseActivity s'estén AppCompatActivity {public static final int WRITE_STORAGE = 100; public static final int SELECT_PHOTO = 102; public static final String ACTION_BAR_TITLE = "action_bar_title"; foto pública d’arxiu; @Override protected void onCreate (@Nullable Bundle savedInstanceState) {super.onCreate (savedInstanceState); ActionBar actionBar = getSupportActionBar (); if (actionBar! = null) {actionBar.setDisplayHomeAsUpEnabled (true); actionBar.setTitle (getIntent (). getStringExtra (ACTION_BAR_TITLE)); }} @Overide public boolean onCreateOptionsMenu (menú Menú) {getMenuInflater (). Inflate (R.menu.my_menu, menu); tornar veritat; } @Override public boolean onOptionsItemSelected (ítem MenuItem) {switch (item.getItemId ()) {// Si està seleccionat "gallery_action", aleshores ... // case R.id.gallery_action: //...check tenim el permís WRITE_STORAGE // checkPermission (WRITE_STORAGE); trencar; } retornar super.onOptionsItemSelected (ítem); } @Override public void onRequestPermissionsResult (int requestCode, permisos @NonNull String, @NonNull int grantResults) {super.onRequestPermissionsResult (requestCode, permisos, grantResults); switch (requestCode) {case WRITE_STORAGE: // Si es concedeix la sol·licitud de permís, llavors ... // if (grantResults.length> 0 && grantResults == PackageManager.PERMISSION_GRANTED) {//...call selectPicture // selectPicture ( ); // Si la sol·licitud de permís és denegada, llavors ... //} else {//... mostrar la cadena "permission_request" // requestPermission (això, requestCode, R.string.permission_request); } trencar; }} // Mostra el diàleg de sol·licitud de permís // public static void requestPermission (activitat final de l’activitat, final int requestCode, int msg) {AlertDialog.Builder alert = new AlertDialog.Builder (activitat); alert.set (msg); alert.setPositiveButton (android.R.string.ok, nou DialogInterface.OnClickListener () {@Override public void onClick (DialogInterface dialogInterface, int i) {dialogInterface.dismiss (); Intent permissonIntent = new IntentAP (Settings.ACTION) .setData (Uri.parse ("paquet:" + activité.getPackageName ()); activité.startActivityForResult (permissonIntent, requestCode);}}); alert.setNegativeButton (android.R.string.cancel, nou DialogInterface.OnClickListener () {@Override public void onClick (DialogInterface dialogInterface, int i) {dialogInterface.dismiss ();}}); alerta.setCancelable (fals); alerta.show (); } // Comproveu si l'usuari ha concedit el permís WRITE_STORAGE // public void checkPermission (int requestCode) {switch (requestCode) {case WRITE_STORAGE: int hasWriteExternalStoragePermission = ActivityCompat.checkSelfPermission (això, Manifest.permission.WRITE_EXTERNAL_STORAGE); // Si tenim accés a emmagatzematge extern ... // if (hasWriteExternalStoragePermission == PackageManager.PERMISSION_GRANTED) {//...call selectPicture, que llança una activitat on l'usuari pot seleccionar una imatge // selectPicture (); // Si no s'ha concedit el permís, llavors ... //} més {//... sol·licitar el permís // ActivityCompat.requestPermissions (aquesta, nova cadena {Manifest.permission.WRITE_EXTERNAL_STORAGE}, requestCode); } trencar; }} private void selectPicture () {photo = MyHelper.createTempFile (foto); Intent intention = new Intent (Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI); // Iniciar una activitat on l’usuari pugui triar una imatge // startActivityForResult (intenció, SELECT_PHOTO); }}

En aquest moment, el vostre projecte s'ha de queixar perquè no pot resoldre MyHelper.createTempFile. Implementem això ara!

Redimensionant les imatges amb createTempFile

Creeu una classe nova "MyHelper". En aquesta classe, haurem de redimensionar la imatge escollida per l'usuari a punt de ser processada per l'API de reconeixement de text.

importa android.graphics.Bitmap; importa android.graphics.BitmapFactory; importa android.content.Context; importa android.database.Cursor; importa android.os.Environment; importa android.widget.ImageView; importa android.provider.MediaStore; importa android.net.Uri; importar estàtic android.graphics.BitmapFactory.decodeFile; importa estàtic android.graphics.BitmapFactory.decodeStream; importa java.io.File; importa java.io.FileNotFoundException; importa java.io.FileOutputStream; importa java.io.IOException; public class MyHelper {public static String getPath (Context de context, Uri uri) {String path = ""; Projecció de cadena = {MediaStore.Images.Media.DATA}; Cursor cursor = context.getContentResolver (). Consulta (uri, projecció, null, null, null); int column_index; if (cursor! = null) {column_index = cursor.getColumnIndexOrThrow (MediaStore.Images.Media.DATA); cursor.moveToFirst (); path = cursor.getString (column_index); cursor.close (); } camí de retorn; } public static Arxiu createTempFile (Fitxer arxiu) {Directori de fitxers = nou Fitxer (Environment.getExternalStorageDirectory (). getPath () + "/com.jessicathornsby.myapplication"); if (! directory.exists () ||! directory.isDirectory ()) {directory.mkdirs (); } if (fitxer == null) {file = new File (directori, "orig.jpg"); } fitxer de retorn; } public static Bitmap resizePhoto (fitxer imageFile, context contextual, Uri uri, vista ImageView) {BitmapFactory.Options newOptions = new BitmapFactory.Options (); proveu {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), nul, newOptions)); } catch (excepció FileNotFoundException) {exception.printStackTrace (); retornar nul; }} public static Bitmap resizePhoto (Fitxer imageFile, ruta de la cadena, vista ImageView) {BitmapFactory.Options options = new BitmapFactory.Options (); decodeFile (ruta, opcions); int photoHeight = options.outHeight; int photoWidth = options.outWidth; options.inSampleSize = Math.min (photoWidth / view.getWidth (), photoHeight / view.getHeight ()); retornar compressPhoto (imageFile, BitmapFactory.decodeFile (ruta, opcions)); } privat static Bitmap compressPhoto (Fitxer PhotoFile, mapa de bits de mapa de bits) {try {FileOutputStream fOutput = new FileOutputStream (photoFile); bitmap.compress (Bitmap.CompressFormat.JPEG, 70, fOutput); fOutput.close (); } captura (excepció IOException) {exception.printStackTrace (); } tornar mapa de bits; }}

Definiu la imatge a ImageView

A continuació, hem d’implementar onActivityResult () a la nostra classe MainActivity i definir la imatge escollida per l’usuari a ImageView.

importa android.graphics.Bitmap; importa android.os.Bundle; importa android.widget.ImageView; importa android.content.Intent; importa android.widget.TextView; importa android.net.Uri; public class MainActivity s'estén BaseActivity {private Bitmap myBitmap; privat ImageView myImageView; TextView privat MyTextView; @Override protected void onCreate (Bundle savedInstanceState) {super.onCreate (savedInstanceState); setContentView (R.layout.activity_main); myTextView = trobarViewById (R.id.textView); myImageView = trobarViewById (R.id.imageView); } @Override protected void onActivityResult (int requestCode, int resultCode, Intent data) {super.onActivityResult (requestCode, resultCode, data); if (resultCode == RESULT_OK) {switch (requestCode) {case WRITE_STORAGE: checkPermission (requestCode); trencar; cas SELECT_PHOTO: Uri dataUri = data.getData (); Ruta de la cadena = MyHelper.getPath (això, dataUri); if (path == null) {myBitmap = MyHelper.resizePhoto (foto, aquesta, dataUri, myImageView); } else {myBitmap = MyHelper.resizePhoto (foto, ruta, myImageView); } if (myBitmap! = null) {myTextView.setText (null); myImageView.setImageBitmap (myBitmap); } trencar; }}}}

Executeu aquest projecte en un dispositiu físic Android o AVD i feu-hi un clic. Quan se us demani, concediu el permís WRITE_STORAGE i trieu una imatge de la galeria; aquesta imatge ara s'hauria de mostrar a la interfície d'usuari de l'aplicació.

Ara ja estem preparats, estem preparats per començar a extreure algun text.

Ensenyar una aplicació a reconèixer el text

Vull activar el reconeixement de text en resposta a un esdeveniment de clic, per la qual cosa hem d’implementar un OnClickListener:

importa android.graphics.Bitmap; importa android.os.Bundle; importa android.widget.ImageView; importa android.content.Intent; importa android.widget.TextView; importa android.view.View; importa android.net.Uri; public class MainActivity estén les implementacions BaseActivity View.OnClickListener {private Bitmap myBitmap; privat ImageView myImageView; TextView privat MyTextView; @Override protected void onCreate (Bundle savedInstanceState) {super.onCreate (savedInstanceState); setContentView (R.layout.activity_main); myTextView = trobarViewById (R.id.textView); myImageView = trobarViewById (R.id.imageView); findViewById (R.id.checkText) .setOnClickListener (això); } @Override public void onClick (View view) {switch (view.getId ()) {case R.id.checkText: if (myBitmap! = Null) {// Implementarem runTextRecog al següent pas // runTextRecog (); } trencar; }}

El kit ML només pot processar imatges quan estiguin en format FirebaseVisionImage, per la qual cosa hem de convertir la nostra imatge en un objecte FirebaseVisionImage. Podeu crear un FirebaseVisionImage a partir d'un mapa de bits, media.Image, ByteBuffer o una matriu de bytes. Com que treballem amb Bitmaps, hem de trucar al mètode utilitat fromBitmap () de la classe FirebaseVisionImage i passar-lo al nostre mapa de bits.

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

El kit ML disposa de diferents classes de detector per a cadascuna de les seves operacions de reconeixement d'imatges. Per a text, hem d’utilitzar la classe FirebaseVisionTextDetector, que realitza el reconeixement òptic de caràcters (OCR) en una imatge.

Creem una instància de FirebaseVisionTextDetector, utilitzant getVisionTextDetector:

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

A continuació, hem de revisar el text de FirebaseVisionImage, trucant al mètode detectInImage () i passant-lo a l'objecte FirebaseVisionImage. També hem d’implementar les devolucions onSuccess i onFailure, més els oients corresponents perquè la nostra aplicació es notifiqui sempre que els resultats estiguin disponibles.

detector.detectInImage (imatge) .addOnSuccessListener (nou OnSuccessListener() {@Override // To do //}}). AddOnFailureListener (nou OnFailureListener () {@Override public void onFailure (excepció @NonNull Excepció) {// La tasca ha fallat amb una excepció //}}); }

Si aquesta operació falla, mostraré un brindis, però si l'operació és un èxit, cridaré processExtractedText amb la resposta.

En aquest moment, el meu codi de detecció de text es sembla:

// Crea un FirebaseVisionImage // private void runTextRecog () {FirebaseVisionImage image = FirebaseVisionImage.fromBitmap (myBitmap); // Crea una instància de FirebaseVisionCloudTextDetector // FirebaseVisionTextDetector detector = FirebaseVision.getInstance (). GetVisionTextDetector (); // Registre un OnSuccessListener // detector.detectInImage (imatge) .addOnSuccessListener (nou OnSuccessListener() {@Override // Implementa la devolució de trucada onSuccess // public void onSuccess (textos FirebaseVisionText) {// Call processExtractedText amb la resposta // processExtractedText (textos); }}). addOnFailureListener (nou OnFailureListener () {@Override // Implementa la qualificació onFailure // public void onFailure (excepció de @NonNull Exception) {Toast.makeText (MainActivity.this, "Excepció", Toast.LENGTH_LONG. );}}); }

Sempre que la nostra aplicació rebi una notificació onSuccess, hem de analitzar els resultats.

Un objecte FirebaseVisionText pot contenir elements, línies i blocs, on cada bloc normalment equival a un sol paràgraf de text. Si FirebaseVisionText retorna 0 blocs, mostrarem la cadena "no_text", però si conté un o més blocs, mostrarem el text recuperat com a part de TextView.

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

Aquí teniu el codi MainActivity completat:

importa android.graphics.Bitmap; importa android.os.Bundle; importa android.widget.ImageView; importa android.content.Intent; importa android.widget.TextView; importa android.widget.Toast; importa android.view.View; importa android.net.Uri; importa android.support.annotation.NonNull; importa com.google.firebase.ml.vision.common.FirebaseVisionImage; importa com.google.firebase.ml.vision.text.FirebaseVisionText; import com.google.firebase.ml.vision.text.FirebaseVisionTextDetector; import com.google.firebase.ml.vision.FirebaseVision; importar com.google.android.gms.tasks.OnSuccessListener; importa com.google.android.gms.tasks.OnFailureListener; public class MainActivity estén les implementacions BaseActivity View.OnClickListener {private Bitmap myBitmap; privat ImageView myImageView; TextView privat MyTextView; @Override protected void onCreate (Bundle savedInstanceState) {super.onCreate (savedInstanceState); setContentView (R.layout.activity_main); myTextView = trobarViewById (R.id.textView); myImageView = trobarViewById (R.id.imageView); findViewById (R.id.checkText) .setOnClickListener (això); } @Override public void onClick (View view) {switch (view.getId ()) {case R.id.checkText: if (myBitmap! = Null) {runTextRecog (); } trencar; }} @Override protected void onActivityResult (int requestCode, int resultCode, Intent data) {super.onActivityResult (requestCode, resultCode, data); if (resultCode == RESULT_OK) {switch (requestCode) {case WRITE_STORAGE: checkPermission (requestCode); trencar; cas SELECT_PHOTO: Uri dataUri = data.getData (); Ruta de la cadena = MyHelper.getPath (això, dataUri); if (path == null) {myBitmap = MyHelper.resizePhoto (foto, aquesta, dataUri, myImageView); } else {myBitmap = MyHelper.resizePhoto (foto, ruta, myImageView); } if (myBitmap! = null) {myTextView.setText (null); myImageView.setImageBitmap (myBitmap); } trencar; }}} private void runTextRecog () {FirebaseVisionImage image = FirebaseVisionImage.fromBitmap (myBitmap); Detector FirebaseVisionTextDetector = FirebaseVision.getInstance (). GetVisionTextDetector (); detector.detectInImage (imatge) .addOnSuccessListener (nou OnSuccessListener() {@Override public void onSuccess (textos FirebaseVisionText) {processExtractedText (textos); }}). addOnFailureListener (nou OnFailureListener () {@Override public void onFailure (excepció @NonNull Excepció) {Toast.makeText (MainActivity.this, "Excepció", Toast.LENGTH_LONG). Començar ();}}); } private void processExtractedText (FirebaseVisionText firebaseVisionText) {myTextView.setText (null); if (firebaseVisionText.getBlocks (). size () == 0) {myTextView.setText (R.string.no_text); retorn; } per (FirebaseVisionText.Block bloc: firebaseVisionText.getBlocks ()) {myTextView.append (block.getText ()); }}}

Prova del projecte

Ara és hora de veure el reconeixement de text de ML Kit en acció. Instal·leu aquest projecte en un dispositiu Android o AVD, trieu una imatge de la galeria i, a continuació, doneu un toc al botó “Comproveu el text”. L'aplicació hauria de respondre extraient tot el text de la imatge i, a continuació, mostrant-lo en una TextView.

Tingueu en compte que, segons la mida de la imatge i la quantitat de text que conté, potser haureu de desplaçar-vos per veure tot el text extret.

També podeu descarregar el projecte completat de GitHub.

Embalatge

Ja sabeu com detectar i extreure text d'una imatge, utilitzant ML Kit.

L’API de reconeixement de text és només una part del kit ML. Aquest SDK també ofereix l'exploració de codis de barres, detecció de rostres, etiquetatge d'imatges i reconeixement de fites, amb plans per afegir més API per a casos d'ús mòbil mòbils, inclosa Smart Reply i una API de contorn facial d'alta densitat.

Quina API de ML Kit és el que més us interessa provar? Feu-nos-ho saber als comentaris a continuació!

OnePlu millora contantment Oxygen O amb nove funcion i uport per a coe que el membre de la comunitat demanen. La pell peronalitzada d'Android é força bona amb le actualitzacion. Mé ...

OnePlu ha lliurat divere actualitzacion per al eu buc inicial del 2018, però la companyia no ’alentirà el 2019. La marca xinea acaba d’anunciar la diponibilitat de nove actualitzacion d’Open...

Articles Fascinants