كيفية استخراج نص من الصور باستخدام Google Learning Machine SDK

مؤلف: John Stephens
تاريخ الخلق: 27 كانون الثاني 2021
تاريخ التحديث: 5 تموز 2024
Anonim
Lesson 49 How to extract text from images in python كيف تستخرج نص من الصور فى بايثون
فيديو: Lesson 49 How to extract text from images in python كيف تستخرج نص من الصور فى بايثون

المحتوى


يمكنك أيضًا استخدام واجهة برمجة تطبيقات التعرف على النص كأساس لتطبيقات الترجمة أو خدمات إمكانية الوصول حيث يمكن للمستخدم توجيه الكاميرا الخاصة بهم إلى أي نص يكافحون معه ، وقراءته بصوت عالٍ لهم.

في هذا البرنامج التعليمي ، سنضع الأساس لمجموعة واسعة من الميزات المبتكرة ، من خلال إنشاء تطبيق يمكنه استخراج نص من أي صورة في معرض المستخدم. على الرغم من أننا لن نغطيها في هذا البرنامج التعليمي ، يمكنك أيضًا التقاط نص من محيط المستخدم في الوقت الفعلي ، عن طريق توصيل هذا التطبيق بكاميرا الجهاز.

على الجهاز أو في السحابة؟

تتوفر بعض واجهات برمجة تطبيقات ML Kit على الجهاز فقط ، ولكن بعضها متاح على الجهاز وفي السحابة ، بما في ذلك واجهة التعرف على النص.

يمكن لواجهة برمجة التطبيقات النصية المستندة إلى مجموعة النظراء تحديد نطاق أوسع من اللغات والأحرف ، كما تعد بدقة أكبر من نظيرها على الجهاز. ومع ذلك ، فإنه هل تتطلب اتصال إنترنت نشطًا ، وهو متاح فقط للمشاريع على مستوى Blaze.

في هذه المقالة ، سنشغل واجهة برمجة تطبيقات التعرف على النص محليًا ، لذلك يمكنك المتابعة بغض النظر عما إذا كنت قد قمت بالترقية إلى Blaze ، أو كنت على خطة Firebase Spark المجانية.


إنشاء تطبيق التعرف على النص مع ML Kit

قم بإنشاء تطبيق بالإعدادات التي تختارها ، ولكن عند المطالبة ، حدد قالب "نشاط فارغ".

يعد ML Kit SDK جزءًا من Firebase ، لذلك ستحتاج إلى توصيل مشروعك بـ Firebase ، باستخدام شهادة توقيع SHA-1. للحصول على SHA-1 لمشروعك:

  • حدد علامة التبويب "Gradle" في Android Studio.
  • في لوحة "مشاريع Gradle" ، انقر نقرًا مزدوجًا لتوسيع "جذر" مشروعك ، ثم حدد "المهام> Android> توقيع التقرير".
  • يجب تحديث اللوحة الموجودة أسفل نافذة Android Studio لعرض بعض المعلومات حول هذا المشروع - بما في ذلك شهادة توقيع SHA-1.

لتوصيل مشروعك بـ Firebase:

  • في متصفح الويب الخاص بك ، قم بتشغيل Firebase Console.
  • حدد "إضافة مشروع".
  • أعط اسم مشروعك أنا أستخدم "اختبار ML".
  • اقرأ الشروط والأحكام ، وإذا كنت سعيدًا بالمتابعة ، فحدد "أوافق ..." ثم "إنشاء مشروع".
  • حدد "إضافة Firebase إلى تطبيق Android الخاص بك."
  • أدخل اسم حزمة المشروع ، والذي ستجده في الجزء العلوي من ملف MainActivity ، وداخل البيان.
  • أدخل شهادة توقيع SHA-1 لمشروعك.
  • انقر فوق "تسجيل التطبيق".
  • حدد "تنزيل google-services.json". يحتوي هذا الملف على جميع بيانات تعريف Firebase اللازمة لمشروعك ، بما في ذلك مفتاح API.
  • في Android Studio ، اسحب وإسقط ملف google-services.json في دليل "تطبيق" مشروعك.


  • افتح ملف build.gradle على مستوى المشروع وأضف classpath لخدمات Google:

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

  • افتح ملف build.gradle على مستوى التطبيق الخاص بك ، وقم بإضافة تبعيات لـ Firebase Core و Firebase ML Vision ومترجم النموذج ، بالإضافة إلى مكون خدمات Google الإضافي:

طبق المكوّن الإضافي: com.google.gms.google-services ... ... ... تبعيات {application fileTree (dir: libs، include:) application com.google.firebase: firebase-core: 16.0.1 implementation com. google.firebase: firebase-ml-vision: تطبيق 16.0.0 com.google.firebase: firebase-ml-model-phpreter: 16.0.0

في هذه المرحلة ، ستحتاج إلى تشغيل مشروعك حتى يتمكن من الاتصال بخوادم Firebase:

  • قم بتثبيت تطبيقك على هاتف ذكي أو جهاز لوحي يعمل بنظام Android ، أو على جهاز Android الظاهري (AVD).
  • في Firebase Console ، حدد "تشغيل التطبيق للتحقق من التثبيت".
  • بعد لحظات قليلة ، سترى "مبروك" ؛ حدد "متابعة إلى وحدة التحكم."

قم بتنزيل نماذج Google للتعلم الآلي المدربة مسبقًا

بشكل افتراضي ، يقوم ML Kit بتنزيل النماذج فقط عند الحاجة إليها ، لذلك سيقوم التطبيق لدينا بتنزيل نموذج التعرف الضوئي على الحروف عندما يحاول المستخدم استخراج النص لأول مرة.

قد يكون لهذا تأثير سلبي على تجربة المستخدم - تخيل محاولة الوصول إلى ميزة ، فقط لاكتشاف أن التطبيق عليه تنزيل المزيد من الموارد قبل أن يتمكن من تقديم هذه الميزة بالفعل. في أسوأ الحالات ، قد لا يتمكن تطبيقك حتى من تنزيل الموارد التي يحتاجها ، عندما يحتاج إليها ، على سبيل المثال إذا كان الجهاز ليس لديه اتصال بالإنترنت.

للتأكد من أن هذا لا يحدث مع تطبيقنا ، سأقوم بتنزيل طراز OCR الضروري في وقت التثبيت ، والذي يتطلب بعض التغييرات على Maniest.

على الرغم من فتح "البيان" ، سأضيف أيضًا إذن WRITE_EXTERNAL_STORAGE ، الذي سنستخدمه لاحقًا في هذا البرنامج التعليمي.

// أضف إذن WRITE_EXTERNAL_STORAGE // // أضف التالي //

بناء التصميم

دعنا نتخلص من الأشياء السهلة وننشئ نسقًا يتكون من:

  • ImageView. في البداية ، سيعرض هذا عنصرًا نائبًا ، لكنه سيتم تحديثه بمجرد أن يختار المستخدم صورة من معرضه.
  • زر ، والذي يؤدي إلى استخراج النص.
  • عرض نص ، حيث سنقوم بعرض النص المستخرج.
  • ScrollView. نظرًا لعدم وجود ضمان بأن النص المستخرج سيكون ملائمًا على الشاشة ، فسوف أضع TextView داخل ScrollView.

إليك ملف activity_main.xml النهائي:

يشير هذا التخطيط إلى "ic_placeholder" القابل للدوران ، لذلك دعونا ننشئ هذا الآن:

  • حدد "ملف> جديد> Image Asset" من شريط أدوات Android Studio.
  • افتح القائمة المنسدلة "نوع الأيقونة" وحدد "شريط الإجراءات وعلامات التبويب".
  • تأكد من تحديد زر الاختيار "Clip Art".
  • أعط زر "قصاصة فنية" نقرة.
  • حدد الصورة التي تريد استخدامها كعنصر نائب ؛ أنا أستخدم "إضافة إلى الصور".
  • انقر فوق موافق."
  • افتح القائمة المنسدلة "السمة" ، واختر "HOLO_LIGHT".
  • في حقل "الاسم" ، أدخل "ic_placeholder".
  • انقر فوق "التالي". اقرأ المعلومات ، وإذا كنت سعيدًا بالمتابعة ، فانقر فوق "إنهاء".

رموز شريط الإجراءات: بدء تشغيل تطبيق المعرض

بعد ذلك ، سوف أقوم بإنشاء عنصر شريط إجراءات يبدأ تشغيل معرض المستخدم ، ويكون جاهزًا له لتحديد صورة.

يمكنك تحديد أيقونات شريط الإجراءات داخل ملف مورد قائمة ، والذي يعيش داخل دليل "res / menu". إذا كان مشروعك لا يحتوي على هذا الدليل ، فستحتاج إلى إنشائه:

  • انقر مع الضغط على Control على دليل "res" الخاص بمشروعك واختر "New> Android Resource Directory."
  • افتح القائمة المنسدلة "نوع المورد" وحدد "القائمة".
  • يجب تحديث "اسم الدليل" إلى "القائمة" تلقائيًا ، ولكن إذا لم يكن كذلك ، فستحتاج إلى إعادة تسميته يدويًا.
  • انقر فوق موافق."

أنت الآن جاهز لإنشاء ملف مورد القائمة:

  • انقر مع الضغط على Control على دليل "قائمة" في مشروعك وحدد "New> ملف مورد القائمة".
  • اسم هذا الملف "my_menu".
  • انقر فوق موافق."
  • افتح ملف "my_menu.xml" ، وأضف ما يلي:

//يخترع عنصر لكل عمل //

يشير ملف القائمة إلى سلسلة "action_gallery" ، لذا افتح ملف res / values ​​/ strings.xml للمشروع الخاص بك وقم بإنشاء هذا المورد. بينما أنا هنا ، أقوم أيضًا بتحديد السلاسل الأخرى التي سنستخدمها في هذا المشروع.

صالة عرض يحتاج هذا التطبيق للوصول إلى الملفات الموجودة على جهازك. لم يتم العثور على نص

بعد ذلك ، استخدم Image Asset Studio لإنشاء رمز "ic_gallery" بشريط الإجراءات:

  • اختر "ملف> جديد> صورة الأصل".
  • اضبط القائمة المنسدلة "نوع الأيقونة" على "شريط الإجراءات وعلامات الجدولة".
  • انقر فوق الزر "قصاصة فنية".
  • اختيار drawable. أنا أستخدم "الصورة".
  • انقر فوق موافق."
  • للتأكد من أن هذا الرمز مرئي بوضوح في شريط الإجراءات ، افتح القائمة المنسدلة "السمة" وحدد "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.DialogInterface؛ استيراد android.content.Intent ؛ استيراد android.Manifest. استيراد 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.Nullable؛ استيراد java.io.File ؛ BaseActivity الفئة العامة يمتد AppCompatActivity {public static final int WRITE_STORAGE = 100؛ نهائي ثابت عام int SELECT_PHOTO = 102؛ نهائي ثابت عام StION ACTION_BAR_TITLE = "action_bar_title"؛ ملف الصورة العامة. Override محمية void onCreate (Nullable Bundle saveInstanceState) {super.onCreate (saveInstanceState)؛ ActionBar actionBar = getSupportActionBar ()؛ if (actionBar! = null) {actionBar.setDisplayHomeAsUpEnabled (true)؛ actionBar.setTitle (getIntent () getStringExtra (ACTION_BAR_TITLE))؛ }}Override public boolean onCreateOptionsMenu (Menu Menu) {getMenuInflater (). inflate (R.menu.my_menu، menu)؛ العودة الحقيقية ؛ }Override منطقي عام onOptionsItemSelected (عنصر MenuItem) {switch (item.getItemId ()) {// إذا تم تحديد "gallery_action" ، فعندئذ ... // case R.id.gallery_action: //...check لدينا إذن WRITE_STORAGE // checkPermission (WRITE_STORAGE) ؛ استراحة؛ } إرجاع super.onOptionsItemSelected (item) ؛ }Override public void onRequestPermissionsResult (int requestCode،NonNull String الأذونات،NonNull int grantResults) {super.onRequestPermissionsResult (requestCode، الأذونات، grantResults)؛ التبديل (requestCode) {case WRITE_STORAGE: // إذا تم منح طلب الإذن ، ف ... // if (grantResults.length> 0 && grantResults == PackageManager.PERMISSION_GRANTED) {//...call selectPicture // selectPicture ( )؛ // إذا تم رفض طلب الإذن ، فحينئذٍ ... //} آخر {//.. عرض سلسلة "ذن_الطلب "// requestPermission (هذا ، requestCode ، R.string.permission_request) ؛ } استراحة؛ }} // عرض مربع حوار طلب الإذن // public static void requestPermission (نشاط النشاط النهائي ، requestCode ، int msg) {AlertDialog.Builder alert = new AlertDialog.Builder (نشاط)؛ alert.set (جي اس)؛ alert.setPositiveButton (android.R.string.ok ، DialogInterface.OnClickListener () {Override public void onClick (DialogInterface dialogInterface، int i) {dialogInterface.dismiss ()؛ Intent permissonIntent = new Intent (Settings.ACTION_APPLICATIONSETTAIL_) .setData (Uri.parse ("package:" + activity.getPackageName ()))؛ activity.startActivityForResult (permissonIntent، requestCode)؛}})؛ alert.setNegativeButton (android.R.string.cancel ، DialogInterface.OnClickListener () {Override public void onClick (DialogInterface dialogInterface، int i) {dialogInterface.dismiss ()؛}})؛ alert.setCancelable (كاذبة)؛ alert.show ()؛ } // تحقق مما إذا كان المستخدم قد منح إذن WRITE_STORAGE / / void checkPermission (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} ، requestCode) ؛ } استراحة؛ }} private void selectPicture () {photo = MyHelper.createTempFile (photo)؛ Intent intent = new Intent (Intent.ACTION_PICK، MediaStore.Images.Media.EXTERNAL_CONTENT_URI)؛ // بدء نشاط حيث يمكن للمستخدم اختيار صورة // startActivityForResult (نية ، SELECT_PHOTO) ؛ }}

في هذه المرحلة ، يجب أن يشكو مشروعك من أنه لا يمكن حل MyHelper.createTempFile. لننفذ هذا الآن!

تغيير حجم الصور باستخدام createTempFile

قم بإنشاء فصل "MyHelper" جديد. في هذه الفئة ، سنقوم بتغيير حجم الصورة التي اختارها المستخدم ، جاهزة للتجهيز بواسطة واجهة برمجة تطبيقات التعرف على النص.

استيراد android.graphics.Bitmap ؛ استيراد android.graphics.BitmapFactory ؛ استيراد android.content.Context؛ استيراد android.database.Cursor؛ استيراد android.os.Environment. استيراد android.widget.ImageView ؛ استيراد android.provider.MediaStore؛ استيراد android.net.Uri ؛ استيراد android.graphics ثابت .itmapFactory.decodeFile؛ استيراد ثابت android.graphics.BitmapFactory.decodeStream ؛ استيراد java.io.File ؛ استيراد java.io.FileNotFoundException؛ استيراد java.io.FileOutputStream ؛ استيراد java.io.IOException ؛ الفئة العامة MyHelper {public static getringath Static (سياق السياق ، 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 ()؛ } مسار العودة؛ } ملف ثابت عام createTempFile (ملف ملف) {File directory = ملف جديد (Environment.getExternalStorageDirectory (). getPath () + "/com.jessicathornsby.myapplication")؛ if (! directory.exists () ||! directory.isDirectory ()) {directory.mkdirs ()؛ } if (file == null) {file = new file (directory، "orig.jpg")؛ ملف الإرجاع } صورة ثابتة ثابتة resizePhoto (ملف imageFile ، سياق السياق ، Uri uri ، ImageView view) {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) {استثناء.printStackTrace ()؛ عودة لاغية }} صورة ثابتة ثابتة 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 (المسار ، الخيارات)) ؛ } صورة ثابتة ثابتة للضغط الصوري (File photoFile ، صورة نقطية نقطية) {try {FileOutputStream fOutput = new FileOutputStream (photoFile) ؛ bitmap.compress (Bitmap.CompressFormat.JPEG، 70، fOutput)؛ fOutput.close ()؛ } catch (استثناء IOException) {استثناء.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 {private Bitmap myBitmap؛ ImageView الخاص myImageView. TextView myTextView الخاص ؛ Override محمية void onCreate (Bundle saveInstanceState) {super.onCreate (saveInstanceState)؛ setContentView (R.layout.activity_main)؛ myTextView = findViewById (R.id.textView) ؛ myImageView = findViewById (R.id.imageView) ؛ }Override محمية void onActivityResult (int requestCode ، int resultCode ، Intent data) {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 (path == null) {myBitmap = MyHelper.resizePhoto (الصورة ، هذا ، dataUri ، myImageView) ؛ } آخر {myBitmap = MyHelper.resizePhoto (الصورة ، المسار ، myImageView) ؛ } if (myBitmap! = null) {myTextView.setText (null)؛ myImageView.setImageBitmap (myBitmap)؛ } استراحة؛ }}}}

قم بتشغيل هذا المشروع على جهاز Android الفعلي أو 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 {private Bitmap myBitmap؛ ImageView الخاص myImageView. TextView myTextView الخاص ؛ Override محمية void onCreate (Bundle saveInstanceState) {super.onCreate (saveInstanceState)؛ setContentView (R.layout.activity_main)؛ myTextView = findViewById (R.id.textView) ؛ myImageView = findViewById (R.id.imageView) ؛ findViewById (R.id.checkText) .setOnClickListener (هذا)؛ }Override public void onClick (عرض العرض) {switch (view.getId ()) {case R.id.checkText: if (myBitmap! = null) {// سنقوم بتنفيذ runTextRecog في الخطوة التالية // runTextRecog ()؛ } استراحة؛ }}

يمكن لمجموعة ML معالجة الصور فقط عندما تكون بتنسيق FirebaseVisionImage ، لذلك نحن بحاجة إلى تحويل صورتنا إلى كائن FirebaseVisionImage. يمكنك إنشاء FirebaseVisionImage من صورة نقطية أو media.Image أو ByteBuffer أو صفيف بايت. نظرًا لأننا نعمل مع الصور النقطية ، نحتاج إلى استدعاء أسلوب الأداة المساعدة fromBitmap () لفئة FirebaseVisionImage ، وتمريرها لدينا.

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

يحتوي ML Kit على فئات كشف مختلفة لكل عملية من عمليات التعرف على الصور. بالنسبة للنص ، نحتاج إلى استخدام فئة FirebaseVisionTextDetector ، التي تقوم بالتعرف الضوئي على الأحرف (OCR) على صورة ما.

نقوم بإنشاء مثيل FirebaseVisionTextDetector ، باستخدام getVisionTextDetector:

FirebaseVisionTextDetector detector = FirebaseVision.getInstance (). getVisionTextDetector ()؛

بعد ذلك ، نحتاج إلى التحقق من FirebaseVisionImage للحصول على نص ، عن طريق استدعاء الأسلوب detectInImage () وتمريره كائن FirebaseVisionImage. نحتاج أيضًا إلى تطبيق عمليات الاستعادة onSuccess و onFailure ، بالإضافة إلى المستمعين المقابلين حتى يتم إخطار تطبيقنا عند توفر النتائج.

detector.detectInImage (صورة) .addOnSuccessListener (جديد OnSuccessListener() {Override // To // //}}). addOnFailureListener (new OnFailureListener () {Override public void onFailure (@ استثناء استثناء NonNull) {// المهمة فشلت مع استثناء //}})؛ }

إذا فشلت هذه العملية ، فسأقوم بعرض نخب ، ولكن إذا نجحت العملية ، فسنقوم باستدعاء processExtractedText مع الرد.

في هذه المرحلة ، يبدو رمز الكشف عن النص الخاص بي كما يلي:

// Create a FirebaseVisionImage // private void runTextRecog () {FirebaseVisionImage image = FirebaseVisionImage.fromBitmap (myBitmap)؛ / / قم بإنشاء نسخة من FirebaseVisionCloudTextDetector // FirebaseVisionTextDetector detector = FirebaseVision.getInstance (). getVisionTextDetector ()؛ / / سجل OnSuccessListener // detector.detectInImage (صورة) .addOnSuccessListener (جديد OnSuccessListener() {Override // تطبيق رد الاتصال onSuccess // public void onSuccess (نصوص FirebaseVisionText) {// Call processExtractedText مع الرد // processExtractedText (النصوص)؛ }}). addOnFailureListener (جديد OnFailureListener () {Override // طبّق على onFailure calback // public void onFailure (استثناء استثناء NonNull) {Toast.makeText (MainActivity.this ، "Exception"، Toast.LENGTH_LONG) .show ) ؛}}) ؛ }

عندما يتلقى تطبيقنا إخطار onSuccess ، نحتاج إلى تحليل النتائج.

يمكن أن يحتوي كائن FirebaseVisionText على عناصر وخطوط وكتل ، حيث تساوي كل كتلة عادةً فقرة واحدة من النص. إذا قام FirebaseVisionText بإرجاع 0 كتل ، فسنقوم بعرض سلسلة "no_text" ، ولكن إذا كان يحتوي على واحد أو أكثر من الكتل ، فسنعرض النص المسترجع كجزء من TextView لدينا.

عملية باطلة خاصةExtractedText (FirebaseVisionText firebaseVisionText) {myTextView.setText (null)؛ if (firebaseVisionText.getBlocks (). size () == 0) {myTextView.setText (R.string.no_text)؛ إرجاع؛ } for (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؛ import com.google.firebase.ml.vision.common.FirebaseVisionImage؛ import com.google.firebase.ml.vision.text.FirebaseVisionText؛ import com.google.firebase.ml.vision.text.FirebaseVisionTextDetector؛ import com.google.firebase.ml.vision.FirebaseVision؛ import com.google.android.gms.tasks.OnSuccessListener؛ import com.google.android.gms.tasks.OnFailureListener؛ MainActivity فئة عامة يمتد BaseActivity تنفذ View.OnClickListener {private Bitmap myBitmap؛ ImageView الخاص myImageView. TextView myTextView الخاص ؛ Override محمية void onCreate (Bundle saveInstanceState) {super.onCreate (saveInstanceState)؛ setContentView (R.layout.activity_main)؛ myTextView = findViewById (R.id.textView) ؛ myImageView = findViewById (R.id.imageView) ؛ findViewById (R.id.checkText) .setOnClickListener (هذا)؛ }Override public void onClick (View view) {switch (view.getId ()) {case R.id.checkText: if (myBitmap! = null) {runTextRecog ()؛ } استراحة؛ }}Override محمية void onActivityResult (int requestCode ، int resultCode ، Intent data) {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 (path == null) {myBitmap = MyHelper.resizePhoto (الصورة ، هذا ، dataUri ، myImageView) ؛ } آخر {myBitmap = MyHelper.resizePhoto (الصورة ، المسار ، myImageView) ؛ } if (myBitmap! = null) {myTextView.setText (null)؛ myImageView.setImageBitmap (myBitmap)؛ } استراحة؛ }}} private void runTextRecog () {FirebaseVisionImage image = FirebaseVisionImage.fromBitmap (myBitmap)؛ FirebaseVisionTextDetector detector = FirebaseVision.getInstance (). getVisionTextDetector ()؛ detector.detectInImage (صورة) .addOnSuccessListener (جديد OnSuccessListener() {@ Oververide public void onSuccess (نصوص FirebaseVisionText) {processExtractedText (النصوص)؛ }}). addOnFailureListener (جديد OnFailureListener () {Override public void onFailure (استثناء استثناءNonNull) {Toast.makeText (MainActivity.this، "Exception"، Toast.LENGTH_LONG) .show ()؛}}؛ } عملية باطلة خاصةExtractedText (FirebaseVisionText firebaseVisionText) {myTextView.setText (null)؛ if (firebaseVisionText.getBlocks (). size () == 0) {myTextView.setText (R.string.no_text)؛ إرجاع؛ } for (FirebaseVisionText.Block block: firebaseVisionText.getBlocks ()) {myTextView.append (block.getText ())؛ }}}

اختبار المشروع

حان الوقت الآن لرؤية تطبيق التعرف على النص في ML Kit! قم بتثبيت هذا المشروع على جهاز Android أو AVD ، واختر صورة من المعرض ، ثم اضغط على زر "التحقق من النص". يجب أن يستجيب التطبيق من خلال استخراج كل النص من الصورة ، ثم عرضها في TextView.

لاحظ أنه وفقًا لحجم الصورة ومقدار النص الذي تحتويه ، قد تحتاج إلى التمرير لرؤية النص المستخرج بأكمله.

يمكنك أيضًا تنزيل المشروع المكتمل من جيثب.

تغليف

أنت تعرف الآن كيفية اكتشاف واستخراج النص من صورة ، باستخدام ML Kit.

واجهة برمجة تطبيقات التعرف على النص ليست سوى جزء واحد من ML Kit. يوفر SDK هذا أيضًا مسح الباركود ، والكشف عن الوجوه ، ووضع علامات على الصور والتعرف على المعالم ، مع وجود خطط لإضافة المزيد من واجهات برمجة التطبيقات لحالات استخدام الأجهزة المحمولة الشائعة ، بما في ذلك الرد الذكي وواجهة برمجة التطبيقات عالية الكثافة للوجه.

ما واجهة برمجة تطبيقات ML Kit التي تحبها أكثر شيئ؟ اسمحوا لنا أن نعرف في التعليقات أدناه!

أطلقت Huawei هاتف Nova 5T في ماليزيا في أغسطس. وصل الهاتف الرباعي إلى أوروبا في شهر نوفمبر.هاتف Huawei Nova 5T هو نفس هاتف Honor 20 الذي تم إطلاقه بواسطة علامة Huawei الفرعية في مايو. تشمل أبرز ميزات ...

قد تطلق Huawei نظام التشغيل الخاص بها في أغسطس أو سبتمبر من هذا العام ، وفقًا لصحيفة صينية تصدر باللغة الإنجليزية جلوبال تايمز (عن طريق Indiahopp). وصلت الأخبار في تغريدة في وقت سابق من اليوم عقب تكهن...

شعبية على البوابة