Hur man extraherar text från bilder med Googles maskininlärnings-SDK

Författare: John Stephens
Skapelsedatum: 27 Januari 2021
Uppdatera Datum: 5 Juli 2024
Anonim
Hur man extraherar text från bilder med Googles maskininlärnings-SDK - Appar
Hur man extraherar text från bilder med Googles maskininlärnings-SDK - Appar

Innehåll


Du kan också använda API: n för textigenkänning som bas för översättningsappar, eller tillgänglighetstjänster där användaren kan rikta sin kamera mot vilken text de kämpar med och få den läst högt upp för dem.

I denna handledning lägger vi grunden för ett brett utbud av innovativa funktioner genom att skapa en app som kan extrahera text från valfri bild i användarens galleri. Även om vi inte täcker det i den här självstudien, kan du också fånga text från användarens omgivning i realtid genom att ansluta den här applikationen till enhetens kamera.

På enheten eller i molnet?

Vissa av ML Kit API: er är bara tillgängliga på enheten, men några är tillgängliga på enheten och i molnet, inklusive API för textigenkänning.

Det molnbaserade Text API kan identifiera ett bredare spektrum av språk och tecken och lovar större noggrannhet än dess motsvarighet på enheten. Men det gör kräver en aktiv Internetanslutning och är endast tillgänglig för projekt på Blaze-nivå.


I den här artikeln kommer vi att köra API för textigenkänning lokalt, så att du kan följa med oavsett om du har uppgraderat till Blaze, eller om du har en gratis Firebase Spark-plan.

Skapa en app för textigenkänning med ML Kit

Skapa en applikation med inställningarna du väljer, men välj mall "Tom aktivitet" när du uppmanas.

ML Kit SDK är en del av Firebase, så du måste ansluta ditt projekt till Firebase med hjälp av sitt SHA-1-signeringscertifikat. Så här får du projektets SHA-1:

  • Välj fliken "Gradle" i Android Studio.
  • I panelen "Gradle projects" dubbelklickar du för att utöka projektets "root" och välj sedan "Tasks> Android> Signing Report."
  • Panelen längst ner i fönstret Android Studio bör uppdateras för att visa lite information om detta projekt - inklusive dess SHA-1-signeringscertifikat.


Så här ansluter du ditt projekt till Firebase:

  • Starta Firebase Console i din webbläsare.
  • Välj "Lägg till projekt."
  • Ge ditt projekt ett namn; Jag använder "ML Test."
  • Läs villkoren och om du gärna fortsätter väljer du "Jag accepterar ..." följt av "Skapa projekt."
  • Välj "Lägg till eldstad i din Android-app."
  • Ange projektets paketnamn, som du hittar högst upp i MainActivity-filen och inuti manifestet.
  • Ange ditt projekts SHA-1-signeringscertifikat.
  • Klicka på "Registrera app."
  • Välj ”Ladda ner google-services.json.” Den här filen innehåller alla nödvändiga Firebase-metadata för ditt projekt, inklusive API-nyckeln.
  • Dra och släpp google-services.json-filen i Android Studio i projektets "app" -katalog.

  • Öppna din build.gradle-fil på projektnivå och lägg till Google Services-klassvägen:

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

  • Öppna din build.gradle-fil på appnivå och lägg till beroenden för Firebase Core, Firebase ML Vision och modelltolkaren, plus Googles serviceplugin:

applicera plugin: com.google.gms.google-services ... ... ... beroenden {implementeringsfilTree (dir: libs, inkluderar:) implementering com.google.firebase: firebase-core: 16.0.1 implementering com. google.firebase: firebase-ml-vision: 16.0.0 implementering com.google.firebase: firebase-ml-model-tolk: 16.0.0

Just nu måste du köra ditt projekt så att det kan ansluta till Firebase-servrarna:

  • Installera din app på antingen en fysisk Android-smartphone eller surfplatta eller en Android Virtual Device (AVD).
  • I Firebase Console väljer du "Kör app för att verifiera installationen."
  • Efter några ögonblick bör du se "Grattis"; välj "Fortsätt till konsolen."

Ladda ner Googles förutbildade modeller för maskininlärning

Som standard hämtar ML Kit endast modeller efter behov, så vår app kommer att ladda ner OCR-modellen när användaren försöker extrahera text för första gången.

Detta kan potentiellt ha en negativ inverkan på användarupplevelsen - tänk dig att försöka komma åt en funktion, bara för att upptäcka att appen måste ladda ner fler resurser innan den faktiskt kan leverera den här funktionen. I värsta fall kanske din app inte ens kan ladda ner de resurser den behöver, när den behöver dem, till exempel om enheten inte har någon internetanslutning.

För att se till att detta inte händer med vår app kommer jag att ladda ner den nödvändiga OCR-modellen vid installationstiden, vilket kräver några ändringar i Maniest.

Medan vi har manifestet öppet kommer jag också att lägga till WRITE_EXTERNAL_STORAGE-behörigheten, som vi kommer att använda det senare i den här handboken.

// Lägg till tillståndet WRITE_EXTERNAL_STORAGE // // Lägg till följande //

Bygga layouten

Låt oss få de enkla sakerna ur vägen och skapa en layout som består av:

  • En ImageView. Till en början visar detta en platshållare, men den kommer att uppdateras när användaren väljer en bild från sitt galleri.
  • En knapp, som utlöser textuttag.
  • En TextView, där vi visar den extraherade texten.
  • En ScrollView. Eftersom det inte finns någon garanti för att den extraherade texten kommer att passa snyggt på skärmen kommer jag att placera TextView i en ScrollView.

Här är den färdiga filen Activity_main.xml:

Den här layouten hänvisar till ett "ic_placeholder" -dragbart, så låt oss skapa det nu:

  • Välj "File> New> Image Asset" i verktygsfältet Android Studio.
  • Öppna rullgardinsmenyn "Ikontyp" och välj "Åtgärdsfält och tabbikoner."
  • Se till att alternativknappen "Clip Art" är vald.
  • Klicka på knappen "Clip Art".
  • Välj den bild du vill använda som platshållare; Jag använder "Lägg till foton."
  • Klicka på "OK."
  • Öppna rullgardinsmenyn "Tema" och välj "HOLO_LIGHT."
  • I fältet "Namn" anger du "ic_placeholder."
  • Klicka på "Nästa." Läs informationen, och om du gärna fortsätter klickar du på "Slutför."

Handlingsfältikoner: Starta Galleri-appen

Därefter kommer jag att skapa en åtgärdsfält som kommer att starta användarens galleri, redo för dem att välja en bild.

Du definierar åtgärdsfältikoner i en menyresursfil som lever i katalogen "res / menu". Om ditt projekt inte innehåller den här katalogen, måste du skapa den:

  • Kontrollera-klicka på projektets "res" -katalog och välj "New> Android Resource Directory."
  • Öppna rullgardinsmenyn "Resurstyp" och välj "meny."
  • "Katalognamn" bör uppdateras till "meny" automatiskt, men om det inte gör det måste du byta namn på det manuellt.
  • Klicka på "OK."

Du är nu redo att skapa menyresursfilen:

  • Kontrollklicka på projektets "meny" -katalog och välj "Ny> Menyresursfil."
  • Namnge den här filen "my_menu."
  • Klicka på "OK."
  • Öppna filen "my_menu.xml" och lägg till följande:

//Skapa en element för varje åtgärd //

Menyfilen refererar till en "action_gallery" -sträng, så öppna projektets res / Values ​​/ Strings.xml-fil och skapa den här resursen. Medan jag är här definierar jag också de andra strängarna som vi kommer att använda i hela detta projekt.

Galleri Denna app måste komma åt filer på din enhet. Ingen text hittades

Därefter använder du Image Asset Studio för att skapa åtgärdsfältets ikon "ic_gallery":

  • Välj "File> New> Image Asset."
  • Ställ in rullgardinsmenyn "Ikontyp" till "Åtgärdsfält och tabbikoner."
  • Klicka på knappen "Clip Art".
  • Välj en dragbar; Jag använder "image."
  • Klicka på "OK."
  • För att se till att denna ikon är tydligt synlig i åtgärdsfältet, öppna rullgardinsmenyn "Tema" och välj "HOLO_DARK."
  • Namnge denna ikon "ic_gallery."
  • "Klicka på" Nästa "följt av" Finish. "

Hantering av behörighetsbegäranden och klickhändelser

Jag kommer att utföra alla uppgifter som inte är direkt relaterade till API: n för textigenkänning i en separat ClassActivity-klass, inklusive inställning av menyn, hantering av åtgärdsfältets klickhändelser och begär åtkomst till enhetens lagring.

  • Välj "File> New> Java class" i Android Studio: s verktygsfält.
  • Namnge denna klass "BaseActivity."
  • Klicka på "OK."
  • Öppna BaseActivity och lägg till följande:

import android.app.Aktivitet; import android.support.v4.app.ActivityCompat; import android.support.v7.app.ActionBar; import android.support.v7.app.AlertDialog; importera 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; importera android.support.annotation.NonNull; import android.support.annotation.Nullable; import java.io.File; public class BaseActivity utökar 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"; offentligt filfoto; @Override skyddat tomrum 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 (Meny meny) {getMenuInflater (). Inflate (R.menu.my_menu, menu); tillbaka sant; } @Override public boolean onOptionsItemSelected (MenuItem item) {switch (item.getItemId ()) {// Om “gallery_action” är valt, så ... // case R.id.gallery_action: //...check vi har WRITE_STORAGE-behörigheten // checkPermission (WRITE_STORAGE); ha sönder; } return super.onOptionsItemSelected (artikel); } @Override public void onRequestPermissionsResult (int requestCode, @NonNull String permissions, @NonNull int grantResults) {super.onRequestPermissionsResult (requestCode, permissions, grantResults); switch (requestCode) {case WRITE_STORAGE: // Om behörighetsbegäran beviljas, ... ... if (grantResults.length> 0 && grantResults == PackageManager.PERMISSION_GRANTED) {//...call selectPicture // selectPicture ( ); // Om tillståndsbegäran avvisas, ... ...} annars {//...display strängen "Permission_request" // requestPermission (detta, requestCode, R.string.permission_request); } ha sönder; }} // Visa dialogrutan om tillståndsbegäran // public static void requestPermission (slutlig aktivitetsaktivitet, final int requestCode, int msg) {AlertDialog.Builder alert = new AlertDialog.Builder (aktivitet); 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_APPLILSATIONSETT) .setData (Uri.parse ("paket:" + Activity.getPackageName ())); Activity.startActivityForResult (permissonIntent, requestCode);}}); alert.setNegativeButton (android.R.string.cancel, ny DialogInterface.OnClickListener () {@Override public void onClick (DialogInterface dialogInterface, int i) {dialogInterface.dismiss ();}}); alert.setCancelable (false); alert.show (); } // Kontrollera om användaren har gett WRITE_STORAGE tillstånd // public void checkPermission (int requestCode) {switch (requestCode) {case WRITE_STORAGE: int hasWriteExternalStoragePermission = ActivityCompat.checkSelfPermission (detta, Manifest.permission.WRITE_EXTERNAL_STORAGE); // Om vi ​​har tillgång till extern lagring ... // if (hasWriteExternalStoragePermission == PackageManager.PERMISSION_GRANTED) {//...anrop selectPicture, som startar en aktivitet där användaren kan välja en bild // selectPicture (); // Om tillstånd inte har beviljats, ... ...} annars {//...fråga om tillstånd // ActivityCompat.requestPermissions (detta, ny String {Manifest.permission.WRITE_EXTERNAL_STORAGE}, requestCode); } ha sönder; }} privat tomrum selectPicture () {photo = MyHelper.createTempFile (foto); Intent intention = new Intent (Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI); // Starta en aktivitet där användaren kan välja en bild // startActivityForResult (avsikt, SELECT_PHOTO); }}

Just nu bör ditt projekt klaga på att det inte kan lösa MyHelper.createTempFile. Låt oss implementera detta nu!

Ändra storlek på bilder med createTempFile

Skapa en ny klass "MyHelper". I den här klassen kommer vi att ändra storleken på användarens valda bild, redo att behandlas av API: n för textigenkänning.

import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.content.Context; import android.database. Markör; import android.os. Miljö; import android.widget.ImageView; import android.provider.MediaStore; import android.net.Uri; importera statisk android.graphics.BitmapFactory.decodeFile; importera statisk android.graphics.BitmapFactory.decodeStream; import java.io.File; importera java.io.FileNotFoundException; import java.io.FileOutputStream; importera java.io.IOException; public class MyHelper {public static String getPath (Context context, Uri uri) {String path = ""; Strängprojektion = {MediaStore.Images.Media.DATA}; Markörmarkören = context.getContentResolver () .fråga (uri, projektion, null, null, null); int column_index; if (markör! = null) {column_index = cursor.getColumnIndexOrThrow (MediaStore.Images.Media.DATA); cursor.moveToFirst (); sökväg = cursor.getString (column_index); cursor.close (); } returväg; } public static File createTempFile (File file) {File directory = new File (Environment.getExternalStorageDirectory (). getPath () + "/com.jessicathornsby.myapplication"); if (! directory.exists () ||! directory.isDirectory ()) {directory.mkdirs (); } if (fil == null) {fil = ny fil (katalog, "orig.jpg"); } returfil; } offentlig statisk Bitmap resizePhoto (File imageFile, Context context, Uri uri, ImageView-vy) {BitmapFactory.Options newOptions = new BitmapFactory.Options (); prova {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 undantag) {exception.printStackTrace (); return null; }} offentlig statisk Bitmap resizePhoto (File imageFile, String path, ImageView view) {BitmapFactory.Options-alternativ = new BitmapFactory.Options (); decodeFile (sökväg, alternativ); int photoHeight = optioner.outHeight; int photoWidth = options.outWidth; options.inSampleSize = Math.min (photoWidth / view.getWidth (), photoHeight / view.getHeight ()); return compressPhoto (imageFile, BitmapFactory.decodeFile (sökväg, alternativ)); } privat statisk Bitmap compressPhoto (File photoFile, Bitmap bitmap) {prov {FileOutputStream fOutput = new FileOutputStream (photoFile); bitmap.compress (Bitmap.CompressFormat.JPEG, 70, fOutput); fOutput.close (); } catch (IOException exception) {exception.printStackTrace (); } returnera bitmapp; }}

Ställ in bilden till en ImageView

Därefter måste vi implementera onActivityResult () i vår MainActivity-klass och ställa in användarens valda bild till vår 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; public class MainActivity utökar BaseActivity {privat Bitmap myBitmap; privat ImageView myImageView; privat TextView myTextView; @Override skyddat tomrum onCreate (Bundle SavedInstanceState) {super.onCreate (SavedInstanceState); setContentView (R.layout.activity_main); myTextView = findViewById (R.id.textView); myImageView = findViewById (R.id.imageView); } @Override skyddat tomrum påActivityResult (int requestCode, int resultCode, Intent data) {super.onActivityResult (requestCode, resultCode, data); if (resultCode == RESULT_OK) {switch (requestCode) {case WRITE_STORAGE: checkPermission (requestCode); ha sönder; fall SELECT_PHOTO: Uri dataUri = data.getData (); Strängväg = MyHelper.getPath (detta, dataUri); if (sökväg == null) {myBitmap = MyHelper.resizePhoto (foto, detta, dataUri, myImageView); } annat {myBitmap = MyHelper.resizePhoto (foto, sökväg, myImageView); } if (myBitmap! = null) {myTextView.setText (null); myImageView.setImageBitmap (myBitmap); } ha sönder; }}}}

Kör detta projekt på en fysisk Android-enhet eller AVD och ge åtgärdsfältikonen ett klick. När du blir ombedd, ge WRITE_STORAGE behörighet och välj en bild från galleriet. den här bilden ska nu visas i appens användargränssnitt.

Nu har vi lagt grunden, vi är redo att börja extrahera lite text!

Lär en app att känna igen text

Jag vill utlösa textigenkänning som svar på en klickhändelse, så vi måste implementera en 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; public class MainActivity utökar BaseActivity implementerar View.OnClickListener {privat Bitmap myBitmap; privat ImageView myImageView; privat TextView myTextView; @Override skyddat tomrum 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 (detta); } @Override public void onClick (View view) {switch (view.getId ()) {case R.id.checkText: if (myBitmap! = Null) {// Vi kommer att implementera runTextRecog i nästa steg // runTextRecog (); } ha sönder; }}

ML Kit kan bara bearbeta bilder när de är i FirebaseVisionImage-formatet, så vi måste konvertera vår bild till ett FirebaseVisionImage-objekt. Du kan skapa en FirebaseVisionImage från en bitmapp, media.Image, ByteBuffer eller en byte-grupp. Eftersom vi arbetar med Bitmaps måste vi anropa verktygsmetoden fromBitmap () i klassen FirebaseVisionImage och skicka den till vår Bitmap.

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

ML Kit har olika detektorklasser för var och en av sina bildigenkänningsoperationer. För text måste vi använda klassen FirebaseVisionTextDetector, som utför optisk teckenigenkänning (OCR) på en bild.

Vi skapar en instans av FirebaseVisionTextDetector med hjälp av getVisionTextDetector:

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

Därefter måste vi kontrollera FirebaseVisionImage efter text genom att kalla metoden detectInImage () och skicka det till FirebaseVisionImage-objektet. Vi måste också implementera onSuccess och onFailure återuppringningar, plus motsvarande lyssnare så att vår app blir meddelad när resultaten blir tillgängliga.

detector.detectInImage (image) .addOnSuccessListener (ny OnSuccessListener() {@Override // Att göra //}}). AddOnFailureListener (nytt OnFailureListener () {@Override public void onFailure (@NonNull Undantag undantag) {// Uppgift misslyckades med ett undantag //}}); }

Om den här operationen misslyckas kommer jag att visa en rostat bröd, men om operationen är en framgång kommer jag att ringa processExtractedText med svaret.

Just nu ser min textdetekteringskod ut så här:

// Skapa en FirebaseVisionImage // private void runTextRecog () {FirebaseVisionImage image = FirebaseVisionImage.fromBitmap (myBitmap); // Skapa en instans av FirebaseVisionCloudTextDetector // FirebaseVisionTextDetector detector = FirebaseVision.getInstance (). GetVisionTextDetector (); // Registrera en OnSuccessListener // detector.detectInImage (bild) .addOnSuccessListener (ny OnSuccessListener() {@Override // Implementera onSuccess callback // public void onSuccess (FirebaseVisionText-texter) {// Call processExtractedText med svaret // processExtractedText (texter); }}). addOnFailureListener (ny OnFailureListener () {@Override // Implementera onFailure-kalbacken // public void onFailure (@NonNull Undantag undantag) {Toast.makeText (MainActivity.this, "Exception", Toast.LENGTH_LONG). show ( );}}); }

När vår app får ett onSuccess-meddelande måste vi analysera resultaten.

Ett FirebaseVisionText-objekt kan innehålla element, linjer och block, där varje block typiskt motsvarar ett enda stycke text. Om FirebaseVisionText returnerar 0 block kommer vi att visa strängen "no_text", men om den innehåller ett eller flera block så kommer vi att visa den hämtade texten som en del av vår TextView.

privat ogiltig processExtractedText (FirebaseVisionText firebaseVisionText) {myTextView.setText (null); if (firebaseVisionText.getBlocks (). storlek () == 0) {myTextView.setText (R.string.no_text); lämna tillbaka; } för (FirebaseVisionText.Block-block: firebaseVisionText.getBlocks ()) {myTextView.append (block.getText ()); }}}

Här är den ifyllda MainActivity-koden:

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; importera android.support.annotation.NonNull; importera 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; importera com.google.android.gms.tasks.OnSuccessListener; importera com.google.android.gms.tasks.OnFailureListener; public class MainActivity utökar BaseActivity implementerar View.OnClickListener {privat Bitmap myBitmap; privat ImageView myImageView; privat TextView myTextView; @Override skyddat tomrum 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 (detta); } @Override public void onClick (View view) {switch (view.getId ()) {case R.id.checkText: if (myBitmap! = Null) {runTextRecog (); } ha sönder; }} @Override skyddat tomrum onActivityResult (int requestCode, int resultCode, Intent data) {super.onActivityResult (requestCode, resultCode, data); if (resultCode == RESULT_OK) {switch (requestCode) {case WRITE_STORAGE: checkPermission (requestCode); ha sönder; fall SELECT_PHOTO: Uri dataUri = data.getData (); Strängväg = MyHelper.getPath (detta, dataUri); if (sökväg == null) {myBitmap = MyHelper.resizePhoto (foto, detta, dataUri, myImageView); } annat {myBitmap = MyHelper.resizePhoto (foto, sökväg, myImageView); } if (myBitmap! = null) {myTextView.setText (null); myImageView.setImageBitmap (myBitmap); } ha sönder; }}} privat tomrum runTextRecog () {FirebaseVisionImage image = FirebaseVisionImage.fromBitmap (myBitmap); FirebaseVisionTextDetector detektor = FirebaseVision.getInstance (). GetVisionTextDetector (); detector.detectInImage (image) .addOnSuccessListener (ny OnSuccessListener() {@Override public void onSuccess (FirebaseVisionTexttexter) {processExtractedText (texter); }}). addOnFailureListener (ny OnFailureListener () {@Override public void onFailure (@NonNull Exception exception) {Toast.makeText (MainActivity.this, "Undantag", Toast.LENGTH_LONG). show ();}}); } privat ogiltig processExtractedText (FirebaseVisionText firebaseVisionText) {myTextView.setText (null); if (firebaseVisionText.getBlocks (). storlek () == 0) {myTextView.setText (R.string.no_text); lämna tillbaka; } för (FirebaseVisionText.Block-block: firebaseVisionText.getBlocks ()) {myTextView.append (block.getText ()); }}}

Testa projektet

Nu är det dags att se ML Kit's textigenkänning i aktion! Installera detta projekt på en Android-enhet eller AVD, välj en bild från galleriet och ge sedan knappen "Kontrollera texten" en knapp. Appen ska svara genom att extrahera all text från bilden och sedan visa den i en TextView.

Observera att beroende på storleken på din bild och mängden text den innehåller, kan du behöva bläddra för att se all extraherad text.

Du kan också ladda ner det slutförda projektet från GitHub.

Avslutar

Nu vet du hur du kan upptäcka och extrahera text från en bild med ML Kit.

Textigenkännings API är bara en del av ML Kit. Denna SDK erbjuder också streckkodsscanning, ansiktsdetektering, bildmärkning och landmärkeigenkänning, med planer på att lägga till fler API: er för vanliga mobilanvändningsfall, inklusive Smart Answer och ett ansiktskontur-API med hög densitet.

Vilket ML Kit API är du mest intresserad att prova? Låt oss veta i kommentarerna nedan!

Nexu 7 firade in junde födeledag förra veckan. Min kollega David Imel gjorde en utmärkt minnebit om det och inkluderade ett gäng roliga aker om Android Honeycomb i proceen.Android...

Fan önkningar har äntligen beviljat: Old chool Runecape Mobile är ute nu i Google Play tore! Det kan vara amma pel, men det finn några märkbara killnader mellan OR Mobile och ...

Rekommenderat För Dig