Membuat aplikasi Android untuk pengenalan teks dalam 10 menit. Mobile Vision CodeLab

Versi video tutorial



Optical Character Recognition ( OCR ) memberi komputer kemampuan untuk membaca teks dalam gambar, memungkinkan aplikasi memahami tanda, artikel, selebaran, halaman teks, menu, atau apa pun dalam bentuk teks. Mobile Vision Text API memberi pengembang Android fitur OCR kuat dan andal yang mendukung sebagian besar perangkat Android dan tidak menambah ukuran aplikasi Anda.


Dalam tutorial ini, Anda akan membuat aplikasi di mana semua teks yang jatuh ke dalam bingkai akan dikenali dan diputar selama proses perekaman video.


Kami juga menerbitkan artikel tentang fitur Mobile Vision lainnya:



Kode sumber dapat diunduh di sini .


Atau klon repositori GitHub dari baris perintah:


 $ git clone https://github.com/googlesamples/android-vision.git 

Repositori visionSamples berisi banyak proyek sampel yang terkait dengan Mobile Vision . Hanya dua yang digunakan dalam pelajaran ini:


  • ocr-codelab / ocr-reader-start adalah kode awal yang akan Anda gunakan dalam pelajaran ini.
  • ocr-codelab / ocr-reader-complete - kode lengkap untuk aplikasi yang sudah selesai. Anda dapat menggunakannya untuk memecahkan masalah atau langsung ke aplikasi yang berfungsi.

Pembaruan Layanan Google Play


Anda mungkin perlu meningkatkan versi Google Repository Anda yang terinstal untuk menggunakan Mobile Vision Text API .


Buka Android Studio dan buka SDK Manager :




Pastikan Google Repository terbaru. Setidaknya harus versi 26 .




Tambahkan ketergantungan Layanan Google Play dan buat aplikasi peluncur


Sekarang Anda dapat membuka proyek pemula:


  1. Pilih direktori peluncuran ocr-reader dari kode yang diunduh ( File > Open > ocr-codelab/ocr-reader-start ).


  2. Tambahkan ketergantungan Google Play Services ke aplikasi. Tanpa ketergantungan ini, Text API tidak akan tersedia.



Proyek dapat menunjukkan tidak adanya file integer / google_play_services_version dan memberikan kesalahan. Ini normal, kami akan memperbaikinya pada langkah berikutnya.


Buka file build.gradle di modul app dan ubah blok ketergantungan untuk menyertakan ketergantungan play-services-vision sana. Ketika semuanya sudah siap, file akan terlihat seperti ini:


 dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'com.android.support:support-v4:26.1.0' implementation 'com.android.support:design:26.1.0' implementation 'com.google.android.gms:play-services-vision:15.0.0' } 

  1. Klik Gradle sinkronisasi Gradle .


  2. Klik tombol mulai.



Setelah beberapa detik, Anda akan melihat layar Baca Teks, tetapi ini hanyalah layar hitam.




Tidak ada yang terjadi sekarang karena CameraSource tidak dikonfigurasi. Ayo lakukan.


Jika Anda tidak berhasil, Anda dapat membuka proyek ocr-reader-complete dan pastikan itu berfungsi dengan benar. Proyek ini adalah versi pelajaran yang sudah jadi, dan jika versi ini tidak berfungsi, Anda harus memeriksa apakah semuanya sudah sesuai dengan perangkat Anda dan pengaturan Android Studio .


Konfigurasikan TextRecognizer dan CameraSource


Untuk memulai, kami akan membuat TextRecognizer kami. Objek detektor ini memproses gambar dan menentukan teks apa yang muncul di dalamnya. Setelah inisialisasi, TextRecognizer dapat digunakan untuk mendeteksi teks di semua jenis gambar. Temukan metode createCameraSource dan buat TextRecognizer :


OcrCaptureActivity.java


 private void createCameraSource(boolean autoFocus, boolean useFlash) { Context context = getApplicationContext(); // TODO: Create the TextRecognizer TextRecognizer textRecognizer = new TextRecognizer.Builder(context).build(); // TODO: Set the TextRecognizer's Processor. // TODO: Check if the TextRecognizer is operational. // TODO: Create the mCameraSource using the TextRecognizer. } 

Sekarang TextRecognizer siap TextRecognizer . Namun, mungkin belum berfungsi. Jika perangkat tidak memiliki cukup memori atau Google Play Services tidak dapat memuat dependensi OCR , objek TextRecognizer tidak akan berfungsi. Sebelum kita mulai menggunakannya untuk pengenalan teks, kita harus memverifikasi bahwa itu sudah siap. Kami akan menambahkan cek ini ke createCameraSource setelah menginisialisasi TextRecognizer :


OcrCaptureActivity.java


 // TODO: Check if the TextRecognizer is operational. if (!textRecognizer.isOperational()) { Log.w(TAG, "Detector dependencies are not yet available."); // Check for low storage. If there is low storage, the native library will not be // downloaded, so detection will not become operational. IntentFilter lowstorageFilter = new IntentFilter(Intent.ACTION_DEVICE_STORAGE_LOW); boolean hasLowStorage = registerReceiver(null, lowstorageFilter) != null; if (hasLowStorage) { Toast.makeText(this, R.string.low_storage_error, Toast.LENGTH_LONG).show(); Log.w(TAG, getString(R.string.low_storage_error)); } } 

Sekarang kami telah memverifikasi bahwa TextRecognizer siap digunakan, kami dapat menggunakannya untuk mengenali setiap frame. Tetapi kami ingin melakukan sesuatu yang lebih menarik: membaca teks dalam mode video. Untuk melakukan ini, kami akan membuat CameraSource yang sudah dikonfigurasikan sebelumnya untuk mengontrol kamera. Kita perlu menetapkan resolusi tinggi untuk pemotretan dan mengaktifkan fokus otomatis untuk mengatasi tugas mengenali teks kecil. Jika Anda yakin bahwa pengguna Anda akan melihat blok teks besar, misalnya tanda-tanda, Anda dapat menggunakan resolusi yang lebih rendah, dan kemudian pemrosesan bingkai akan lebih cepat:


OcrCaptureActivity.java


 // TODO: Create the cameraSource using the TextRecognizer. cameraSource = new CameraSource.Builder(getApplicationContext(), textRecognizer) .setFacing(CameraSource.CAMERA_FACING_BACK) .setRequestedPreviewSize(1280, 1024) .setRequestedFps(15.0f) .setFlashMode(useFlash ? Camera.Parameters.FLASH_MODE_TORCH : null) .setFocusMode(autoFocus ? Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO : null) .build(); 

Inilah yang akan terlihat seperti metode createCameraSource ketika Anda selesai:


OcrCaptureActivity.java


 private void createCameraSource(boolean autoFocus, boolean useFlash) { Context context = getApplicationContext(); // Create the TextRecognizer TextRecognizer textRecognizer = new TextRecognizer.Builder(context).build(); // TODO: Set the TextRecognizer's Processor. // Check if the TextRecognizer is operational. if (!textRecognizer.isOperational()) { Log.w(TAG, "Detector dependencies are not yet available."); // Check for low storage. If there is low storage, the native library will not be // downloaded, so detection will not become operational. IntentFilter lowstorageFilter = new IntentFilter(Intent.ACTION_DEVICE_STORAGE_LOW); boolean hasLowStorage = registerReceiver(null, lowstorageFilter) != null; if (hasLowStorage) { Toast.makeText(this, R.string.low_storage_error, Toast.LENGTH_LONG).show(); Log.w(TAG, getString(R.string.low_storage_error)); } } // Create the cameraSource using the TextRecognizer. cameraSource = new CameraSource.Builder(getApplicationContext(), textRecognizer) .setFacing(CameraSource.CAMERA_FACING_BACK) .setRequestedPreviewSize(1280, 1024) .setRequestedFps(15.0f) .setFlashMode(useFlash ? Camera.Parameters.FLASH_MODE_TORCH : null) .setFocusMode(autoFocus ? Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO : null) .build(); } 

Jika Anda menjalankan aplikasi, Anda akan melihat bahwa video telah dimulai! Tetapi untuk memproses gambar dari kamera, kita perlu menambahkan TODO terakhir ini ke createCameraSource : buat Processor untuk memproses teks begitu diterima.


Membuat OcrDetectorProcessor


Aplikasi Anda sekarang dapat mendeteksi teks pada frame individual menggunakan metode penemuan di TextRecognizer . Jadi, Anda dapat menemukan teks, misalnya, di foto. Tetapi untuk dapat membaca teks secara langsung selama perekaman video, Anda perlu mengimplementasikan Processor yang akan memproses teks segera setelah muncul di layar.


Pergi ke kelas OcrDetectorProcessor mengimplementasikan antarmuka Detector.Processor :


OcrDetectorProcessor.java


 public class OcrDetectorProcessor implements Detector.Processor<TextBlock> { private GraphicOverlay<OcrGraphic> graphicOverlay; OcrDetectorProcessor(GraphicOverlay<OcrGraphic> ocrGraphicOverlay) { graphicOverlay = ocrGraphicOverlay; } } 

Untuk mengimplementasikan antarmuka ini, Anda perlu mengganti dua metode. Yang pertama, receiveDetections , menerima TextBlocks dari TextRecognizer saat terdeteksi. Yang kedua, release , digunakan untuk melepaskan sumber daya ketika TextRecognizer dihancurkan. Dalam hal ini, kita hanya perlu menghapus kanvas grafis, yang akan mengarah pada penghapusan semua objek OcrGraphic .


Kami akan mendapatkan TextBlocks dan membuat objek OcrGraphic untuk setiap blok teks yang terdeteksi oleh prosesor. Kami menerapkan logika gambar mereka pada langkah berikutnya.


OcrDetectorProcessor.java


 @Override public void receiveDetections(Detector.Detections<TextBlock> detections) { graphicOverlay.clear(); SparseArray<TextBlock> items = detections.getDetectedItems(); for (int i = 0; i < items.size(); ++i) { TextBlock item = items.valueAt(i); if (item != null && item.getValue() != null) { Log.d("Processor", "Text detected! " + item.getValue()); OcrGraphic graphic = new OcrGraphic(graphicOverlay, item); graphicOverlay.add(graphic); } } } @Override public void release() { graphicOverlay.clear(); } 

Sekarang setelah prosesor siap, kita perlu mengkonfigurasi textRecognizer untuk menggunakannya. Kembali ke TODO tersisa terakhir dalam metode OcrCaptureActivity di OcrCaptureActivity :


OcrCaptureActivity.java


 // Create the TextRecognizer TextRecognizer textRecognizer = new TextRecognizer.Builder(context).build(); // TODO: Set the TextRecognizer's Processor. textRecognizer.setProcessor(new OcrDetectorProcessor(graphicOverlay)); 

Sekarang jalankan aplikasi. Pada titik ini, ketika Anda mengarahkan kamera ke teks, Anda akan melihat pesan debug "Teks terdeteksi!" di Android Monitor Logcat ! Tapi ini bukan cara yang sangat visual untuk memvisualisasikan apa yang dilihat TextRecognizer , kan?


Pada langkah berikutnya, kita akan menggambar teks ini di layar.


Menggambar teks di layar


Mari kita implementasikan metode draw di OcrGraphic . Kita perlu memahami jika ada teks dalam gambar, mengubah koordinat batasnya menjadi bingkai kanvas, dan kemudian menggambar batas dan teks.


OcrGraphic.java


 @Override public void draw(Canvas canvas) { // TODO: Draw the text onto the canvas. if (text == null) { return; } // Draws the bounding box around the TextBlock. RectF rect = new RectF(text.getBoundingBox()); rect = translateRect(rect); canvas.drawRect(rect, rectPaint); // Render the text at the bottom of the box. canvas.drawText(text.getValue(), rect.left, rect.bottom, textPaint); } 

Luncurkan aplikasi dan uji pada teks sampel ini:



Anda akan melihat bahwa sebuah bingkai muncul di layar dengan teks di dalamnya! Anda dapat bermain dengan warna teks menggunakan TEXT_COLOR .


Bagaimana dengan ini?



Bingkai di sekitar teks terlihat benar, tetapi teks ada di bagian bawahnya.




Ini karena mesin mentransfer semua teks yang dikenali di TextBlock sebagai satu kalimat, bahkan jika ia melihat sebuah kalimat dibagi menjadi beberapa baris. Jika Anda perlu mendapatkan seluruh penawaran, maka ini sangat nyaman. Tetapi bagaimana jika Anda ingin tahu di mana setiap baris teks berada?


Anda bisa mendapatkan Lines dari TextBlock dengan memanggil getComponents , dan kemudian, menyortir setiap baris, Anda dapat dengan mudah mendapatkan lokasi dan teks di dalamnya. Ini memungkinkan Anda untuk menggambar teks di tempat teks itu benar-benar muncul.


OcrGraphic.java


 @Override public void draw(Canvas canvas) { // TODO: Draw the text onto the canvas. if (text == null) { return; } // Draws the bounding box around the TextBlock. RectF rect = new RectF(text.getBoundingBox()); rect = translateRect(rect); canvas.drawRect(rect, rectPaint); // Break the text into multiple lines and draw each one according to its own bounding box. List<? extends Text> textComponents = text.getComponents(); for(Text currentText : textComponents) { float left = translateX(currentText.getBoundingBox().left); float bottom = translateY(currentText.getBoundingBox().bottom); canvas.drawText(currentText.getValue(), left, bottom, textPaint); } } 

Coba teks ini lagi:



Hebat! Anda bahkan dapat memecah teks yang ditemukan menjadi komponen yang lebih kecil, berdasarkan kebutuhan Anda. Anda dapat memanggil getComponents di setiap baris dan mendapatkan Elements (kata-kata Latin). Dimungkinkan untuk mengkonfigurasi textSize sehingga teks mengambil ruang sebanyak yang dibutuhkan teks pada layar.




Putar teks saat diklik


Sekarang teks dari kamera diubah menjadi garis terstruktur, dan garis-garis ini ditampilkan di layar. Mari kita lakukan sesuatu yang lain dengan mereka.


Menggunakan TextToSpeech API dibangun di Android dan metode contains dalam OcrGraphic , kita dapat mengajarkan aplikasi untuk berbicara dengan suara keras ketika Anda mengklik teks.


Pertama, mari kita implementasikan metode contains dalam OcrGraphic . Kita hanya perlu memeriksa apakah koordinat x dan y berada dalam batas teks yang ditampilkan.
OcrGraphic.java


 public boolean contains(float x, float y) { // TODO: Check if this graphic's text contains this point. if (text == null) { return false; } RectF rect = new RectF(text.getBoundingBox()); rect = translateRect(rect); return rect.contans(x, y); } 

Anda mungkin memperhatikan bahwa ada banyak kesamaan dengan metode Draw ! Dalam proyek ini, Anda harus dapat menggunakan kembali kode tersebut, tetapi di sini kami meninggalkan semuanya karena hanya untuk contoh saja.


Sekarang mari kita beralih ke metode OcrCaptureActivity di OcrCaptureActivity dan proses klik pada teks, jika ada di tempat ini.


OcrCaptureActivity.java


 private boolean onTap(float rawX, float rawY) { // TODO: Speak the text when the user taps on screen. OcrGraphic graphic = graphicOverlay.getGraphicAtLocation(rawX, rawY); TextBlock text = null; if (graphic != null) { text = graphic.getTextBlock(); if (text != null && text.getValue() != null) { Log.d(TAG, "text data is being spoken! " + text.getValue()); // TODO: Speak the string. } else { Log.d(TAG, "text data is null"); } } else { Log.d(TAG,"no text detected"); } return text != null; } 

Anda dapat menjalankan aplikasi dan memastikan bahwa mengklik teks sebenarnya sedang diproses melalui Android Monitor Logcat .


Mari kita buat aplikasi kita bicara! Buka awal Activity dan temukan metode onCreate . Saat memulai aplikasi, kita harus menginisialisasi mesin TextToSpeech untuk penggunaan di masa mendatang.


OcrCaptureActivity.java


 @Override public void onCreate(Bundle bundle) { // (Portions of this method omitted) // TODO: Set up the Text To Speech engine. TextToSpeech.OnInitListener listener = new TextToSpeech.OnInitListener() { @Override public void onInit(final int status) { if (status == TextToSpeech.SUCCESS) { Log.d("TTS", "Text to speech engine started successfully."); tts.setLanguage(Locale.US); } else { Log.d("TTS", "Error starting the text to speech engine."); } } }; tts = new TextToSpeech(this.getApplicationContext(), listener); } 

Terlepas dari kenyataan bahwa kami menginisialisasi TextToSpeech dengan benar, sebagai aturan, Anda masih harus menangani kesalahan umum, misalnya, saat mesin masih belum siap saat pertama kali Anda mengklik teks tersebut.


TextToSpeech juga tergantung pada bahasa. Anda dapat mengubah bahasa berdasarkan bahasa teks yang dikenali. Pengenalan bahasa tidak dimasukkan ke dalam Mobile Vision Text API , tetapi tersedia melalui Google Translate API . Sebagai bahasa untuk mengenali teks, Anda dapat menggunakan bahasa perangkat pengguna.


Hebat, yang tersisa adalah menambahkan kode pemutaran teks dalam metode onTap .


OcrCaptureActivity.java


 private boolean onTap(float rawX, float rawY) { // TODO: Speak the text when the user taps on screen. OcrGraphic graphic = graphicOverlay.getGraphicAtLocation(rawX, rawY); TextBlock text = null; if (graphic != null) { text = graphic.getTextBlock(); if (text != null && text.getValue() != null) { Log.d(TAG, "text data is being spoken! " + text.getValue()); // Speak the string. tts.speak(text.getValue(), TextToSpeech.QUEUE_ADD, null, "DEFAULT"); } else { Log.d(TAG, "text data is null"); } } else { Log.d(TAG,"no text detected"); } return text != null; } 

Sekarang, ketika Anda memulai aplikasi dan mengklik teks yang terdeteksi, perangkat Anda akan memainkannya. Cobalah!


Penyelesaian


Sekarang Anda memiliki aplikasi yang dapat mengenali teks dari kamera dan mengucapkannya dengan lantang!


Anda dapat menerapkan pengetahuan yang diperoleh tentang pengenalan teks di aplikasi Anda yang lain. Misalnya, baca alamat dan nomor telepon dari kartu bisnis, cari teks dari foto-foto berbagai dokumen. Singkatnya, gunakan OCR mana pun Anda mungkin perlu mengenali teks dalam suatu gambar.


Sumber

Source: https://habr.com/ru/post/id412679/


All Articles