So extrahieren Sie Text aus Bildern mit dem Machine Learning SDK von Google

Autor: John Stephens
Erstelldatum: 27 Januar 2021
Aktualisierungsdatum: 5 Juli 2024
Anonim
JCON2019 - KI in der Praxis - Machine Learning auf Prozessdaten mit Java - Mario Micudaj
Video: JCON2019 - KI in der Praxis - Machine Learning auf Prozessdaten mit Java - Mario Micudaj

Inhalt


Sie können die Texterkennungs-API auch als Grundlage für Übersetzungs-Apps oder Eingabehilfen verwenden, bei denen der Benutzer mit der Kamera auf einen Text zeigen und ihn vorlesen lassen kann.

In diesem Tutorial legen wir den Grundstein für eine Vielzahl innovativer Funktionen, indem wir eine App erstellen, mit der Sie Text aus jedem Bild in der Benutzergalerie extrahieren können. Obwohl wir in diesem Lernprogramm nicht darauf eingehen, können Sie auch Text aus der Umgebung des Benutzers in Echtzeit erfassen, indem Sie diese Anwendung mit der Kamera des Geräts verbinden.

Auf dem Gerät oder in der Cloud?

Einige der ML Kit-APIs sind nur auf dem Gerät verfügbar, einige jedoch auf dem Gerät und in der Cloud, einschließlich der Texterkennungs-API.

Die cloudbasierte Text-API kann eine größere Auswahl an Sprachen und Zeichen identifizieren und verspricht eine höhere Genauigkeit als das Gegenstück auf dem Gerät. Wie auch immer, es tut erfordern eine aktive Internetverbindung und sind nur für Projekte auf Blaze-Ebene verfügbar.


In diesem Artikel wird die Texterkennungs-API lokal ausgeführt, sodass Sie unabhängig davon, ob Sie auf Blaze aktualisiert haben oder ob Sie den kostenlosen Firebase Spark-Plan nutzen, nachverfolgen können.

Erstellen einer Texterkennungs-App mit ML Kit

Erstellen Sie eine Anwendung mit den Einstellungen Ihrer Wahl, wählen Sie jedoch bei Aufforderung die Vorlage "Leere Aktivität" aus.

Das ML Kit SDK ist Teil von Firebase. Daher müssen Sie Ihr Projekt mithilfe des SHA-1-Signaturzertifikats mit Firebase verbinden. So erhalten Sie das SHA-1 Ihres Projekts:

  • Wählen Sie die Registerkarte "Gradle" von Android Studio.
  • Doppelklicken Sie im Bedienfeld "Gradle-Projekte", um das Stammverzeichnis Ihres Projekts zu erweitern, und wählen Sie dann "Aufgaben> Android> Bericht signieren".
  • Der Bereich am unteren Rand des Android Studio-Fensters sollte aktualisiert werden, um einige Informationen zu diesem Projekt anzuzeigen - einschließlich des SHA-1-Signaturzertifikats.


So verbinden Sie Ihr Projekt mit Firebase:

  • Starten Sie in Ihrem Webbrowser die Firebase-Konsole.
  • Wählen Sie "Projekt hinzufügen".
  • Geben Sie Ihrem Projekt einen Namen. Ich verwende "ML-Test".
  • Lesen Sie die Allgemeinen Geschäftsbedingungen und wählen Sie "Ich akzeptiere ...", gefolgt von "Projekt erstellen", wenn Sie fortfahren möchten.
  • Wählen Sie "Firebase zu Ihrer Android-App hinzufügen".
  • Geben Sie den Paketnamen Ihres Projekts ein, den Sie oben in der MainActivity-Datei und im Manifest finden.
  • Geben Sie das SHA-1-Signaturzertifikat Ihres Projekts ein.
  • Klicken Sie auf "App registrieren".
  • Wählen Sie "google-services.json herunterladen". Diese Datei enthält alle erforderlichen Firebase-Metadaten für Ihr Projekt, einschließlich des API-Schlüssels.
  • Ziehen Sie in Android Studio die Datei google-services.json in das App-Verzeichnis Ihres Projekts.

  • Öffnen Sie die build.gradle-Datei auf Projektebene und fügen Sie den Klassenpfad für die Google-Dienste hinzu:

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

  • Öffnen Sie die build.gradle-Datei auf App-Ebene und fügen Sie Abhängigkeiten für Firebase Core, Firebase ML Vision und den Modellinterpreter sowie das Google-Plug-in hinzu:

Plugin anwenden: com.google.gms.google-services ... ... ... Abhängigkeiten {Implementierung fileTree (dir: libs, include:) Implementierung com.google.firebase: firebase-core: 16.0.1 Implementierung com. google.firebase: firebase-ml-vision: 16.0.0 implementierung com.google.firebase: firebase-ml-model-interpreter: 16.0.0

Zu diesem Zeitpunkt müssen Sie Ihr Projekt ausführen, damit eine Verbindung zu den Firebase-Servern hergestellt werden kann:

  • Installieren Sie Ihre App entweder auf einem physischen Android-Smartphone oder -Tablet oder auf einem virtuellen Android-Gerät (AVD).
  • Wählen Sie in der Firebase-Konsole "App ausführen, um die Installation zu überprüfen".
  • Nach einigen Augenblicken sollten Sie einen "Glückwunsch" sehen; Wählen Sie "Weiter zur Konsole".

Laden Sie die vorbereiteten Modelle für maschinelles Lernen von Google herunter

Standardmäßig lädt ML Kit Modelle nur nach Bedarf herunter. Daher lädt unsere App das OCR-Modell herunter, wenn der Benutzer zum ersten Mal versucht, Text zu extrahieren.

Dies kann sich möglicherweise negativ auf die Benutzererfahrung auswirken. Stellen Sie sich vor, Sie möchten auf eine Funktion zugreifen und erst dann feststellen, dass die App mehr Ressourcen herunterladen muss, bevor sie diese Funktion tatsächlich bereitstellen kann. Im schlimmsten Fall kann Ihre App möglicherweise nicht einmal die benötigten Ressourcen herunterladen, wenn sie benötigt wird, z. B. wenn das Gerät keine Internetverbindung hat.

Um sicherzustellen, dass dies mit unserer App nicht passiert, lade ich das erforderliche OCR-Modell zur Installationszeit herunter, was einige Änderungen am Maniest erfordert.

Während das Manifest geöffnet ist, werde ich auch die WRITE_EXTERNAL_STORAGE-Berechtigung hinzufügen, die wir später in diesem Lernprogramm verwenden werden.

// Füge die WRITE_EXTERNAL_STORAGE Berechtigung hinzu // // Füge das Folgende hinzu //

Aufbau des Layouts

Lassen Sie uns die einfachen Dinge aus dem Weg räumen und ein Layout erstellen, bestehend aus:

  • Eine ImageView. Zunächst wird ein Platzhalter angezeigt, der jedoch aktualisiert wird, sobald der Benutzer ein Bild aus seiner Galerie auswählt.
  • Ein Button, der die Textextraktion auslöst.
  • Eine Textansicht, in der der extrahierte Text angezeigt wird.
  • Eine ScrollView. Da keine Garantie besteht, dass der extrahierte Text ordnungsgemäß auf den Bildschirm passt, platziere ich die Textansicht in einer Scrollansicht.

Hier ist die fertige activity_main.xml-Datei:

Dieses Layout verweist auf einen "ic_placeholder", der gezeichnet werden kann. Erstellen wir also jetzt Folgendes:

  • Wählen Sie in der Android Studio-Symbolleiste „Datei> Neu> Bild-Asset“.
  • Öffnen Sie die Dropdown-Liste "Symboltyp" und wählen Sie "Aktionsleisten- und Registerkartensymbole".
  • Stellen Sie sicher, dass das Optionsfeld "ClipArt" ausgewählt ist.
  • Klicken Sie auf die Schaltfläche "ClipArt".
  • Wählen Sie das Bild aus, das Sie als Platzhalter verwenden möchten. Ich verwende "Zu Fotos hinzufügen".
  • OK klicken."
  • Öffnen Sie das Dropdown-Menü "Thema" und wählen Sie "HOLO_LIGHT".
  • Geben Sie im Feld "Name" "ic_placeholder" ein.
  • Klicken Sie auf "Weiter". Lesen Sie die Informationen und klicken Sie auf "Fertig stellen", wenn Sie fortfahren möchten.

Aktionsleisten-Symbole: Starten der Galerie-App

Als Nächstes erstelle ich ein Element in der Aktionsleiste, mit dem die Benutzergalerie geöffnet wird, damit sie ein Bild auswählen können.

Sie definieren Aktionsleistensymbole in einer Menüressourcendatei, die sich im Verzeichnis "res / menu" befindet. Wenn Ihr Projekt dieses Verzeichnis nicht enthält, müssen Sie es erstellen:

  • Klicken Sie bei gedrückter Ctrl-Taste auf das "res" -Verzeichnis Ihres Projekts und wählen Sie "Neu> Android-Ressourcenverzeichnis".
  • Öffnen Sie die Dropdown-Liste "Ressourcentyp" und wählen Sie "Menü".
  • Der "Verzeichnisname" sollte automatisch auf "Menü" aktualisiert werden. Ist dies nicht der Fall, müssen Sie ihn manuell umbenennen.
  • OK klicken."

Sie können jetzt die Menüressourcendatei erstellen:

  • Klicken Sie bei gedrückter Ctrl-Taste auf das Menüverzeichnis Ihres Projekts und wählen Sie "Neu> Menüressourcendatei".
  • Nennen Sie diese Datei "my_menu".
  • OK klicken."
  • Öffnen Sie die Datei "my_menu.xml" und fügen Sie Folgendes hinzu:

//Erstelle ein Element für jede Aktion //

Die Menüdatei verweist auf eine Zeichenfolge "action_gallery". Öffnen Sie daher die Datei res / values ​​/ strings.xml Ihres Projekts und erstellen Sie diese Ressource. Während ich hier bin, definiere ich auch die anderen Zeichenfolgen, die wir in diesem Projekt verwenden werden.

Galerie Diese App muss auf Dateien auf Ihrem Gerät zugreifen. Kein Text gefunden

Verwenden Sie anschließend Image Asset Studio, um das Symbol "ic_gallery" der Aktionsleiste zu erstellen:

  • Wählen Sie "Datei> Neu> Bild-Asset".
  • Stellen Sie die Dropdown-Liste "Symboltyp" auf "Aktionsleisten- und Registerkartensymbole".
  • Klicken Sie auf die Schaltfläche "ClipArt".
  • Wähle einen Drawable; Ich verwende "Bild".
  • OK klicken."
  • Um sicherzustellen, dass dieses Symbol in der Aktionsleiste gut sichtbar ist, öffnen Sie das Dropdown-Menü "Thema" und wählen Sie "HOLO_DARK".
  • Nennen Sie dieses Symbol "ic_gallery".
  • "Klicken Sie auf" Weiter ", gefolgt von" Fertig stellen ".

Verarbeiten von Berechtigungsanforderungen und Klicken auf Ereignisse

Ich führe alle Aufgaben aus, die nicht direkt mit der Texterkennungs-API in Zusammenhang stehen, und zwar das Instanziieren des Menüs, das Behandeln von Aktionsleisten-Klickereignissen und das Anfordern des Zugriffs auf den Gerätespeicher.

  • Wählen Sie "Datei> Neu> Java-Klasse" in der Symbolleiste von Android Studio.
  • Nennen Sie diese Klasse "BaseActivity".
  • OK klicken."
  • Öffnen Sie BaseActivity und fügen Sie Folgendes hinzu:

android.app.Activity importieren; import android.support.v4.app.ActivityCompat; import android.support.v7.app.ActionBar; android.support.v7.app.AlertDialog importieren; android.support.v7.app.AppCompatActivity importieren; android.os.Bundle importieren; import android.content.DialogInterface; android.content.Intent importieren; android.Manifest importieren; android.provider.MediaStore importieren; android.view.Menu importieren; import android.view.MenuItem; android.content.pm.PackageManager importieren; import android.net.Uri; android.provider.Settings importieren; import android.support.annotation.NonNull; Import android.support.annotation.Nullable; import java.io.File; public class BaseActivity erweitert 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"; öffentliches Aktenfoto; @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)); }} @Override public boolean onCreateOptionsMenu (Menü menu) {getMenuInflater (). Inflate (R.menu.my_menu, menu); return true; } @Override public boolean onOptionsItemSelected (MenuItem item) {switch (item.getItemId ()) {// Wenn "gallery_action" ausgewählt ist, dann ... // case R.id.gallery_action: //...check we have die WRITE_STORAGE-Berechtigung // checkPermission (WRITE_STORAGE); brechen; } return super.onOptionsItemSelected (item); } @Override public void onRequestPermissionsResult (int requestCode, @NonNull String-Berechtigungen, @NonNull int grantResults) {super.onRequestPermissionsResult (requestCode, Berechtigungen, grantResults); switch (requestCode) {case WRITE_STORAGE: // Wenn die Berechtigungsanforderung erteilt wurde, dann ... // if (grantResults.length> 0 && grantResults == PackageManager.PERMISSION_GRANTED) {//...call selectPicture // selectPicture ( ); // Wenn die Berechtigungsanforderung verweigert wird, dann ... //} else {//...display the "permission_request" string // requestPermission (this, requestCode, R.string.permission_request); } brechen; }} // Den Berechtigungsanforderungsdialog anzeigen // public static void requestPermission (letzte Aktivitätsaktivität, letzter int requestCode, int msg) {AlertDialog.Builder alert = new AlertDialog.Builder (activity); alert.set (msg); alert.setPositiveButton (android.R.string.ok, new DialogInterface.OnClickListener () {@Override public void onClick (DialogInterface dialogInterface, int i) {dialogInterface.dismiss (); Intent permissonIntent = new Intent (Settings.ACTION_APPLICATION_DETTAILSET) .setData (Uri.parse ("package:" + activity.getPackageName ())); activity.startActivityForResult (permissonIntent, requestCode);}}); alert.setNegativeButton (android.R.string.cancel, new DialogInterface.OnClickListener () {@Override public void onClick (DialogInterface dialogInterface, int i) {dialogInterface.dismiss ();}}); alert.setCancelable (false); alert.show (); } // Überprüfe, ob der Benutzer die WRITE_STORAGE-Berechtigung erteilt hat // public void checkPermission (int requestCode) {switch (requestCode) {case WRITE_STORAGE: int hasWriteExternalStoragePermission = ActivityCompat.checkSelfPermission (this, Manifest.permission.WRITE_EXTERNAL_STORAGE); // Wenn wir Zugriff auf externen Speicher haben ... // if (hasWriteExternalStoragePermission == PackageManager.PERMISSION_GRANTED) {//...call selectPicture, das eine Aktivität startet, bei der der Benutzer ein Bild auswählen kann // selectPicture (); // Wenn keine Berechtigung erteilt wurde, dann ... //} else {//... die Berechtigung anfordern // ActivityCompat.requestPermissions (dies ist die neue Zeichenfolge {Manifest.permission.WRITE_EXTERNAL_STORAGE}, requestCode); } brechen; }} private void selectPicture () {photo = MyHelper.createTempFile (photo); Intent intent = new Intent (Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI); // Eine Aktivität starten, in der der Benutzer ein Bild auswählen kann // startActivityForResult (intent, SELECT_PHOTO); }}

An diesem Punkt sollte sich Ihr Projekt beschweren, dass MyHelper.createTempFile nicht aufgelöst werden kann. Lassen Sie uns das jetzt umsetzen!

Ändern der Größe von Bildern mit createTempFile

Erstellen Sie eine neue Klasse "MyHelper". In dieser Klasse ändern wir die Größe des vom Benutzer ausgewählten Bildes, das von der Texterkennungs-API verarbeitet werden kann.

android.graphics.Bitmap importieren; import android.graphics.BitmapFactory; android.content.Context importieren; import android.database.Cursor; android.os.Environment importieren; import android.widget.ImageView; android.provider.MediaStore importieren; import android.net.Uri; Importieren Sie statische android.graphics.BitmapFactory.decodeFile; Importieren Sie statische android.graphics.BitmapFactory.decodeStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; öffentliche Klasse MyHelper {public static String getPath (Kontextkontext, 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 (); } der Weg zurück; } public static File createTempFile (Dateidatei) {Dateiverzeichnis = neue Datei (Environment.getExternalStorageDirectory (). getPath () + "/com.jessicathornsby.myapplication"); if (! directory.exists () ||! directory.isDirectory ()) {directory.mkdirs (); } if (file == null) {file = new Datei (Verzeichnis, "orig.jpg"); } return file; } public static Bitmap resizePhoto (Datei imageFile, Kontextkontext, Uri uri, ImageView-Ansicht) {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 (FileNotFoundException-Ausnahme) {exception.printStackTrace (); return null; }} public static Bitmap resizePhoto (Datei imageFile, Zeichenkettenpfad, ImageView-Ansicht) {BitmapFactory.Options options = new BitmapFactory.Options (); decodeFile (Pfad, Optionen); int photoHeight = options.outHeight; int photoWidth = options.outWidth; options.inSampleSize = Math.min (photoWidth / view.getWidth (), photoHeight / view.getHeight ()); return compressPhoto (imageFile, BitmapFactory.decodeFile (Pfad, Optionen)); } private statische Bitmap compressPhoto (Datei photoFile, Bitmap bitmap) {try {FileOutputStream fOutput = new FileOutputStream (photoFile); bitmap.compress (Bitmap.CompressFormat.JPEG, 70, fOutput); fOutput.close (); } catch (IOException-Ausnahme) {exception.printStackTrace (); } return bitmap; }}

Stellen Sie das Bild auf eine ImageView ein

Als Nächstes müssen wir onActivityResult () in unserer MainActivity-Klasse implementieren und das vom Benutzer ausgewählte Image auf ImageView setzen.

android.graphics.Bitmap importieren; android.os.Bundle importieren; import android.widget.ImageView; android.content.Intent importieren; import android.widget.TextView; import android.net.Uri; public class MainActivity erweitert BaseActivity {private Bitmap myBitmap; private ImageView myImageView; private TextView myTextView; @Override protected void onCreate (Bundle savedInstanceState) {super.onCreate (savedInstanceState); setContentView (R.layout.activity_main); myTextView = findViewById (R.id.textView); myImageView = findViewById (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); brechen; case SELECT_PHOTO: Uri dataUri = data.getData (); String path = MyHelper.getPath (this, dataUri); if (path == null) {myBitmap = MyHelper.resizePhoto (Foto, dies, dataUri, myImageView); } else {myBitmap = MyHelper.resizePhoto (Foto, Pfad, myImageView); } if (myBitmap! = null) {myTextView.setText (null); myImageView.setImageBitmap (myBitmap); } brechen; }}}}

Führen Sie dieses Projekt auf einem physischen Android-Gerät oder AVD aus und klicken Sie auf das Aktionsleistensymbol. Wenn Sie dazu aufgefordert werden, erteilen Sie die Berechtigung WRITE_STORAGE und wählen Sie ein Bild aus der Galerie aus. Dieses Bild sollte nun in der Benutzeroberfläche Ihrer App angezeigt werden.

Jetzt haben wir die Grundlagen geschaffen und können mit dem Extrahieren von Text beginnen!

Lehren einer App zum Erkennen von Text

Ich möchte die Texterkennung als Reaktion auf ein Klickereignis auslösen, daher müssen wir einen OnClickListener implementieren:

android.graphics.Bitmap importieren; android.os.Bundle importieren; import android.widget.ImageView; android.content.Intent importieren; import android.widget.TextView; android.view.View importieren; import android.net.Uri; public class MainActivity erweitert BaseActivity implementiert View.OnClickListener {private Bitmap myBitmap; private ImageView myImageView; private TextView myTextView; @Override protected 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 (this); } @Override public void onClick (Ansichtsansicht) {switch (view.getId ()) {case R.id.checkText: if (myBitmap! = Null) {// Wir werden runTextRecog im nächsten Schritt implementieren // runTextRecog (); } brechen; }}

ML Kit kann Bilder nur im FirebaseVisionImage-Format verarbeiten. Daher müssen wir unser Bild in ein FirebaseVisionImage-Objekt konvertieren. Sie können ein FirebaseVisionImage aus einer Bitmap, media.Image, ByteBuffer oder einem Byte-Array erstellen. Da wir mit Bitmaps arbeiten, müssen wir die Dienstprogrammmethode fromBitmap () der FirebaseVisionImage-Klasse aufrufen und sie an unsere Bitmap übergeben.

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

ML Kit hat für jede seiner Bilderkennungsoperationen unterschiedliche Detektorklassen. Für Text müssen Sie die FirebaseVisionTextDetector-Klasse verwenden, die die optische Zeichenerkennung (OCR) für ein Bild ausführt.

Wir erstellen eine Instanz von FirebaseVisionTextDetector mit getVisionTextDetector:

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

Als Nächstes müssen wir das FirebaseVisionImage auf Text überprüfen, indem wir die detectInImage () - Methode aufrufen und das FirebaseVisionImage-Objekt übergeben. Wir müssen auch onSuccess- und onFailure-Rückrufe sowie entsprechende Listener implementieren, damit unsere App benachrichtigt wird, sobald Ergebnisse verfügbar sind.

detector.detectInImage (image) .addOnSuccessListener (neuer OnSuccessListener)() {@Override // To do //}}). AddOnFailureListener (neuer OnFailureListener () {@Override public void onFailure (Ausnahme @NonNull) {// Task mit Ausnahme fehlgeschlagen //}}); }

Wenn dieser Vorgang fehlschlägt, zeige ich einen Toast an. Wenn der Vorgang jedoch erfolgreich ist, rufe ich processExtractedText mit der Antwort auf.

Zu diesem Zeitpunkt sieht mein Texterkennungscode folgendermaßen aus:

// Erstellen Sie ein FirebaseVisionImage // Private void runTextRecog () {FirebaseVisionImage image = FirebaseVisionImage.fromBitmap (myBitmap); // Eine Instanz von FirebaseVisionCloudTextDetector erstellen // FirebaseVisionTextDetector detect = FirebaseVision.getInstance (). GetVisionTextDetector (); // Einen OnSuccessListener registrieren // detect.detectInImage (image) .addOnSuccessListener (neuer OnSuccessListener)() {@Override // Implementiere den onSuccess Callback // public void onSuccess (FirebaseVisionText Texte) {// Rufe processExtractedText mit der Antwort // processExtractedText (Texte) auf; }}). addOnFailureListener (new OnFailureListener () {@Override // Implementiere den onFailure-Calback // public void onFailure (Ausnahme @NonNull Exception) {Toast.makeText (MainActivity.this, "Exception", Toast.LENGTH_LONG) .show ( );}}); }

Immer wenn unsere App eine OnSuccess-Benachrichtigung erhält, müssen wir die Ergebnisse analysieren.

Ein FirebaseVisionText-Objekt kann Elemente, Linien und Blöcke enthalten, wobei jeder Block normalerweise einem einzelnen Textabschnitt entspricht. Wenn FirebaseVisionText 0 Blöcke zurückgibt, wird die Zeichenfolge "no_text" angezeigt. Wenn sie jedoch einen oder mehrere Blöcke enthält, wird der abgerufene Text als Teil unserer Textansicht angezeigt.

private void processExtractedText (FirebaseVisionText firebaseVisionText) {myTextView.setText (null); if (firebaseVisionText.getBlocks (). size () == 0) {myTextView.setText (R.string.no_text); Rückkehr; } für (FirebaseVisionText.Block-Block: firebaseVisionText.getBlocks ()) {myTextView.append (block.getText ()); }}}

Hier ist der vollständige MainActivity-Code:

android.graphics.Bitmap importieren; android.os.Bundle importieren; import android.widget.ImageView; android.content.Intent importieren; import android.widget.TextView; android.widget.Toast importieren; android.view.View importieren; 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; importieren Sie com.google.firebase.ml.vision.FirebaseVision; import com.google.android.gms.tasks.OnSuccessListener; import com.google.android.gms.tasks.OnFailureListener; public class MainActivity erweitert BaseActivity implementiert View.OnClickListener {private Bitmap myBitmap; private ImageView myImageView; private TextView myTextView; @Override protected 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 (this); } @Override public void onClick (Ansichtsansicht) {switch (view.getId ()) {case R.id.checkText: if (myBitmap! = Null) {runTextRecog (); } brechen; }} @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); brechen; case SELECT_PHOTO: Uri dataUri = data.getData (); String path = MyHelper.getPath (this, dataUri); if (path == null) {myBitmap = MyHelper.resizePhoto (Foto, dies, dataUri, myImageView); } else {myBitmap = MyHelper.resizePhoto (Foto, Pfad, myImageView); } if (myBitmap! = null) {myTextView.setText (null); myImageView.setImageBitmap (myBitmap); } brechen; }}} private void runTextRecog () {FirebaseVisionImage image = FirebaseVisionImage.fromBitmap (myBitmap); FirebaseVisionTextDetector detect = FirebaseVision.getInstance (). GetVisionTextDetector (); detector.detectInImage (image) .addOnSuccessListener (neuer OnSuccessListener)() {@Override public void onSuccess (FirebaseVisionText-Texte) {processExtractedText (Texte); }}). addOnFailureListener (new OnFailureListener () {@Override public void onFailure (Ausnahme @NonNull Exception) {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); Rückkehr; } für (FirebaseVisionText.Block-Block: firebaseVisionText.getBlocks ()) {myTextView.append (block.getText ()); }}}

Projekt testen

Jetzt ist es Zeit, die Texterkennung von ML Kit in Aktion zu sehen! Installieren Sie dieses Projekt auf einem Android-Gerät oder einer AVD, wählen Sie ein Bild aus der Galerie aus und tippen Sie dann auf die Schaltfläche „Text überprüfen“. Die App sollte reagieren, indem sie den gesamten Text aus dem Bild extrahiert und ihn dann in einer Textansicht anzeigt.

Beachten Sie, dass Sie abhängig von der Größe Ihres Bildes und der darin enthaltenen Textmenge möglicherweise einen Bildlauf durchführen müssen, um den gesamten extrahierten Text anzuzeigen.

Sie können das fertige Projekt auch von GitHub herunterladen.

Einpacken

Mit ML Kit können Sie jetzt Text aus einem Bild erkennen und extrahieren.

Die Texterkennungs-API ist nur ein Teil des ML-Kits. Dieses SDK bietet auch Barcode-Scannen, Gesichtserkennung, Bildkennzeichnung und Erkennung von Orientierungspunkten. Es ist geplant, weitere APIs für gängige mobile Anwendungsfälle hinzuzufügen, darunter Smart Reply und eine hochdichte API für Gesichtskonturen.

Welche ML Kit API interessiert Sie am meisten? Lass es uns in den Kommentaren unten wissen!

PoitiveWunderchöne Deign und olide Verarbeitung Android One oftware-Erfahrung Beeindruckende Leitung Kabelloe LadenNegativeKeine außergewöhnliche Kameraleitung Etwa teuer...

Update (13.03.): Nokia Power Uer Dem erten Bericht folgte die Behauptung, da eine „vertrauenwürdige Quelle au China“ Einzelheiten zum lang gerüchteweien Nokia 9 PureView betätigt habe....

Unsere Empfehlung