Πώς να εξαγάγετε κείμενο από εικόνες με το SDK Machine Learning της Google

Συγγραφέας: John Stephens
Ημερομηνία Δημιουργίας: 27 Ιανουάριος 2021
Ημερομηνία Ενημέρωσης: 5 Ιούλιος 2024
Anonim
Build Tomorrow’s Library by Jeffrey Licht
Βίντεο: Build Tomorrow’s Library by Jeffrey Licht

Περιεχόμενο


Θα μπορούσατε επίσης να χρησιμοποιήσετε το API αναγνώρισης κειμένου ως βάση για τις εφαρμογές μετάφρασης ή τις υπηρεσίες προσβασιμότητας, όπου ο χρήστης μπορεί να δείχνει την κάμερα σε οποιοδήποτε κείμενο αντιμετωπίζει και να το διαβάσει δυνατά σε αυτούς.

Σε αυτό το σεμινάριο, θα θέσουμε τα θεμέλια για ένα ευρύ φάσμα καινοτόμων λειτουργιών, δημιουργώντας μια εφαρμογή που μπορεί να εξάγει κείμενο από οποιαδήποτε εικόνα στη συλλογή του χρήστη. Παρόλο που δεν θα το καλύψουμε σε αυτό το σεμινάριο, θα μπορούσατε επίσης να καταγράψετε κείμενο από το περιβάλλον του χρήστη σε πραγματικό χρόνο, συνδέοντας αυτή την εφαρμογή με τη φωτογραφική μηχανή της συσκευής.

Στη συσκευή ή στο νέφος;

Ορισμένα από τα AP API Kit ML είναι διαθέσιμα μόνο σε συσκευές, αλλά μερικά είναι διαθέσιμα σε συσκευές και στο νέφος, συμπεριλαμβανομένου του API αναγνώρισης κειμένου.

Το API κειμένου που βασίζεται σε σύννεφο μπορεί να αναγνωρίσει μια ευρύτερη γκάμα γλωσσών και χαρακτήρων και υπόσχεται μεγαλύτερη ακρίβεια από ό, τι το αντίστοιχο αντίγραφο της συσκευής. Ωστόσο, αυτό κάνει απαιτούν μια ενεργή σύνδεση στο διαδίκτυο και είναι διαθέσιμα μόνο για έργα Blaze.


Σε αυτό το άρθρο, θα εκτελούμε το API αναγνώρισης κειμένου τοπικά, έτσι ώστε να μπορείτε να ακολουθήσετε, ανεξάρτητα από το αν έχετε αναβαθμίσει το Blaze ή είστε στο ελεύθερο σχέδιο Firebase Spark.

Δημιουργία μιας εφαρμογής αναγνώρισης κειμένου με το κιτ ML

Δημιουργήστε μια εφαρμογή με τις ρυθμίσεις της επιλογής σας, αλλά όταν σας ζητηθεί, επιλέξτε το πρότυπο "Empty Activity".

Το ML Kit SDK είναι μέρος της Firebase, οπότε θα χρειαστεί να συνδέσετε το έργο σας με το Firebase, χρησιμοποιώντας το πιστοποιητικό υπογραφής του SHA-1. Για να αποκτήσετε το SHA-1 του έργου σας:

  • Επιλέξτε την καρτέλα "Gradle" του Android Studio.
  • Στον πίνακα "Gradle projects", κάντε διπλό κλικ για να αναπτύξετε το "root" του έργου σας και, στη συνέχεια, επιλέξτε "Tasks> Android> Signing Report".
  • Ο πίνακας κατά μήκος του κάτω μέρους του παραθύρου του Android Studio πρέπει να ενημερωθεί για να εμφανίσει ορισμένες πληροφορίες σχετικά με αυτό το έργο - συμπεριλαμβανομένου του πιστοποιητικού υπογραφής του SHA-1.


Για να συνδέσετε το έργο σας με το Firebase:

  • Στο πρόγραμμα περιήγησης ιστού σας, ξεκινήστε την κονσόλα Firebase.
  • Επιλέξτε "Προσθήκη έργου".
  • Δώστε στο έργο σας ένα όνομα. Χρησιμοποιώ το "Test ML".
  • Διαβάστε τους όρους και προϋποθέσεις και εάν είστε ευτυχείς να προχωρήσετε, επιλέξτε "Αποδέχομαι ..." και στη συνέχεια "Δημιουργία έργου".
  • Επιλέξτε "Προσθήκη Firebase στην εφαρμογή Android".
  • Πληκτρολογήστε το όνομα του πακέτου του έργου σας, το οποίο θα βρείτε στην κορυφή του αρχείου MainActivity και στο Manifest.
  • Καταχωρίστε το πιστοποιητικό υπογραφής SHA-1 του έργου.
  • Κάντε κλικ στην επιλογή "Εγγραφή εφαρμογής".
  • Επιλέξτε "Λήψη google-services.json". Αυτό το αρχείο περιέχει όλα τα απαραίτητα μεταδεδομένα Firebase για το έργο σας, συμπεριλαμβανομένου του κλειδιού API.
  • Στο Android Studio, μεταφέρετε και αποθέστε το αρχείο google-services.json στον κατάλογο "app" του έργου σας.

  • Ανοίξτε το αρχείο build.gradle σε επίπεδο έργου και προσθέστε το classpath της υπηρεσίας Google:

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

  • Ανοίξτε το αρχείο build.grable σε επίπεδο εφαρμογής και προσθέστε εξαρτήσεις για το Firebase Core, το Firebase ML Vision και τον πρότυπο διερμηνέα, καθώς και την προσθήκη υπηρεσιών Google:

εφαρμογή plugin: com.google.gms.google-services ... ... ... εξαρτήσεις {implementation fileTree (dir: libs, include:) εφαρμογή com.google.firebase: firebase-core: 16.0.1 υλοποίηση com. google.firebase: firebase-ml-vision: 16.0.0 υλοποίηση com.google.firebase: firebase-ml-μοντέλο-διερμηνέας: 16.0.0

Σε αυτό το σημείο, θα χρειαστεί να εκτελέσετε το έργο σας έτσι ώστε να μπορεί να συνδεθεί στους διακομιστές Firebase:

  • Εγκαταστήστε την εφαρμογή σας είτε σε φυσικό Android smartphone ή tablet είτε σε εικονική συσκευή Android (AVD).
  • Στην κονσόλα Firebase, επιλέξτε "Εκτέλεση εφαρμογής για επαλήθευση της εγκατάστασης".
  • Μετά από λίγα λεπτά, θα πρέπει να δείτε ένα "Συγχαρητήρια". επιλέξτε "Συνέχεια στην κονσόλα".

Κάντε λήψη των προ-εκπαιδευμένων μοντέλων εκμάθησης μηχανών της Google

Από προεπιλογή, το ML Kit μόνο μεταφορτώνει μοντέλα όπως και πότε χρειάζονται, έτσι η εφαρμογή μας θα κατεβάσει το μοντέλο OCR όταν ο χρήστης προσπαθήσει να εξάγει κείμενο για πρώτη φορά.

Αυτό θα μπορούσε ενδεχομένως να έχει αρνητικό αντίκτυπο στην εμπειρία του χρήστη - φανταστείτε ότι προσπαθείτε να αποκτήσετε πρόσβαση σε μια λειτουργία, μόνο για να ανακαλύψετε ότι η εφαρμογή πρέπει να κάνει λήψη περισσότερων πόρων προτού να μπορέσει να παραδώσει αυτήν τη λειτουργία. Στο χειρότερο σενάριο, η εφαρμογή σας μπορεί να μην έχει τη δυνατότητα να κάνει λήψη των πόρων που χρειάζεται, όταν τις χρειάζεται, για παράδειγμα εάν η συσκευή δεν διαθέτει σύνδεση στο Internet.

Για να βεβαιωθείτε ότι αυτό δεν συμβαίνει με την εφαρμογή μας, θα κατεβάσετε το απαραίτητο μοντέλο OCR κατά το χρόνο εγκατάστασης, το οποίο απαιτεί κάποιες αλλαγές στο Maniest.

Παρόλο που έχουμε το Manifest ανοικτό, θα προσθέσω επίσης το WRITE_EXTERNAL_STORAGE δικαίωμα, το οποίο θα το χρησιμοποιήσουμε αργότερα σε αυτό το εκπαιδευτικό πρόγραμμα.

// Προσθέστε το δικαίωμα WRITE_EXTERNAL_STORAGE // // Προσθέστε τα ακόλουθα //

Δημιουργία της διάταξης

Ας πάρουμε το εύκολο πράγμα από το δρόμο, και να δημιουργήσετε μια διάταξη που αποτελείται από:

  • Ένα ImageView. Αρχικά, αυτό θα εμφανίσει ένα σύμβολο κράτησης θέσης, αλλά θα ενημερωθεί μόλις ο χρήστης επιλέξει μια εικόνα από την συλλογή του.
  • Ένα κουμπί, το οποίο ενεργοποιεί την εξαγωγή κειμένου.
  • Ένα TextView, όπου θα εμφανιστεί το εξαγόμενο κείμενο.
  • Ένα ScrollView. Δεδομένου ότι δεν υπάρχει καμία εγγύηση ότι το εξαγόμενο κείμενο θα ταιριάζει καθαρά στην οθόνη, θα τοποθετήσω το TextView μέσα σε ένα ScrollView.

Εδώ είναι το ολοκληρωμένο αρχείο activity_main.xml:

Αυτή η διάταξη αναφέρει έναν "ic_placeholder" σχετικό, οπότε ας το δημιουργήσουμε τώρα:

  • Επιλέξτε "File> New> Image Asset" από τη γραμμή εργαλείων του Android Studio.
  • Ανοίξτε το αναπτυσσόμενο μενού "Τύπος εικονιδίου" και επιλέξτε "Γραμμή δράσης και εικονίδια καρτέλας".
  • Βεβαιωθείτε ότι έχετε επιλέξει το κουμπί επιλογής "Clip Art".
  • Δώστε στο κουμπί "Clip Art" ένα κλικ.
  • Επιλέξτε την εικόνα που θέλετε να χρησιμοποιήσετε ως σύμβολο κράτησης θέσης. Χρησιμοποιώ το "Προσθήκη στις φωτογραφίες".
  • Κάντε κλικ στο κουμπί "OK".
  • Ανοίξτε το αναπτυσσόμενο μενού "Θέμα" και επιλέξτε "HOLO_LIGHT".
  • Στο πεδίο "Όνομα," πληκτρολογήστε "ic_placeholder".
  • Κάντε κλικ στο κουμπί "Επόμενο". Διαβάστε τις πληροφορίες και εάν είστε ευτυχείς να προχωρήσετε, κάντε κλικ στην επιλογή "Τέλος".

Εικονίδια γραμμής ενεργειών: Εκκίνηση της εφαρμογής "Gallery"

Στη συνέχεια, θα δημιουργήσω ένα στοιχείο γραμμής δράσης που θα ξεκινήσει τη συλλογή του χρήστη, έτοιμη για να επιλέξει μια εικόνα.

Μπορείτε να ορίσετε εικονίδια γραμμής δράσης μέσα σε ένα αρχείο πόρων μενού, το οποίο ζει μέσα στον κατάλογο "res / menu". Εάν το έργο σας δεν περιέχει αυτόν τον κατάλογο, τότε θα πρέπει να το δημιουργήσετε:

  • Ελέγξτε-κάντε κλικ στον κατάλογο "res" του έργου σας και επιλέξτε "Νέα> Κατάλογος πόρων του Android".
  • Ανοίξτε το αναπτυσσόμενο μενού "Τύπος πόρων" και επιλέξτε "μενού".
  • Το "Όνομα καταλόγου" θα πρέπει να ενημερώνεται αυτόματα στο "μενού", αλλά αν δεν το χρειάζεται τότε θα πρέπει να το μετονομάσετε με μη αυτόματο τρόπο.
  • Κάντε κλικ στο κουμπί "OK".

Τώρα είστε έτοιμοι να δημιουργήσετε το αρχείο πόρων του μενού:

  • Ελέγξτε-κάντε κλικ στον κατάλογο "μενού" του έργου σας και επιλέξτε "Νέα> αρχείο πόρων μενού".
  • Ονομάστε αυτό το αρχείο "my_menu".
  • Κάντε κλικ στο κουμπί "OK".
  • Ανοίξτε το αρχείο "my_menu.xml" και προσθέστε τα εξής:

// Δημιουργήστε ένα στοιχείο για κάθε ενέργεια //

Το αρχείο μενού αναφέρει μια συμβολοσειρά "action_gallery", ανοίξτε το αρχείο res / values ​​/ strings.xml του έργου σας και δημιουργήστε αυτόν τον πόρο. Ενώ είμαι εδώ, ορίζω επίσης τις άλλες χορδές που θα χρησιμοποιήσουμε σε όλο το έργο.

Εκθεσιακός χώρος Αυτή η εφαρμογή χρειάζεται πρόσβαση σε αρχεία στη συσκευή σας. Δεν βρέθηκε κανένα κείμενο

Στη συνέχεια, χρησιμοποιήστε το Image Asset Studio για να δημιουργήσετε το εικονίδιο "ic_gallery" της γραμμής δράσης:

  • Επιλέξτε "File> New> Image Asset."
  • Ορίστε το αναπτυσσόμενο μενού "Τύπος εικονιδίου" στην "Γραμμή δράσης και εικονίδια καρτέλας".
  • Κάντε κλικ στο κουμπί "Clip Art".
  • Επιλέξτε ένα συρόμενο. Χρησιμοποιώ "εικόνα".
  • Κάντε κλικ στο κουμπί "OK".
  • Για να βεβαιωθείτε ότι αυτό το εικονίδιο είναι ορατό στη γραμμή δράσης, ανοίξτε το αναπτυσσόμενο μενού "Θέμα" και επιλέξτε "HOLO_DARK".
  • Ονομάστε αυτό το εικονίδιο "ic_gallery".
  • "Κάντε κλικ στο κουμπί" Επόμενο ", ακολουθούμενο από" Τέλος ".

Αντιμετώπιση αιτημάτων άδειας και κλικ στα συμβάντα

Πρόκειται να εκτελέσω όλες τις εργασίες που δεν σχετίζονται άμεσα με το API αναγνώρισης κειμένου σε ξεχωριστή κλάση BaseActivity, συμπεριλαμβανομένης της εμφάνισης του μενού, του χειρισμού των συμβάντων κλικ στο κουμπί ενεργειών και της αίτησης για πρόσβαση στο χώρο αποθήκευσης της συσκευής.

  • Επιλέξτε "File> New> Java class" από τη γραμμή εργαλείων του Android Studio.
  • Ονομάστε αυτήν την κλάση "BaseActivity".
  • Κάντε κλικ στο κουμπί "OK".
  • Ανοίξτε το BaseActivity και προσθέστε τα εξής:

εισαγωγή καιroid.app.Activity; εισαγωγή καιroid.support.v4.app.ActivityCompat; εισαγωγή καιroid.support.v7.app.ActionBar; εισαγωγή καιroid.support.v7.app.AlertDialog; εισαγωγή καιroid.support.v7.app.AppCompatActivity; εισαγωγή android.os.Bundle; εισαγωγή καιroid.content.DialogInterface; εισαγωγή καιroid.content.Intent; εισαγωγή καιroid.Manifest? εισαγωγή android.provider.MediaStore; εισαγωγή καιroid.view.Menu; εισαγωγή καιroid.view.MenuItem; εισαγωγή καιroid.content.pm.PackageManager; εισαγωγή καιroid.net.Uri; εισαγωγή καιroid.provider.Settings; εισαγωγή καιroid.support.annotation.NonNull; εισαγωγή android.support.notnotation.Nullable; import java.io.File; η δημόσια κλάση BaseActivity επεκτείνει την AppCompatActivity {public static final int WRITE_STORAGE = 100; δημόσιος στατικός τελικός int SELECT_PHOTO = 102; Δημόσια στατική τελική συμβολοσειρά ACTION_BAR_TITLE = "action_bar_title"; δημόσιο αρχείο αρχείου; @Override προστατεύεται void onCreate (@Nullable Bundle savedInstanceState) {super.onCreate (savedInstanceState); ActionBar actionBar = getSupportActionBar (); αν (actionBar! = null) {actionBar.setDisplayHomeAsUpEnabled (true); actionBar.setTitle (getIntent (). getStringExtra (ACTION_BAR_TITLE)). }} @Override δημόσια boolean onCreateOptionsMenu (μενού μενού) {getMenuInflater () φουσκώσει (R.menu.my_menu, μενού); επιστροφή true; } @Override δημόσιο boolean onOptionsItemSelected (στοιχείο MenuItem) {switch (item.getItemId ()) {// Αν επιλεγεί "gallery_action", τότε ... // case R.id.gallery_action: //...check έχουμε η άδεια WRITE_STORAGE // checkPermission (WRITE_STORAGE). Διακοπή; } επιστροφή super.onOptionsItemSelected (στοιχείο); } @Override δημόσιο κενό onRequestPermissionsResult (int requestCode, @NonNull δικαιώματα String, @NonNull int grantResults) {super.onRequestPermissionsResult (requestCode, δικαιώματα, grantResults)? switch (requestCode) {περίπτωση WRITE_STORAGE: // Εάν η αίτηση άδειας παραχωρείται, τότε ... // αν (grantResults.length> 0 && grantResults == PackageManager.PERMISSION_GRANTED) {//...call selectPicture // selectPicture ( ) · // Αν το αίτημα άδειας απορρίπτεται, τότε ... //} αλλιώς {// .. εμφανίζει το string permission_request // requestPermission (this, requestCode, R.string.permission_request). } Διακοπή; }} // Εμφάνιση του διαλόγου αιτήματος άδειας // δημόσιο static void requestPermission (τελική δραστηριότητα δραστηριότητας, final int requestCode, int msg) {AlertDialog.Builder alert = new AlertDialog.Builder (δραστηριότητα); alert.set (msg); alert.setPositiveButton (android.R.string.ok, νέο DialogInterface.OnClickListener () {@Override public void onClick (διάλογοςInterface dialogInterface, int i) {dialogInterface.dismiss (); Προθέματα permissonIntent = new Intent (Settings.ACTION_APPLICATION_DETAILS_SETTINGS); permissonIntent .setData (πακέτο: "+ activity.getPackageName ())); activity.startActivityForResult (permissonIntent, requestCode)?}})? alert.setNegativeButton (android.R.string.cancel, new DialogInterface.OnClickListener () {@Override public void onClick (ΔιάλογοςInterface dialogInterface, int i) {dialogInterface.dismiss ();}}); alert.setCancelable (false); alert.show (); } // Ελέγξτε εάν ο χρήστης έχει παραχωρήσει το δικαίωμα WRITE_STORAGE // void checkPermission (int requestCode) {switch (requestCode) {περίπτωση WRITE_STORAGE: int hasWriteExternalStoragePermission = ActivityCompat.checkSelfPermission (αυτό, Manifest.permission.WRITE_EXTERNAL_STORAGE); // Εάν έχουμε πρόσβαση σε εξωτερικό αποθηκευτικό χώρο ... // if (hasWriteExternalStoragePermission == PackageManager.PERMISSION_GRANTED) {//...call selectPicture, που εκκινεί μια δραστηριότητα όπου ο χρήστης μπορεί να επιλέξει μια εικόνα // selectPicture (); // Εάν δεν έχει χορηγηθεί άδεια, τότε ... //} αλλιώς {// ... ζητήστε την άδεια // ActivityCompat.requestPermissions (αυτό, νέο String {Manifest.permission.WRITE_EXTERNAL_STORAGE}, requestCode). } Διακοπή; }} ιδιωτικό void selectPicture () {photo = MyHelper.createTempFile (φωτογραφία); Πρόθεση πρόθεσης = νέα πρόθεση (Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI); // Ξεκινήστε μια δραστηριότητα όπου ο χρήστης μπορεί να επιλέξει μια εικόνα // startActivityForResult (intent, SELECT_PHOTO). }}

Σε αυτό το σημείο, το σχέδιό σας θα πρέπει να παραπονείται ότι δεν μπορεί να επιλύσει το MyHelper.createTempFile. Ας εφαρμόσουμε αυτό τώρα!

Αλλαγή μεγέθους εικόνων με το createTempFile

Δημιουργήστε μια νέα κατηγορία "MyHelper". Σε αυτήν την τάξη, πρόκειται να αλλάξουμε το μέγεθος της εικόνας που έχει επιλέξει ο χρήστης και είναι έτοιμη για επεξεργασία από το API αναγνώρισης κειμένου.

εισαγωγή καιroid.graphics.Bitmap; εισαγωγή καιroid.graphics.BitmapFactory; εισαγωγή καιroid.content.Context. εισαγωγή καιroid.database.Cursor; Εισαγωγή καιroid.os.Environment; εισαγωγή καιroid.widget.ImageView; εισαγωγή android.provider.MediaStore; εισαγωγή καιroid.net.Uri; εισαγωγή static android.graphics.BitmapFactory.decodeFile; εισαγωγή static android.graphics.BitmapFactory.decodeStream; import java.io.File; εισαγωγή java.io.FileNotFoundException; εισαγωγή java.io.FileOutputStream; εισαγωγή java.io.IOException; δημόσια τάξη MyHelper {δημόσιο στατικό string getPath (Πλαίσιο περιβάλλοντος, Uri uri) {Διαδρομή στοιχειοσειράς = ""; Προβολή στοιχειοσειράς = {MediaStore.Images.Media.DATA}; Cursor cursor = context.getContentResolver () ερώτημα (uri, προβολή, null, null, null); int column_index; εάν (δρομέας! = null) {column_index = cursor.getColumnIndexOrThrow (MediaStore.Images.Media.DATA); cursor.moveToFirst (); διαδρομή = cursor.getString (column_index); cursor.close (); } μονοπάτι επιστροφής; } δημόσιο στατικό Αρχείο createTempFile (Αρχείο αρχείου) {Αρχείο καταλόγου = νέο αρχείο (Environment.getExternalStorageDirectory (). getPath () + "/com.jessicathornsby.myapplication"); αν (! directory.exists () ||! directory.isDirectory ()) {directory.mkdirs (); } αν (αρχείο == null) {αρχείο = νέο αρχείο (κατάλογος, "orig.jpg"); } αρχείο επιστροφής. } Δημόσια στατική Bitmap αλλαγή μεγέθουςΦωτογραφία (FileFile αρχείο, πλαίσιο περιβάλλοντος, Uri uri, προβολή ImageView) {BitmapFactory.Options newOptions = new BitmapFactory.Options (); δοκιμάστε {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 ()); επιστροφή compressPhoto (imageFile, BitmapFactory.decodeStream (context.getContentResolver (), openInputStream (uri), null, newOptions)). } catch (εξαίρεση FileNotFoundException) {exception.printStackTrace (); επιστροφή null; }} δημόσιο στατικό Bitmap resizePhoto (αρχείο imageFile, διαδρομή γραμμής, προβολή ImageView) {BitmapFactory.Options options = new BitmapFactory.Options (); decodeFile (διαδρομή, επιλογές); int photoHeight = options.outHeight; int photoWidth = options.outWidth; options.inSampleSize = Math.min (photoWidth / view.getWidth (), photoHeight / view.getHeight ()); επιστροφή compressPhoto (imageFile, BitmapFactory.decodeFile (διαδρομή, επιλογές)); } ιδιωτική στατική Bitmap compressPhoto (Αρχείο photoFile, Bitmap Bitmap) {try {FileOutputStream fOutput = νέο FileOutputStream (photoFile); bitmap.compress (Bitmap.CompressFormat.JPEG, 70, fOutput). fOutput.close (); } catch (εξαίρεση IOException) {exception.printStackTrace (); } επιστροφή bitmap? }}

Ορίστε την εικόνα σε ένα ImageView

Στη συνέχεια, πρέπει να εφαρμόσουμε την onActivityResult () στην κλάση MainActivity και να ορίσουμε την εικόνα που έχει επιλέξει ο χρήστης στο ImageView.

εισαγωγή καιroid.graphics.Bitmap; εισαγωγή android.os.Bundle; εισαγωγή καιroid.widget.ImageView; εισαγωγή καιroid.content.Intent; εισαγωγή καιroid.widget.TextView; εισαγωγή καιroid.net.Uri; δημόσια class MainActivity επεκτείνει BaseActivity {ιδιωτική bitmap myBitmap; ιδιωτική ImageView myImageView; ιδιωτική TextView myTextView; @Override προστατεύεται void onCreate (Bundle savedInstanceState) {super.onCreate (savedInstanceState); setContentView (R.layout.activity_main); myTextView = findViewById (R.id.textView); myImageView = findViewById (R.id.imageView); } @Περισσότερα προστατευμένα void onActivityResult (int requestCode, int αποτέλεσμαCode, δεδομένα σκοπού) {super.onActivityResult (requestCode, αποτέλεσμαCode, δεδομένα)? αν (resultCode == RESULT_OK) {switch (requestCode) {περίπτωση WRITE_STORAGE: checkPermission (requestCode); Διακοπή; περίπτωση SELECT_PHOTO: Uri dataUri = data.getData (); Διαδρομή στοιχειοσειράς = MyHelper.getPath (αυτό, dataUri); αν (path == null) {myBitmap = MyHelper.resizePhoto (φωτογραφία, αυτό, dataUri, myImageView); } else {myBitmap = MyHelper.resizePhoto (φωτογραφία, διαδρομή, myImageView); } αν (myBitmap! = null) {myTextView.setText (null); myImageView.setImageBitmap (myBitmap); } Διακοπή; }}}}

Εκτελέστε αυτό το έργο σε μια φυσική συσκευή Android ή AVD και δώστε στο εικονίδιο της γραμμής δράσης ένα κλικ. Όταν σας ζητηθεί, παραχωρήστε την άδεια WRITE_STORAGE και επιλέξτε μια εικόνα από τη συλλογή. αυτή η εικόνα πρέπει τώρα να εμφανίζεται στο περιβάλλον χρήστη της εφαρμογής σας.

Τώρα έχουμε βάλει τις βάσεις, είμαστε έτοιμοι να αρχίσουμε να εξάγουμε κάποιο κείμενο!

Διδασκαλία μιας εφαρμογής για αναγνώριση κειμένου

Θέλω να ενεργοποιήσω την αναγνώριση κειμένου ως απάντηση σε ένα συμβάν κλικ, οπότε πρέπει να εφαρμόσουμε ένα OnClickListener:

εισαγωγή καιroid.graphics.Bitmap; εισαγωγή android.os.Bundle; εισαγωγή καιroid.widget.ImageView; εισαγωγή καιroid.content.Intent; εισαγωγή καιroid.widget.TextView; εισαγωγή android.view.View; εισαγωγή καιroid.net.Uri; η δημόσια κλάση MainActivity επεκτείνει την εφαρμογή BaseActivity View.OnClickListener {ιδιωτική Bitmap myBitmap; ιδιωτική ImageView myImageView; ιδιωτική TextView myTextView; @Override προστατεύεται 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 (αυτό); } () () () ()) {Case R.id.checkText: if (myBitmap! = Null) {// Θα εκτελέσουμε το runTextRecog στο επόμενο βήμα // runTextRecog (). } Διακοπή; }}

Το ML Kit μπορεί να επεξεργάζεται εικόνες μόνο όταν βρίσκονται στη μορφή FirebaseVisionImage, οπότε πρέπει να μετατρέψουμε την εικόνα μας σε αντικείμενο FirebaseVisionImage. Μπορείτε να δημιουργήσετε ένα FirebaseVisionImage από Bitmap, media.Image, ByteBuffer ή από byte array. Εφόσον δουλεύουμε με τα Bitmaps, πρέπει να καλέσουμε τη μέθοδο χρησιμότητας του Bittmap () της κλάσης FirebaseVisionImage και να την περάσουμε στο bitmap μας.

ιδιωτικό άκυρο runTextRecog () {FirebaseVisionImage image = FirebaseVisionImage.fromBitmap (myBitmap);

Το ML Kit έχει διαφορετικές κατηγορίες ανιχνευτών για κάθε λειτουργία αναγνώρισης εικόνας. Για κείμενο, πρέπει να χρησιμοποιήσουμε την κλάση FirebaseVisionTextDetector, η οποία εκτελεί οπτική αναγνώριση χαρακτήρων (OCR) σε μια εικόνα.

Δημιουργούμε μια εμφάνιση του FirebaseVisionTextDetector, χρησιμοποιώντας το getVisionTextDetector:

Ανιχνευτής FirebaseVisionTextDetector = FirebaseVision.getInstance (). GetVisionTextDetector ();

Έπειτα, πρέπει να ελέγξουμε το FirebaseVisionImage για κείμενο, καλώντας τη μέθοδο detectInImage () και διαβιβάσαμε το αντικείμενο FirebaseVisionImage. Πρέπει επίσης να υλοποιήσουμε τις επανάκλησεις onSuccess και onFailure, καθώς και τους αντίστοιχους ακροατές, ώστε η εφαρμογή μας να ενημερώνεται κάθε φορά που θα είναι διαθέσιμα τα αποτελέσματα.

detector.detectInImage (εικόνα) .addOnSuccessListener (νέο OnSuccessListener() {@Override // Να κάνει //}}) addOnFailureListener (νέο OnFailureListener () {@Override public void onFailure (@NonNull Εξαίρεση εξαίρεση) {// Η εργασία απέτυχε με εξαίρεση //}})? }}

Εάν η λειτουργία αυτή αποτύχει, τότε θα εμφανίσω ένα τοστ, αλλά αν η λειτουργία είναι επιτυχής τότε θα καλέσω το processExtractedText με την απάντηση.

Σε αυτό το σημείο, ο κώδικας ανίχνευσης κειμένου μου φαίνεται ως εξής:

// Δημιουργία FirebaseVisionImage // private void runTextRecog () {FirebaseVisionImage image = FirebaseVisionImage.fromBitmap (myBitmap); // Δημιουργήστε μια εμφάνιση του FirebaseVisionCloudTextDetector // FirebaseVisionTextDetector ανιχνευτής = FirebaseVision.getInstance (). GetVisionTextDetector (); // Καταχωρήστε ένα OnSuccessListener // detector.detectInImage (image) .addOnSuccessListener (νέο OnSuccessListener() {@Override // Εφαρμογή της onSuccess callback // public void onSuccess (κείμενα FirebaseVisionText) {// Διαδικασία κλήσηςExtractedText με την απάντηση // processExtractedText (κείμενα). }}) addOnFailureListener (νέο OnFailureListener () {@Override // Εφαρμογή της επίπληξης onFailure // public void onFailure (@NonNull Εξαίρεση εξαίρεσης) {Toast.makeText (MainActivity.this, "Εξαίρεση", Toast.LENGTH_LONG) .show )?})? }}

Κάθε φορά που η εφαρμογή μας λαμβάνει ειδοποίηση σχετικά με την επιτυχία, πρέπει να αναλύσουμε τα αποτελέσματα.

Ένα αντικείμενο FirebaseVisionText μπορεί να περιέχει στοιχεία, γραμμές και μπλοκ, όπου κάθε μπλοκ τυπικά ισοδυναμεί με μια μόνο παράγραφο του κειμένου. Αν το FirebaseVisionText επιστρέψει 0 μπλοκ, τότε θα εμφανιστεί η συμβολοσειρά "no_text", αλλά αν περιέχει ένα ή περισσότερα μπλοκ τότε θα εμφανιστεί το ανακτημένο κείμενο ως μέρος του TextView.

ιδιωτική κενή διαδικασίαExtractedText (FirebaseVisionText firebaseVisionText) {myTextView.setText (null); αν (firebaseVisionText.getBlocks (). μέγεθος () == 0) {myTextView.setText (R.string.no_text); ΕΠΙΣΤΡΟΦΗ; } για (μπλοκ FirebaseVisionText.Block: firebaseVisionText.getBlocks ()) {myTextView.append (block.getText ()); }}}

Εδώ είναι ο ολοκληρωμένος κωδικός MainActivity:

εισαγωγή καιroid.graphics.Bitmap; εισαγωγή android.os.Bundle; εισαγωγή καιroid.widget.ImageView; εισαγωγή καιroid.content.Intent; εισαγωγή καιroid.widget.TextView; εισαγωγή καιroid.widget.Toast; εισαγωγή android.view.View; εισαγωγή καιroid.net.Uri; εισαγωγή καιroid.support.annotation.NonNull; import com.google.firebase.ml.vision.common.FirebaseVisionImage; εισαγωγή com.google.firebase.ml.vision.text.FirebaseVisionText; εισαγωγή com.google.firebase.ml.vision.text.FirebaseVisionTextDetector; εισαγωγή com.google.firebase.ml.vision.FirebaseVision; εισαγάγετε com.google.android.gms.tasks.OnSuccessListener. εισαγωγή com.google.android.gms.tasks.OnFailureListener. η δημόσια κλάση MainActivity επεκτείνει την εφαρμογή BaseActivity View.OnClickListener {ιδιωτική Bitmap myBitmap; ιδιωτική ImageView myImageView; ιδιωτική TextView myTextView; @Override προστατεύεται 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 (αυτό); } () () () () () () () () ()) {Rt.checkText: if (myBitmap! = Null) {runTextRecog; } Διακοπή; }} @Περιορισμένο προστατευμένο void onActivityResult (int requestCode, int resultCode, Δεδομένα σκοπού) {super.onActivityResult (requestCode, resultCode, δεδομένα)? αν (resultCode == RESULT_OK) {switch (requestCode) {περίπτωση WRITE_STORAGE: checkPermission (requestCode); Διακοπή; περίπτωση SELECT_PHOTO: Uri dataUri = data.getData (); Διαδρομή στοιχειοσειράς = MyHelper.getPath (αυτό, dataUri); αν (path == null) {myBitmap = MyHelper.resizePhoto (φωτογραφία, αυτό, dataUri, myImageView); } else {myBitmap = MyHelper.resizePhoto (φωτογραφία, διαδρομή, myImageView); } αν (myBitmap! = null) {myTextView.setText (null); myImageView.setImageBitmap (myBitmap); } Διακοπή; }}} ιδιωτικό άκυρο runTextRecog () {FirebaseVisionImage image = FirebaseVisionImage.fromBitmap (myBitmap); Ανιχνευτής FirebaseVisionTextDetector = FirebaseVision.getInstance (). GetVisionTextDetector (); detector.detectInImage (εικόνα) .addOnSuccessListener (νέο OnSuccessListener() {@Override public void onSuccess (κείμενα FirebaseVisionText) {processExtractedText (κείμενα); }}) addOnFailureListener (νέο OnFailureListener () {@Override public void onFailure (@NonNull εξαίρεση εξαίρεσης) {Toast.makeText (MainActivity.this, "Εξαίρεση", Toast.LENGTH_LONG) .show ();}})? } ιδιωτική κενή διαδικασίαExtractedText (FirebaseVisionText firebaseVisionText) {myTextView.setText (null); αν (firebaseVisionText.getBlocks (). μέγεθος () == 0) {myTextView.setText (R.string.no_text); ΕΠΙΣΤΡΟΦΗ; } για (μπλοκ FirebaseVisionText.Block: firebaseVisionText.getBlocks ()) {myTextView.append (block.getText ()); }}}

Δοκιμή του έργου

Τώρα ήρθε η ώρα να δείτε την αναγνώριση κειμένου ML Kit στην πράξη! Εγκαταστήστε αυτό το έργο σε συσκευή Android ή AVD, επιλέξτε μια εικόνα από τη συλλογή και, στη συνέχεια, κάντε κλικ στο πλήκτρο "Έλεγχος κειμένου". Η εφαρμογή θα πρέπει να ανταποκρίνεται εξάγοντας όλο το κείμενο από την εικόνα και, στη συνέχεια, εμφανίζοντας το σε ένα TextView.

Σημειώστε ότι ανάλογα με το μέγεθος της εικόνας σας και το μέγεθος του κειμένου που περιέχει, ίσως χρειαστεί να μετακινηθείτε για να δείτε όλο το εξαγόμενο κείμενο.

Μπορείτε επίσης να κατεβάσετε το ολοκληρωμένο έργο από το GitHub.

Τυλίγοντας

Τώρα γνωρίζετε πώς μπορείτε να ανιχνεύσετε και να εξαγάγετε κείμενο από μια εικόνα, χρησιμοποιώντας το ML Kit.

Το API αναγνώρισης κειμένου είναι μόνο ένα μέρος του κιτ ML. Το SDK προσφέρει επίσης σάρωση με γραμμωτό κώδικα, ανίχνευση προσώπου, σήμανση εικόνας και αναγνώριση ορόσημων, με σχέδια για την προσθήκη περισσότερων API για κοινές περιπτώσεις κινητής χρήσης, συμπεριλαμβανομένης της έξυπνης απάντησης και API περί περιγράμματος προσώπου υψηλής πυκνότητας.

Ποιο είναι το ML Kit API που σας ενδιαφέρει περισσότερο; Ενημερώστε μας στα σχόλια παρακάτω!

Ο καιρός στο Ηνωμένο Βασίλειο μπορεί να είναι απρόβλεπτος. Με τυχαία, ρεκόρ καταιγίδων που ακούγονται αμέσως μετά από αυστηρές καταιγίδες αυτό το καλοκαίρι, είναι καλό να γνωρίζουμε τι να περιμένετε ό...

Με τη μετάβαση στη νέα τεχνολογία δικτύωσης, ορισμένες γνωστές ιστορίες τρομοκρατίας επανεμφανίζονται. Ίσως να έχετε δει μερικά από τα σχόλια εδώ. "5G θα σας δώσει καρκίνο", "η τεχνολο...

Τελευταίες Δημοσιεύσεις