Hoe tekst uit afbeeldingen te extraheren met de Machine Learning SDK van Google

Schrijver: John Stephens
Datum Van Creatie: 27 Januari 2021
Updatedatum: 5 Juli- 2024
Anonim
How to extract text from images using EasyOCR Python Library (Deep Learning)
Video: How to extract text from images using EasyOCR Python Library (Deep Learning)

Inhoud


U kunt ook de API voor tekstherkenning gebruiken als basis voor vertaal-apps of toegankelijkheidsservices waarbij de gebruiker zijn camera kan richten op alle tekst waarmee hij worstelt en deze hardop voorleest.

In deze zelfstudie leggen we de basis voor een breed scala aan innovatieve functies, door een app te maken die tekst uit elke afbeelding in de galerij van de gebruiker kan extraheren. Hoewel we het in deze zelfstudie niet zullen behandelen, kunt u ook tekst in realtime vastleggen door deze applicatie te verbinden met de camera van het apparaat.

Op apparaat of in de cloud?

Sommige ML Kit API's zijn alleen beschikbaar op het apparaat, maar een paar zijn beschikbaar op het apparaat en in de cloud, inclusief de Tekstherkenning-API.

De cloud-gebaseerde Text API kan een breder scala aan talen en karakters identificeren en belooft een grotere nauwkeurigheid dan zijn tegenhanger op het apparaat. Het is echter doet vereist een actieve internetverbinding en is alleen beschikbaar voor projecten op Blaze-niveau.


In dit artikel voeren we de API voor tekstherkenning lokaal uit, dus u kunt volgen, ongeacht of u een upgrade naar Blaze hebt uitgevoerd of dat u het gratis Firebase Spark-plan gebruikt.

Een app voor tekstherkenning maken met ML Kit

Maak een applicatie met de instellingen van uw keuze, maar selecteer desgevraagd de sjabloon "Lege activiteit".

De ML Kit SDK is onderdeel van Firebase, dus u moet uw project verbinden met Firebase, met behulp van het SHA-1-ondertekeningscertificaat. Om de SHA-1 van uw project te krijgen:

  • Selecteer het tabblad "Gradle" van Android Studio.
  • Dubbelklik in het paneel "Projecten" om de "root" van uw project uit te vouwen en selecteer vervolgens "Taken> Android> Ondertekeningsrapport".
  • Het paneel onderaan het venster van Android Studio moet worden bijgewerkt om wat informatie over dit project weer te geven - inclusief het SHA-1-ondertekeningscertificaat.


Uw project verbinden met Firebase:

  • Start de Firebase-console in uw webbrowser.
  • Selecteer 'Project toevoegen'.
  • Geef uw project een naam; Ik gebruik "ML-test".
  • Lees de algemene voorwaarden en selecteer 'Ik accepteer ...' gevolgd door 'Project maken' als u wilt doorgaan.
  • Selecteer "Firebase toevoegen aan uw Android-app."
  • Voer de pakketnaam van uw project in, die u bovenaan het MainActivity-bestand en in het Manifest vindt.
  • Voer het SHA-1-handtekeningcertificaat van uw project in.
  • Klik op 'App registreren'.
  • Selecteer "Download google-services.json". Dit bestand bevat alle benodigde Firebase-metagegevens voor uw project, inclusief de API-sleutel.
  • Sleep in Android Studio het bestand google-services.json naar de map 'app' van uw project.

  • Open uw build.gradle-bestand op projectniveau en voeg het klassenpad voor Google-services toe:

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

  • Open uw build.gradle-bestand op app-niveau en voeg afhankelijkheden toe voor Firebase Core, Firebase ML Vision en de modelinterpreter, plus de Google-servicesplug-in:

plugin toepassen: com.google.gms.google-services ... ... ... afhankelijkheden {implementatie fileTree (dir: libs, include:) implementatie com.google.firebase: firebase-core: 16.0.1 implementatie com. google.firebase: firebase-ml-vision: 16.0.0 implementatie com.google.firebase: firebase-ml-model-interpreter: 16.0.0

Op dit punt moet u uw project uitvoeren zodat het verbinding kan maken met de Firebase-servers:

  • Installeer uw app op een fysieke Android-smartphone of -tablet of een Android Virtual Device (AVD).
  • Selecteer in de Firebase-console "App uitvoeren om installatie te verifiëren."
  • Na enkele ogenblikken zou u een "Gefeliciteerd" moeten zien; selecteer "Doorgaan naar de console."

Download de vooraf opgeleide modellen voor machinaal leren van Google

Standaard downloadt ML Kit alleen modellen wanneer dat nodig is, dus onze app downloadt het OCR-model wanneer de gebruiker voor het eerst tekst probeert te extraheren.

Dit kan mogelijk een negatieve invloed hebben op de gebruikerservaring - stel je voor dat je probeert toegang te krijgen tot een functie, alleen om te ontdekken dat de app meer bronnen moet downloaden voordat deze deze functie daadwerkelijk kan leveren. In het ergste geval is het mogelijk dat uw app niet eens de middelen kan downloaden die hij nodig heeft, wanneer hij deze nodig heeft, bijvoorbeeld als het apparaat geen internetverbinding heeft.

Om ervoor te zorgen dat dit niet gebeurt met onze app, ga ik het benodigde OCR-model downloaden tijdens de installatie, waarvoor enkele wijzigingen in de Maniest nodig zijn.

Hoewel we het manifest open hebben, voeg ik ook de toestemming WRITE_EXTERNAL_STORAGE toe, die we later in deze zelfstudie zullen gebruiken.

// Voeg de machtiging WRITE_EXTERNAL_STORAGE toe // // Voeg het volgende toe //

Opbouw van de lay-out

Laten we de eenvoudige dingen uit de weg ruimen en een lay-out maken die bestaat uit:

  • Een beeldweergave. In eerste instantie zal dit een tijdelijke aanduiding weergeven, maar deze wordt bijgewerkt zodra de gebruiker een afbeelding uit zijn galerij selecteert.
  • Een knop die de tekstextractie activeert.
  • Een tekstweergave, waar we de geëxtraheerde tekst weergeven.
  • Een ScrollView. Aangezien er geen garantie is dat de geëxtraheerde tekst netjes op het scherm past, ga ik de TextView in een ScrollView plaatsen.

Hier is het voltooide bestand activity_main.xml:

Deze lay-out verwijst naar een "ic_placeholder" -tekenbaar, dus laten we dit nu maken:

  • Selecteer "Bestand> Nieuw> Afbeelding-activum" op de werkbalk van Android Studio.
  • Open de vervolgkeuzelijst 'Pictogramtype' en selecteer 'Actiebalk- en tabbladpictogrammen'.
  • Zorg ervoor dat het keuzerondje "Clip Art" is geselecteerd.
  • Klik op de knop "Clip Art".
  • Selecteer de afbeelding die u als uw tijdelijke aanduiding wilt gebruiken; Ik gebruik 'Toevoegen aan foto's'.
  • Klik OK."
  • Open de vervolgkeuzelijst 'Thema' en selecteer 'HOLO_LIGHT'.
  • Voer in het veld 'Naam' ic_placeholder in.
  • Klik op "Volgende". Lees de informatie en klik op "Voltooien" als u verder wilt gaan.

Actiebalkpictogrammen: de Gallery-app starten

Vervolgens ga ik een actiebalkitem maken waarmee de galerij van de gebruiker wordt geopend, zodat deze een afbeelding kan selecteren.

U definieert actiebalkpictogrammen in een menubronbestand, dat zich in de map 'res / menu' bevindt. Als uw project deze map niet bevat, moet u deze maken:

  • Houd Control ingedrukt en klik op de map 'res' van uw project en selecteer 'Nieuw> Android Resource Directory'.
  • Open de vervolgkeuzelijst 'Type bron' en selecteer 'menu'.
  • De "Directorynaam" moet automatisch worden bijgewerkt naar "menu", maar als dit niet het geval is, moet u de naam handmatig wijzigen.
  • Klik OK."

U bent nu klaar om het menubronbestand te maken:

  • Houd Control ingedrukt en klik op de map 'menu' van uw project en selecteer 'Nieuw> Menubronbestand'.
  • Noem dit bestand "mijn_menu".
  • Klik OK."
  • Open het bestand "my_menu.xml" en voeg het volgende toe:

//Creëer een element voor elke actie //

Het menubestand verwijst naar een string "action_gallery", dus open het bestand res / values ​​/ strings.xml van uw project en maak deze resource aan. Terwijl ik hier ben, definieer ik ook de andere strings die we in dit project zullen gebruiken.

Galerij Deze app moet toegang hebben tot bestanden op uw apparaat. Geen tekst gevonden

Gebruik vervolgens de Image Asset Studio om het pictogram “ic_gallery” van de actiebalk te maken:

  • Selecteer "Bestand> Nieuw> Afbeelding-activum".
  • Stel de vervolgkeuzelijst 'Pictogramtype' in op 'Actiebalk- en tabbladpictogrammen'.
  • Klik op de knop "Clip Art".
  • Kies een tekenbaar; Ik gebruik 'afbeelding'.
  • Klik OK."
  • Om ervoor te zorgen dat dit pictogram duidelijk zichtbaar is in de actiebalk, opent u de vervolgkeuzelijst 'Thema' en selecteert u 'HOLO_DARK'.
  • Noem dit pictogram 'ic_gallery'.
  • "Klik op" Volgende ", gevolgd door" Voltooien. "

Verzoeken om toestemming en klikgebeurtenissen

Ik ga alle taken uitvoeren die niet direct gerelateerd zijn aan de API voor tekstherkenning in een afzonderlijke BaseActivity-klasse, waaronder het menu instantiëren, klikgebeurtenissen met actiebalk afhandelen en toegang vragen tot de opslag van het apparaat.

  • Selecteer 'Bestand> Nieuw> Java-klasse' op de werkbalk van Android Studio.
  • Noem deze klasse "BaseActivity."
  • Klik OK."
  • Open BaseActivity en voeg het volgende toe:

android.app.Activity importeren; android.support.v4.app.ActivityCompat importeren; android.support.v7.app.ActionBar importeren; android.support.v7.app.AlertDialog importeren; android.support.v7.app.AppCompatActivity importeren; android.os.bundle importeren; android.content.DialogInterface importeren; android.content.Intent importeren; android.Manifest importeren; android.provider.MediaStore importeren; android.view.Menu importeren; android.view.MenuItem importeren; android.content.pm.PackageManager importeren; android.net.Uri importeren; android.provider.Settings importeren; android.support.annotation.NonNull importeren; android.support.annotation.Nullable importeren; import java.io.File; public class BaseActivity breidt AppCompatActivity uit {public static final int WRITE_STORAGE = 100; openbare statische finale int SELECT_PHOTO = 102; public static final String ACTION_BAR_TITLE = "action_bar_title"; openbare bestandsfoto; @Override beschermde nietig onCreate (@Nullable Bundle saveInstanceState) {super.onCreate (opgeslagenInstanceState); ActionBar actionBar = getSupportActionBar (); if (actionBar! = null) {actionBar.setDisplayHomeAsUpEnabled (true); actionBar.setTitle (getIntent () getStringExtra (ACTION_BAR_TITLE).); }} @Override public boolean onCreateOptionsMenu (Menu-menu) {getMenuInflater (). Opblazen (R.menu.my_menu, menu); waar terugkomen; } @Override public boolean onOptionsItemSelected (MenuItem item) {switch (item.getItemId ()) {// Als "gallery cialis" is geselecteerd, dan ... // case R.id.gallery extended: //...check we hebben de WRITE_STORAGE toestemming // checkPermission (WRITE_STORAGE); breken; } retour super.onOptionsItemSelected (item); } @Override public void onRequestPermissionsResult (int requestCode, @NonNull String permissions, @NonNull int grantResults) {super.onRequestPermissionsResult (requestCode, permissions, grantResults); schakelaar (requestCode) {case WRITE_STORAGE: // Als het toestemmingsverzoek wordt ingewilligd, dan ... // if (grantResults.length> 0 && grantResults == PackageManager.PERMISSION_GRANTED) {//...call selectPicture // selectPicture ( ); // Als het toestemmingsverzoek wordt geweigerd, dan ... //} anders {//...display de tekenreeks "permit_request" // requestPermission (this, requestCode, R.string.permission_request); } pauze; }} // Toon het toestemmingsverzoekdialoog // openbare statische ongeldige aanvraagPermissie (laatste activiteit, laatste int requestCode, int msg) {AlertDialog.Builder alert = nieuwe AlertDialog.Builder (activiteit); alert.set (msg); alert.setPositiveButton (android.R.string.ok, nieuw DialogInterface.OnClickListener () {@Override public void onClick (DialogInterface dialogInterface, int i) {dialogInterface.dismiss (); Intent permissonIntent = new Intent (Settings.ACTION_APPLICATION_ETTENTS_TETENTS) .setData (Uri.parse ("package:" + activity.getPackageName ())); activity.startActivityForResult (permissonIntent, requestCode);}}); alert.setNegativeButton (android.R.string.cancel, nieuw DialogInterface.OnClickListener () {@Override public void onClick (DialogInterface dialogInterface, int i) {dialogInterface.dismiss ();}}); alert.setCancelable (false); alert.show (); } // Controleer of de gebruiker de WRITE_STORAGE toestemming heeft verleend // openbare ongeldige checkPermission (int requestCode) {switch (requestCode) {case WRITE_STORAGE: int hasWriteExternalStoragePermission = ActivityCompat.checkSelfPermission (this, Manifest.permission.WRITE_EXTERNAL_STORAGE); // Als we toegang hebben tot externe opslag ... // if (hasWriteExternalStoragePermission == PackageManager.PERMISSION_GRANTED) {//...call selectPicture, waarmee een activiteit wordt gestart waarbij de gebruiker een afbeelding kan selecteren // selectPicture (); // Als er geen toestemming is verleend, dan ... //} anders {//... vraag de toestemming aan // ActivityCompat.requestPermissions (this, new String {Manifest.permission.WRITE_EXTERNAL_STORAGE}, requestCode); } pauze; }} privé nietig selectPicture () {photo = MyHelper.createTempFile (foto); Intent intent = new Intent (Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI); // Start een activiteit waarbij de gebruiker een afbeelding kan kiezen // startActivityForResult (intentie, SELECT_PHOTO); }}

Op dit moment zou uw project moeten klagen dat het MyHelper.createTempFile niet kan oplossen. Laten we dit nu implementeren!

Formaat van afbeeldingen wijzigen met createTempFile

Maak een nieuwe klasse "MyHelper". In deze klasse gaan we het formaat van de door de gebruiker gekozen afbeelding wijzigen, klaar om te worden verwerkt door de API voor tekstherkenning.

android.graphics importeren. Bitmap; android.graphics importeren. BitmapFactory; android.content.Context importeren; android.database.Cursor importeren; android.os importeren. Milieu; android.widget.ImageView importeren; android.provider.MediaStore importeren; android.net.Uri importeren; importeer statische android.graphics.BitmapFactory.decodeFile; statische android.graphics importeren. BitmapFactory.decodeStream; import java.io.File; java.io.FileNotFoundException importeren; java.io.FileOutputStream importeren; java.io.IOException importeren; public class MyHelper {public static String getPath (context, Uri uri) {String path = ""; String projection = {MediaStore.Images.Media.DATA}; Cursor cursor = context.getContentResolver (). Query (uri, projection, 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 (); } terugweg; } openbaar statisch bestand createTempFile (bestand) {Bestandsmap = nieuw bestand (Environment.getExternalStorageDirectory (). getPath () + "/com.jessicathornsby.myapplication"); if (! directory.exists () ||! directory.isDirectory ()) {directory.mkdirs (); } if (file == null) {file = nieuw bestand (map, "orig.jpg"); } retourbestand; } openbare statische Bitmap resizePhoto (File imageFile, Context context, Uri uri, ImageView view) {BitmapFactory.Options newOptions = new BitmapFactory.Options (); probeer {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 (FileNotFoundException uitzondering) {exception.printStackTrace (); terugkeer null; }} openbare statische Bitmap resizePhoto (File imageFile, String path, ImageView view) {BitmapFactory.Options options = new BitmapFactory.Options (); decodeFile (pad, opties); int photoHeight = options.outHeight; int photoWidth = options.outWidth; options.inSampleSize = Math.min (photoWidth / view.getWidth (), photoHeight / view.getHeight ()); return compressPhoto (imageFile, BitmapFactory.decodeFile (pad, opties)); } privé statische Bitmap compressPhoto (File photoFile, Bitmap bitmap) {probeer {FileOutputStream fOutput = new FileOutputStream (photoFile); bitmap.compress (Bitmap.CompressFormat.JPEG, 70, fOutput); fOutput.close (); } catch (IOException exception) {exception.printStackTrace (); } terugkeer bitmap; }}

Stel de afbeelding in op een ImageView

Vervolgens moeten we onActivityResult () in onze MainActivity-klasse implementeren en de door de gebruiker gekozen afbeelding instellen op onze ImageView.

android.graphics importeren. Bitmap; android.os.bundle importeren; android.widget.ImageView importeren; android.content.Intent importeren; android.widget.TextView importeren; android.net.Uri importeren; openbare klasse MainActivity breidt BaseActivity uit {privé Bitmap myBitmap; privé ImageView myImageView; privé TextView myTextView; @Override beschermde nietig onCreate (bundle saveInstanceState) {super.onCreate (saveInstanceState); setContentView (R.layout.activity_main); myTextView = findViewById (R.id.textView); myImageView = findViewById (R.id.imageView); } @Override beveiligde ongeldige onActivityResult (int requestCode, int resultCode, Intent data) {super.onActivityResult (requestCode, resultCode, data); if (resultCode == RESULT_OK) {switch (requestCode) {case WRITE_STORAGE: checkPermission (requestCode); breken; case SELECT_PHOTO: Uri dataUri = data.getData (); String path = MyHelper.getPath (this, dataUri); if (path == null) {myBitmap = MyHelper.resizePhoto (foto, this, dataUri, myImageView); } else {myBitmap = MyHelper.resizePhoto (foto, pad, myImageView); } if (myBitmap! = null) {myTextView.setText (null); myImageView.setImageBitmap (myBitmap); } pauze; }}}}

Voer dit project uit op een fysiek Android-apparaat of AVD en klik op het actiebalkpictogram. Wanneer u hierom wordt gevraagd, verleent u de toestemming WRITE_STORAGE en kiest u een afbeelding uit de galerij; deze afbeelding moet nu worden weergegeven in de gebruikersinterface van uw app.

Nu hebben we de basis gelegd, we zijn klaar om wat tekst te extraheren!

Een app leren om tekst te herkennen

Ik wil tekstherkenning activeren als reactie op een klikgebeurtenis, dus we moeten een OnClickListener implementeren:

android.graphics importeren. Bitmap; android.os.bundle importeren; android.widget.ImageView importeren; android.content.Intent importeren; android.widget.TextView importeren; android.view.View importeren; android.net.Uri importeren; openbare klasse MainActivity breidt BaseActivity-werktuigen uit View.OnClickListener {private Bitmap myBitmap; privé ImageView myImageView; privé TextView myTextView; @Override beschermde nietig onCreate (bundle saveInstanceState) {super.onCreate (saveInstanceState); setContentView (R.layout.activity_main); myTextView = findViewById (R.id.textView); myImageView = findViewById (R.id.imageView); findViewById (R.id.checkText) .setOnClickListener (deze); } @Override public void onClick (View view) {switch (view.getId ()) {case R.id.checkText: if (myBitmap! = Null) {// We implementeren runTextRecog in de volgende stap // runTextRecog (); } pauze; }}

ML Kit kan alleen afbeeldingen verwerken in FirebaseVisionImage-indeling, dus we moeten onze afbeelding converteren naar een FirebaseVisionImage-object. U kunt een FirebaseVisionImage maken op basis van een bitmap, media.Image, ByteBuffer of een bytearray. Omdat we met Bitmaps werken, moeten we de methode fromBitmap () van de klasse FirebaseVisionImage aanroepen en deze onze bitmap doorgeven.

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

ML Kit heeft verschillende detectorklassen voor elk van de beeldherkenningshandelingen. Voor tekst moeten we de FirebaseVisionTextDetector-klasse gebruiken, die optische tekenherkenning (OCR) op een afbeelding uitvoert.

We maken een exemplaar van FirebaseVisionTextDetector met behulp van getVisionTextDetector:

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

Vervolgens moeten we de FirebaseVisionImage op tekst controleren door de methode detectInImage () aan te roepen en deze het FirebaseVisionImage-object te geven. We moeten ook onSuccess en onFailure callbacks implementeren, plus bijbehorende luisteraars, zodat onze app op de hoogte wordt gesteld wanneer er resultaten beschikbaar komen.

detector.detectInImage (afbeelding) .addOnSuccessListener (nieuwe OnSuccessListener() {@Override // To do //}}). AddOnFailureListener (nieuwe OnFailureListener () {@Override public void onFailure (@NonNull Uitzonderingsuitzondering) {// Taak mislukt met uitzondering //}}); }

Als deze bewerking mislukt, ga ik een toast weergeven, maar als de bewerking een succes is, noem ik processExtractedText met het antwoord.

Op dit moment ziet mijn tekstdetectiecode er als volgt uit:

// Maak een FirebaseVisionImage // private void runTextRecog () {FirebaseVisionImage image = FirebaseVisionImage.fromBitmap (myBitmap); // Maak een instantie van FirebaseVisionCloudTextDetector // FirebaseVisionTextDetector detector = FirebaseVision.getInstance (). GetVisionTextDetector (); // Registreer een OnSuccessListener // detector.detectInImage (afbeelding) .addOnSuccessListener (nieuwe OnSuccessListener() {@Override // Implementeer de onSuccess callback // public void onSuccess (FirebaseVisionText-teksten) {// OproepprocesExtractedText met het antwoord // processExtractedText (teksten); }}). addOnFailureListener (nieuwe OnFailureListener () {@Override // Implementeer de onFailure calback // public void onFailure (@NonNull Exception exception) {Toast.makeText (MainActivity.this, "Exception", Toast.LENGTH_LONG) .show ( );}}); }

Wanneer onze app een melding onSuccess ontvangt, moeten we de resultaten parseren.

Een FirebaseVisionText-object kan elementen, lijnen en blokken bevatten, waarbij elk blok doorgaans overeenkomt met een enkele alinea tekst. Als FirebaseVisionText 0 blokken retourneert, wordt de tekenreeks 'geen_tekst' weergegeven, maar als deze een of meer blokken bevat, wordt de opgehaalde tekst weergegeven als onderdeel van onze TextView.

private void processExtractedText (FirebaseVisionText firebaseVisionText) {myTextView.setText (null); if (firebaseVisionText.getBlocks (). size () == 0) {myTextView.setText (R.string.no_text); terug te keren; } voor (FirebaseVisionText.Block block: firebaseVisionText.getBlocks ()) {myTextView.append (block.getText ()); }}}

Hier is de voltooide MainActivity-code:

android.graphics importeren. Bitmap; android.os.bundle importeren; android.widget.ImageView importeren; android.content.Intent importeren; android.widget.TextView importeren; android.widget.Toast importeren; android.view.View importeren; android.net.Uri importeren; android.support.annotation.NonNull importeren; 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; openbare klasse MainActivity breidt BaseActivity-werktuigen uit View.OnClickListener {private Bitmap myBitmap; privé ImageView myImageView; privé TextView myTextView; @Override beschermde nietig onCreate (bundle saveInstanceState) {super.onCreate (saveInstanceState); setContentView (R.layout.activity_main); myTextView = findViewById (R.id.textView); myImageView = findViewById (R.id.imageView); findViewById (R.id.checkText) .setOnClickListener (deze); } @Override public void onClick (View view) {switch (view.getId ()) {case R.id.checkText: if (myBitmap! = Null) {runTextRecog (); } pauze; }} @Override beschermde ongeldige onActivityResult (int requestCode, int resultCode, Intent data) {super.onActivityResult (requestCode, resultCode, data); if (resultCode == RESULT_OK) {switch (requestCode) {case WRITE_STORAGE: checkPermission (requestCode); breken; case SELECT_PHOTO: Uri dataUri = data.getData (); String path = MyHelper.getPath (this, dataUri); if (path == null) {myBitmap = MyHelper.resizePhoto (foto, this, dataUri, myImageView); } else {myBitmap = MyHelper.resizePhoto (foto, pad, myImageView); } if (myBitmap! = null) {myTextView.setText (null); myImageView.setImageBitmap (myBitmap); } pauze; }}} privé nietig runTextRecog () {FirebaseVisionImage image = FirebaseVisionImage.fromBitmap (myBitmap); FirebaseVisionTextDetector detector = FirebaseVision.getInstance (). GetVisionTextDetector (); detector.detectInImage (afbeelding) .addOnSuccessListener (nieuwe OnSuccessListener() {@Override public void onSuccess (FirebaseVisionText-teksten) {processExtractedText (teksten); }}). addOnFailureListener (nieuwe OnFailureListener () {@Override public void onFailure (uitzondering @NonNull uitzondering) {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); terug te keren; } voor (FirebaseVisionText.Block block: firebaseVisionText.getBlocks ()) {myTextView.append (block.getText ()); }}}

Het project testen

Nu is het tijd om de tekstherkenning van ML Kit in actie te zien! Installeer dit project op een Android-apparaat of AVD, kies een afbeelding uit de galerij en tik vervolgens op de knop "Controleer de tekst". De app moet reageren door alle tekst uit de afbeelding te extraheren en deze vervolgens weer te geven in een TextView.

Merk op dat afhankelijk van de grootte van uw afbeelding en de hoeveelheid tekst die het bevat, u mogelijk moet scrollen om alle uitgepakte tekst te zien.

Je kunt het voltooide project ook downloaden van GitHub.

Afsluiten

U weet nu hoe u tekst uit een afbeelding kunt detecteren en extraheren met behulp van ML Kit.

De API voor tekstherkenning is slechts een onderdeel van de ML Kit. Deze SDK biedt ook barcodescanning, gezichtsdetectie, beeldetikettering en herkenning van herkenningspunten, met plannen om meer API's toe te voegen voor veelvoorkomende gevallen van mobiel gebruik, waaronder Smart Reply en een gezichtscontour-API met hoge dichtheid.

Welke ML Kit API ben je het meest geïnteresseerd om te proberen? Laat het ons weten in de reacties hieronder!

Met verchillende Google-app die de afgelopen weken in de donkere modu zijn behandeld, i het eindelijk de beurt aan Gmail om de oogvriendelijke modu te krijgen. Echter, Android politie vond de donkere ...

Update, 24 eptember 2019 (11:32 AM ET): In het ondertaande artikel bechrijven we hoe 9to5Google een implementatie van Gmail in de donkere modu gezien. Veel menen hebben echter nog teed geen donkere mo...

Populair Op Het Terrein