כיצד לחלץ טקסט מתמונות באמצעות SDK של למידה מכונה של גוגל

מְחַבֵּר: John Stephens
תאריך הבריאה: 27 יָנוּאָר 2021
תאריך עדכון: 5 יולי 2024
Anonim
כיצד לחלץ טקסט מתמונות באמצעות SDK של למידה מכונה של גוגל - אפליקציות
כיצד לחלץ טקסט מתמונות באמצעות SDK של למידה מכונה של גוגל - אפליקציות

תוֹכֶן


תוכל גם להשתמש בממשק ה- API לזיהוי טקסט כבסיס ליישומי תרגום, או לשירותי נגישות שבהם המשתמש יכול לכוון את המצלמה שלו על כל טקסט שהוא מתמודד איתו, ולגרום לו לקרוא אותו בקול רם.

במדריך זה נניח את הבסיס למגוון רחב של תכונות חדשניות, על ידי יצירת אפליקציה שיכולה לחלץ טקסט מכל תמונה בגלריית המשתמש. למרות שלא נסקור אותו במדריך זה, תוכל גם ללכוד טקסט מסביבתו של המשתמש בזמן אמת, על ידי חיבור יישום זה למצלמת המכשיר.

במכשיר או בענן?

חלק מממשקי ה- API של ML Kit זמינים רק במכשיר, אך מעטים זמינים במכשיר ובענן, כולל API לזיהוי טקסט.

ממשק ה- API המבוסס על ענן צמתים יכול לזהות מגוון רחב יותר של שפות ותווים, ומבטיח דיוק רב יותר מאשר מקבילתו במכשיר. עם זאת, זה עושה דורשים חיבור אינטרנט פעיל וזמין רק לפרויקטים ברמת Blaze.

במאמר זה, אנו מפעילים את ממשק ה- API לזיהוי טקסט באופן מקומי, כך שתוכלו לעקוב אחריכם ללא קשר לשדרוגם ל- Blaze, או אם אתם נמצאים בתוכנית ניצוץ Firebase Spark.

יצירת אפליקציית זיהוי טקסט עם ערכת ML

צור יישום עם ההגדרות שבחרת, אך כשתתבקש בחר בחר בתבנית "פעילות ריקה".


ה- SDK של ערכת ML הוא חלק מ- Firebase, כך שתצטרך לחבר את הפרוייקט שלך ל- Firebase, באמצעות אישור חתימת ה- SHA-1 שלו. כדי להשיג את ה- SHA-1 של הפרויקט שלך:

  • בחר בכרטיסייה "סטודיו" של Android Studio.
  • בחלונית "פרויקטים של Gradle", לחץ פעמיים כדי להרחיב את "השורש" של הפרויקט שלך ואז בחר "משימות> Android> חתימת דוח."
  • על הפאנל שבתחתית חלון Android Studio להתעדכן כדי להציג מידע על פרויקט זה - כולל אישור חתימתו על ה- SHA-1.

לחיבור הפרוייקט שלך ל- Firebase:

  • בדפדפן האינטרנט שלך, הפעל את מסוף האש.
  • בחר "הוסף פרויקט."
  • תן שם לפרויקט שלך; אני משתמש במבחן ML.
  • קרא את התנאים, ואם אתה שמח להמשיך, בחר "אני מקבל ..." ואחריו "צור פרויקט."
  • בחר "הוסף בסיס אש לאפליקציית Android שלך."
  • הזן את שם החבילה של הפרויקט שלך, אותו תוכל למצוא בראש קובץ MainActivity, ובתוך המניפסט.
  • הזן את אישור חתימת ה- SHA-1 של הפרויקט שלך.
  • לחץ על "הרשמת אפליקציה."
  • בחר "הורד google-services.json." קובץ זה מכיל את כל המטא-נתונים הדרושים לאינטרנט ב- Firebase לפרויקט שלך, כולל מפתח ה- API.
  • באנדרואיד סטודיו, גרור ושחרר את קובץ google-services.json לספריית האפליקציה של הפרויקט.


  • פתח את קובץ build.gradle שלך ​​ברמת הפרויקט והוסף את מסלול הכיתה של שירותי Google:

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

  • פתח את קובץ build.gradle שלך ​​ברמת האפליקציה והוסף תלות לקבוצת Firebase Core, Firebase ML Vision ולמתורגמן הדוגמניות, בנוסף לתוסף שירותי Google:

החל תוסף: com.google.gms.google-services ... ... ... תלות {File FileTree (dir: libs, כולל:) יישום com.google.firebase: core-core: 16.0.1 יישום com. google.firebase: firebase-ml-vision: יישום 16.0.0 com.google.firebase: firebase-ml-model-interpreter: 16.0.0

בשלב זה תצטרך להריץ את הפרויקט שלך כך שהוא יוכל להתחבר לשרתי Firebase:

  • התקן את האפליקציה שלך בסמארטפון או טאבלט אנדרואיד פיזי, או מכשיר אנדרואיד אנדרואיד (AVD).
  • במסוף Firebase, בחר "הפעל אפליקציה לאימות ההתקנה."
  • אחרי כמה רגעים, אתה אמור לראות "מזל טוב"; בחר "המשך למסוף."

הורד את דגמי למידת המכונות של גוגל המאומנים מראש

כברירת מחדל, ML Kit מוריד רק דגמים לפי הצורך, ולכן האפליקציה שלנו תוריד את דגם ה- OCR כאשר המשתמש ינסה לחלץ טקסט בפעם הראשונה.

זה עשוי להשפיע לרעה על חוויית המשתמש - דמיין לנסות לגשת לתכונה, רק כדי לגלות שהאפליקציה צריכה להוריד משאבים נוספים לפני שהיא תוכל לספק את התכונה הזו בפועל. במקרה הגרוע ביותר, ייתכן שהאפליקציה שלך אפילו לא תוכל להוריד את המשאבים הדרושים להם, כאשר היא זקוקה להם, למשל אם למכשיר אין חיבור אינטרנט.

כדי לוודא שזה לא קורה באפליקציה שלנו, אני הולך להוריד את המודל OCR הדרוש בזמן ההתקנה, הדורש שינויים מסוימים ב- Maniest.

למרות שיש לנו את המניפסט פתוח, אני גם הולך להוסיף את ההרשאה WRITE_EXTERNAL_STORAGE, בה אנו נשתמש בה בהמשך במדריך זה.

// הוסף את ההרשאה WRITE_EXTERNAL_STORAGE // // הוסף את הבא //

בניית הפריסה

בואו נגמור את הדברים הקלים מהדרך, וצור פריסה המורכבת מ:

  • תצוגה מקדימה. בתחילה זה יציג מציין מיקום, אך הוא יתעדכן ברגע שהמשתמש יבחר תמונה מהגלריה שלו.
  • כפתור, שמפעיל את חילוץ הטקסט.
  • מבט טקסט, בו נציג את הטקסט שחולץ.
  • תצוגת גלילה. מכיוון שאין אחריות שהטקסט שחולץ יתאים למסך בצורה מסודרת, אני הולך למקם את ה- TextView בתוך ScrollView.

להלן קובץ ה- Activity_main.xml המוגמר:

פריסה זו מתייחסת לצילום "ic_placeholder", אז בואו ליצור זאת כעת:

  • בחר "קובץ> חדש> נכס תמונה" מסרגל הכלים של Android Studio.
  • פתח את התפריט הנפתח "סוג אייקון" ובחר "סמלי סרגל פעולה וטאב."
  • ודא כי לחצן הבחירה "קליפ ארט" נבחר.
  • לחץ על לחצן "קליפ ארט" לחץ.
  • בחר בתמונה בה ברצונך להשתמש כמציין המיקום שלך; אני משתמש ב"הוסף לתמונות. "
  • לחץ על "אישור."
  • פתח את התפריט הנפתח "נושא" ובחר "HOLO_LIGHT."
  • בשדה "שם", הזן את "ic_placeholder."
  • לחץ על "הבא". קרא את המידע, ואם אתה שמח להמשיך, לחץ על "סיום".

סמלי סרגל פעולה: הפעלת אפליקציית הגלריה

בשלב הבא, אני הולך ליצור פריט בסרגל פעולה שיפעיל את גלריית המשתמש, מוכן לבחירת תמונה.

אתה מגדיר סמלי סרגל פעולה בתוך קובץ משאב תפריט, החי בתוך ספריית ה- res / menu. אם הפרויקט שלך אינו מכיל את הספריה הזו, תצטרך ליצור אותו:

  • לחץ על בקרה על ספריית ה- "res" של הפרויקט שלך ובחר "New> Directory Resource Android".
  • פתח את התפריט הנפתח "סוג משאבים" ובחר "תפריט."
  • "שם הספריה" אמור להתעדכן אוטומטית ל"תפריט ", אך אם הוא לא תצטרך לשנות אותו באופן ידני.
  • לחץ על "אישור."

אתה מוכן כעת ליצור את קובץ משאב התפריט:

  • לחץ על שליטה על תיקיית "התפריט" של הפרויקט שלך ובחר "חדש> קובץ משאב תפריט."
  • תן שם לקובץ זה "my_menu."
  • לחץ על "אישור."
  • פתח את הקובץ "my_menu.xml" והוסף את הדברים הבאים:

//ליצור אלמנט לכל פעולה //

קובץ התפריט מתייחס למחרוזת "action_gallery", אז פתח את קובץ ה- res / Values ​​/ strings.xml של הפרויקט וצור את המשאב הזה. בזמן שאני כאן אני מגדיר גם את שאר המחרוזות בהן אנו משתמשים במהלך הפרויקט הזה.

גלריה אפליקציה זו צריכה לגשת לקבצים במכשיר שלך. לא נמצא טקסט

בשלב הבא השתמש בסטודיו 'נכס תמונות' כדי ליצור את הסמל 'ic_gallery' של סרגל הפעולות:

  • בחר "קובץ> חדש> נכס תמונה."
  • הגדר את התפריט הנפתח "סוג אייקון" ל"סמל הפעולה וסמלי כרטיסיות. "
  • לחץ על כפתור "קליפ ארט".
  • בחר מגירה; אני משתמש ב"תמונה ".
  • לחץ על "אישור."
  • כדי לוודא שסמל זה נראה בבירור בסרגל הפעולות, פתח את התפריט הנפתח "נושא" ובחר "HOLO_DARK."
  • תן שם לסמל זה "ic_gallery."
  • "לחץ על" הבא "ואחריו" סיום. "

טיפול בבקשות הרשאה ואירועי קליקים

אני הולך לבצע את כל המשימות שלא קשורות ישירות לממשק ה- API לזיהוי טקסט בשיעור BaseActivity נפרד, כולל הפעלת התפריט, טיפול באירועי קליק בסרגל הפעולות ובקשת גישה לאחסון המכשיר.

  • בחר "קובץ> חדש> כיתת Java" בסרגל הכלים של Android Studio.
  • תן שם למחלקה הזו "BaseActivity."
  • לחץ על "אישור."
  • פתח את BaseActivity והוסף את הדברים הבאים:

יבוא android.app.Activity; יבוא android.support.v4.app.ActivityCompat; יבוא android.support.v7.app.ActionBar; יבוא android.support.v7.app.AlertDialog; יבוא android.support.v7.app.AppCompatActivity; יבוא android.os.Bundle; יבוא android.content.Dialog Interface; יבוא android.content.Intent; יבוא אנדרואיד. חיים; יבוא android.provider.MediaStore; יבוא android.view.Menu; יבוא android.view.MenuItem; יבוא android.content.pm.PackageManager; יבוא android.net.Uri; יבוא android.provider.Settings; יבוא android.support.annotation.NonNull; יבוא android.support.annotation. ביטול; יבוא java.io.File; BaseActivity בכיתה ציבורית מרחיב את AppCompatActivity {public static final int WRITE_STORAGE = 100; גמר סטטי ציבורי int SELECT_PHOTO = 102; מחרוזת סטטי ציבורית ציבורית מחרוזת ACTION_BAR_TITLE = "action_bar_title"; תמונת קובץ ציבורית; @ חלוק על חלל מוגן על OnCreate (@ Bundel הצילום אינסטנס סטייט) {super.onCreate (SaveInstanceState); ActionBar actionBar = getSupportActionBar (); if (actionBar! = null) {actionBar.setDisplayHomeAsUpEnabled (נכון); actionBar.setTitle (getIntent (). getStringExtra (ACTION_BAR_TITLE)); }} @ העבר את בוליאן ציבורי ב-CreateOptions Menu (תפריט תפריט) {getMenuInflater (). לנפח (R.menu.my_menu, תפריט); להחזיר אמיתי; } @ העבר את OnOptionsItemSelected הציבור הבוליאני הציבורי (פריט MenuItem) {switch (item.getItemId ()) {// אם "gallery_action" נבחר, ... ... מקרה R.id.gallery_action: //... בדוק שיש לנו הרשאת WRITE_STORAGE // checkPermission (WRITE_STORAGE); לשבור; } להחזיר super.onOptionsItem Selected (פריט); } @ ביטול חלל ציבורי עלRequestPermissionsResult (קוד בקרת int, @ הרשאות מחרוזת של NNNoll, @NonNull int grantResults) {super.onRequestPermissionsResult (בקשת קוד, הרשאות, grantResults); החלף (בקשת קוד) {מקרה WRITE_STORAGE: // אם בקשת ההרשאה ניתנת, אז ... // if (giveResults.length> 0 && grantResults == PackageManager. PERMISSION_GRANTED) {//... בחר בחר תמונה // selectPicture ( ); // אם בקשת ההרשאה נדחתה, אז ... //} אחרת {//..דגים את מחרוזת "Permission_request" // requestPermission (זה, requestCode, R.string.permission_request); } לשבור; }} // הציגו את תיבת הדו-שיח לבקשת ההרשאה // בקשה לבטלה חלילה סטטית ציבורית הרשאה (פעילות אחרונה, קוד בקשה int int), int msg) {AlertDialog.Builder alert = new AlertDialog.Builder (פעילות); alert.set (msg); alert.setPositiveButton (android.R.string.ok, DialogInterface.OnClickListener חדש () {@ Override void public onClick (DialogInterface dialogInterface, int i) {dialogInterface.dismiss (); Intent permissonIntent = new Intent (Settings.ACTION_APPLILSATION_ETAUTS) .setData (Uri.parse ("חבילה:" + Activity.getPackageName ())); Activity.startActivityForResult (permissonIntent, requestCode);}}); alert.setNegativeButton (android.R.string.cancel, DialogInterface חדש.OnClickListener () {@ הפוך את הריק לציבור ב-Click (DialogInterface dialogInterface, int i) {dialogInterface.dismiss ();}}); alert.set ניתן לביטול (כוזב); alert.show (); } // בדוק אם המשתמש העניק הרשאת WRITE_STORAGE // checkPermission void public (int requestCode) {switch (requestCode) {case WRITE_STORAGE: int hasWriteExternalStoragePermission = ActivityCompat.checkSelfPermission (זה, Manifest.permission.WRITE_EXTERNAL_STORAGE); // אם יש לנו גישה לאחסון חיצוני ... // if (hasWriteExternalStoragePermission == PackageManager.PERMISSION_GRANTED) {//..Call selectPicture, שמשיקה פעילות בה המשתמש יכול לבחור תמונה // selectPicture (); // אם לא ניתנה הרשאה, אז ... //} אחרת {//... בקש את ההרשאה // ActivityCompat.requestPermissions (זה, מחרוזת חדשה {Manifest.permission.WRITE_EXTERNAL_STORAGE}, בקשת קוד); } לשבור; }} חלל פרטי selectPicture () {photo = MyHelper.createTempFile (תמונה); כוונת כוונה = כוונה חדשה (כוונה.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI); // התחל פעילות שבה המשתמש יכול לבחור תמונה // startActivityForResult (כוונה, SELECT_PHOTO); }}

בשלב זה, הפרויקט שלך צריך להתלונן שהוא לא יכול לפתור את MyHelper.createTempFile. בואו ליישם זאת עכשיו!

שינוי גודל התמונות באמצעות createTempFile

צור כיתת "MyHelper" חדשה. בכיתה זו אנו הולכים לשנות את גודל התמונה שנבחרה של המשתמש, ומוכנים לעיבוד באמצעות ממשק ה- API לזיהוי טקסט.

יבוא android.graphics.Bitmap; יבוא android.graphics.BitmapFactory; יבוא android.content.Context; יבוא android.database. סמן; יבוא אנדרואיד.וס.סביבה; יבוא android.widget.ImageView; יבוא android.provider.MediaStore; יבוא android.net.Uri; ייבא אנדרואיד סטטיסטיקות. גרפיקה.BitmapFactory.decodeFile; ייבא אנדרואיד סטטיסטיקות. BitmapFactory.decodeStream; יבוא java.io.File; יבוא java.io.FileNotFoundException; יבוא java.io.FileOutputStream; יבוא java.io.IO חריגה; מעמד ציבורי MyHelper {מחרוזת סטטי פומבית getPath (הקשר הקשר, אורי uri) {String path = ""; הקרנת מחרוזת = {MediaStore.Images.Media.DATA}; סמן סמן = context.getContentResolver (). שאילתה (uri, הקרנה, null, null, null); int column_index; if (סמן! = null) {column_index = cursor.getColumnIndexOrThrow (MediaStore.Images.Media.DATA); cursor.moveToFirst (); נתיב = cursor.getString (column_index); cursor.close (); } דרך חזרה; } קובץ סטטי ציבורי createTempFile (קובץ קובץ) {תיקיית קבצים = קובץ חדש (Environment.getExternalStorageDirectory (). getPath () + "/com.jessicathornsby.myapplication"); if (! directory.exists () ||! directory.is מדריך ()) {directory.mkdirs (); } if (קובץ == null) {file = קובץ חדש (תיקייה, "orig.jpg"); } קובץ החזרה; } שינוי גודל תמונה סטטי פומבי של סיביות (קובץ imageFile, הקשר הקשר, אורי 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 (קובץ imageFile, מסלול מחרוזת, תצוגת ImageView) {BitmapFactory.Options אפשרויות = חדש BitmapFactory.Options (); decodeFile (נתיב, אפשרויות); int photoHeight = אפשרויות. outHeight; int photoWidth = אפשרויות. outWidth; options.inSampleSize = Math.min (photoWidth / view.getWidth (), photoHeight / view.getHeight ()); להחזיר compressPhoto (imageFile, BitmapFactory.decodeFile (נתיב, אפשרויות)); } סטטי פרטי BitMap compressPhoto (קובץ photoFile, מפת bitmap bitmap) {נסה {FileOutputStream fOutput = חדש FileOutputStream (photoFile); bitmap.compress (Bitmap.CompressFormat.JPEG, 70, fUTUTUT); fOutput.close (); } catch (חריג IOException) {exception.printStackTrace (); } מפת סיביות להחזיר; }}

הגדר את התמונה ל- ImageView

בשלב הבא עלינו ליישם את OnActivityResult () בכיתת MainActivity שלנו ולהגדיר את התמונה שנבחרה של המשתמש ל- ImageView שלנו.

יבוא android.graphics.Bitmap; יבוא android.os.Bundle; יבוא android.widget.ImageView; יבוא android.content.Intent; יבוא android.widget.TextView; יבוא android.net.Uri; MainActivity בכיתה ציבורית מרחיבה את BaseActivity {פרטי BitMap myBitmap; ImageView פרטי MyImageView; תצוגת טקסט פרטית myTextView; @Orride חלל מוגן onCreate (Bundle savedInstanceState) {super.onCreate (savedInstanceState); setContentView (R.layout.activity_main); myTextView = findViewById (R.id.textView); myImageView = findViewById (R.id.imageView); } @ חלף על חלל מוגן עלActivityResult (קוד בקרת int, קוד result result, קוד כניסה) {super.onActivityResult (בקשת קוד, resultCode, נתונים); if (resultCode == RESULT_OK) {switch (requestCode) {case WRITE_STORAGE: checkPermission (requestCode); לשבור; מקרה SELECT_PHOTO: Uri dataUri = data.getData (); נתיב מחרוזת = MyHelper.getPath (זה, dataUri); if (נתיב == null) {myBitmap = MyHelper.resizePhoto (תמונה, זה, dataUri, myImageView); } else {myBitmap = MyHelper.resizePhoto (תמונה, נתיב, myImageView); } if (myBitmap! = null) {myTextView.setText (null); myImageView.setImageBitmap (myBitmap); } לשבור; }}}}

הפעל פרויקט זה במכשיר אנדרואיד פיזי או AVD, ולתת לסמל סרגל הפעולה לחץ. כשתתבקש, העניק הרשאת WRITE_STORAGE ובחר תמונה מהגלריה; תמונה זו צריכה להיות מוצגת כעת בממשק המשתמש של האפליקציה שלך.

עכשיו שמנו את היסודות, אנו מוכנים להתחיל לחלץ טקסט!

לימוד אפליקציה לזיהוי טקסט

אני רוצה להפעיל זיהוי טקסט בתגובה לאירוע קליקים, ולכן עלינו ליישם OnClickListener:

יבוא android.graphics.Bitmap; יבוא android.os.Bundle; יבוא android.widget.ImageView; יבוא android.content.Intent; יבוא android.widget.TextView; יבוא android.view.View; יבוא android.net.Uri; MainActivity בכיתה ציבורית מרחיבה BaseActivity מיישמת View.OnClickListener {פרטי BitMap myBitmap; ImageView פרטי MyImageView; תצוגת טקסט פרטית myTextView; @Orride חלל מוגן 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 (זה); } @ החלף חלל ציבורי ב-Click (תצוגת תצוגה) {החלף (view.getId ()) {מקרה R.id.checkText: אם (myBitmap! = Null) {// אנו מיישמים את runTextRecog בשלב הבא // runTextRecog (); } לשבור; }}

ML Kit יכול לעבד תמונות רק כשהן בפורמט FirebaseVisionImage, ולכן עלינו להמיר את התמונה שלנו לאובייקט FirebaseVisionImage. באפשרותך ליצור FirebaseVisionImage ממפת BitMap, media.Image, ByteBuffer או מערך בתים. מכיוון שאנו עובדים עם מפת סיביות, עלינו לקרוא לשיטת השירות fromBitmap () של כיתת FirebaseVisionImage ולהעביר אותה מפת ה- Bitmap שלנו.

void private 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 // To do //}}). AddOnFailureListener (OnFailureListener חדש () {@ Override void onFailure (@ יוצא מן הכלל על שום חריג) {// המשימה נכשלה עם חריג //}}); }

אם פעולה זו לא תצליח, אני אציג הרמת כוסית, אך אם הפעולה מצליחה, אני אתקשר לתהליך ExtractedText עם התגובה.

בשלב זה, קוד זיהוי הטקסט שלי נראה כך:

// צור FirebaseVisionImage // private void runTextRecog () {FirebaseVisionImage image = FirebaseVisionImage.fromBitmap (myBitmap); // צור מופע של FirebaseVisionCloudTextDetector // FirebaseVisionTextDetector גלאי = FirebaseVision.getInstance (). GetVisionTextDetector (); // רשום OnSuccessListener // detector.detectInImage (image) .addOnSuccessListener (OnSuccessListener חדש)() {@ Override // הטמיע את ה- Callback של OnSuccess // חלל ציבורי onSuccess (טקסטים של FirebaseVisionText) {// Call processExtractedText עם התגובה // processExtractedText (טקסטים); }}). addOnFailureListener (OnFailureListener חדש () {@Override // הטמיע את calback onFailure // חלל ציבורי onFailure (@ יוצא מן הכלל ללא יוצא מן הכלל) {Toast.makeText (MainActivity.this, "חריג", Toast.LENGTH_LONG). );}}); }

בכל פעם שהאפליקציה שלנו מקבלת הודעה onSuccess, עלינו לנתח את התוצאות.

אובייקט FirebaseVisionText יכול להכיל אלמנטים, קווים וחסימות, כאשר כל בלוק בדרך כלל משווה לפסקה בודדת של טקסט. אם FirebaseVisionText מחזיר 0 בלוקים, אנו נציג את מחרוזת "no_text", אך אם הוא מכיל בלוק אחד או יותר אז אנו נציג את הטקסט שאוחזר כחלק מתצוגת Text.

process void privateExtractedText (FirebaseVisionText firebaseVisionText) {myTextView.setText (null); if (firebaseVisionText.getBlocks (). גודל () == 0) {myTextView.setText (R.string.no_text); להחזיר; } עבור (FirebaseVisionText.Block block: firebaseVisionText.getBlocks ()) {myTextView.append (block.getText ()); }}}

להלן קוד ה- MainActivity שהושלם:

יבוא android.graphics.Bitmap; יבוא android.os.Bundle; יבוא android.widget.ImageView; יבוא android.content.Intent; יבוא android.widget.TextView; יבוא android.widget.Toast; יבוא android.view.View; יבוא android.net.Uri; יבוא android.support.annotation.NonNull; יבוא 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; תצוגת טקסט פרטית myTextView; @Orride חלל מוגן 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 (זה); } @ החלף חלל ציבורי ב-Click (תצוגת תצוגה) {switch (view.getId ()) {מקרה R.id.checkText: if (myBitmap! = Null) {runTextRecog (); } לשבור; }} @ החלף חלל מוגן onActivityResult (קוד בקרת int, קוד result code, נתוני כוונה) {super.onActivityResult (requestCode, resultCode, data); if (resultCode == RESULT_OK) {switch (requestCode) {case WRITE_STORAGE: checkPermission (requestCode); לשבור; מקרה SELECT_PHOTO: Uri dataUri = data.getData (); נתיב מחרוזת = MyHelper.getPath (זה, dataUri); if (נתיב == null) {myBitmap = MyHelper.resizePhoto (תמונה, זה, dataUri, myImageView); } else {myBitmap = MyHelper.resizePhoto (תמונה, נתיב, myImageView); } if (myBitmap! = null) {myTextView.setText (null); myImageView.setImageBitmap (myBitmap); } לשבור; }}} runTextRecog () {FirebaseVisionImage image = FirebaseVisionImage.fromBitmap (myBitmap); גלאי FirebaseVisionTextDetector = FirebaseVision.getInstance (). GetVisionTextDetector (); detector.detectInImage (תמונה) .addOnSuccessListener (OnSuccessListener חדש)() {@ הרחק את חלל הציבור ב-Success (טקסטים של FirebaseVisionText) {processExtractedText (טקסטים); }}). addOnFailureListener (OnFailureListener חדש () {@ הפעל חלל ציבורי onFailure (חריג חריג מ- NNNull) {Toast.makeText (MainActivity.this, "חריג", טוסט.LENGTH_LONG). show ();}}); } process void privateExtractedText (FirebaseVisionText firebaseVisionText) {myTextView.setText (null); if (firebaseVisionText.getBlocks (). גודל () == 0) {myTextView.setText (R.string.no_text); להחזיר; } עבור (FirebaseVisionText.Block block: firebaseVisionText.getBlocks ()) {myTextView.append (block.getText ()); }}}

בדיקת הפרויקט

עכשיו הגיע הזמן לראות את זיהוי הטקסט של ML Kit בפעולה! התקן פרויקט זה במכשיר אנדרואיד או AVD, בחר תמונה מהגלריה ואז תן ללחיצה על כפתור "בדוק את הטקסט". היישום צריך להגיב על ידי חילוץ כל הטקסט מהתמונה, ואז הצגתו ב- TextView.

שים לב כי בהתאם לגודל התמונה שלך, וכמות הטקסט שהיא מכילה, יתכן שתצטרך לגלול כדי לראות את כל הטקסט שחולץ.

אתה יכול גם להוריד את הפרויקט שהושלם מ- GitHub.

מסיימים

עכשיו אתה יודע לזהות ולחלץ טקסט מתמונה באמצעות ערכת ML.

ממשק ה- API לזיהוי טקסט הוא רק חלק אחד בערכת ה- ML. SDK זה מציע גם סריקת ברקודים, זיהוי פנים, תיוג תמונות וזיהוי ציוני דרך, עם תוכניות להוסיף עוד ממשקי API למקרים נפוצים לשימוש בנייד, כולל תגובה חכמה וממשק API לקווי מתאר בצפיפות גבוהה.

איזה API של ערכת ML אתה הכי מעוניין לנסות? ספר לנו בתגובות למטה!

שני טלפונים ייחודיים של ZTE הופיעו ברשת, וחשפו אלטרנטיבות דרסטיות לחריץ.ה- ZTE Axon כולל עיצוב מחוון אופקי, במקום המנגנון האנכי המבוסס יותר.לעומת זאת, ל- ZTE Axon V יש מעטה למצלמה שיוצא משאר הטלפון.ל...

פוזיטיביותעיצוב דק ומבריק איכות בנייה מעולה תצוגת AMOLED מעוגלת-קצה חיי סוללה טובים תוכנת אנדרואיד קרוב למלאי חיישן טביעות אצבע בתצוגה הוא אמין טעינה צ'י אלחוטית נקודת מחיר אגרסיבית...

פרסומים פופולריים