Création d'une application Android pour la reconnaissance de texte en 10 minutes. Mobile Vision CodeLab

Version vidéo du tutoriel



La reconnaissance optique de caractères ( OCR ) offre à l'ordinateur la possibilité de lire du texte dans une image, permettant aux applications de comprendre les signes, les articles, les dépliants, les pages de texte, les menus ou tout autre élément sous forme de texte. Mobile Vision Text API fournit aux développeurs Android une fonction OCR puissante et fiable qui prend en charge la plupart Android appareils Android et n'augmente pas la taille de votre application.


Dans ce didacticiel, vous allez créer une application dans laquelle tout le texte tombant dans le cadre sera reconnu et lu pendant le processus d'enregistrement vidéo.


Nous avons également publié des articles sur d'autres fonctionnalités de Mobile Vision:



Le code source peut être téléchargé ici .


Ou clonez le référentiel GitHub partir de la ligne de commande:


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

Le référentiel visionSamples contient de nombreux exemples de projets liés à Mobile Vision . Seuls deux sont utilisés dans cette leçon:


  • ocr-codelab / ocr-reader-start est le code initial que vous utiliserez dans cette leçon.
  • ocr-codelab / ocr-reader-complete - le code complet pour l'application terminée. Vous pouvez l'utiliser pour dépanner ou aller directement à l'application de travail.

Mise à jour des services Google Play


Vous devrez peut-être mettre à niveau votre version installée de Google Repository pour utiliser l' Mobile Vision Text API .


Ouvrez Android Studio et ouvrez le SDK Manager :




Assurez-vous que le Google Repository jour. Ce doit être au moins la version 26 .




Ajouter une dépendance aux services Google Play et créer une application de lancement


Vous pouvez maintenant ouvrir le projet de démarrage:


  1. Choisissez un répertoire de lancement ocr-reader partir du code téléchargé ( Fichier > Ouvrir > ocr-codelab/ocr-reader-start ).


  2. Ajoutez la dépendance des Google Play Services à l'application. Sans cette dépendance, l' Text API ne sera pas disponible.



Le projet peut indiquer l'absence du fichier entier / google_play_services_version et donner une erreur. C'est normal, nous le corrigerons à l'étape suivante.


Ouvrez le fichier build.gradle dans le module d' app et modifiez le bloc de dépendance pour y inclure la dépendance play-services-vision . Lorsque tout est prêt, le fichier devrait ressembler à ceci:


 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. Cliquez sur Bouton de synchronisation Gradle .


  2. Cliquez sur bouton de démarrage.



Après quelques secondes, vous verrez l'écran Lire le texte, mais ce n'est qu'un écran noir.




Rien ne se passe actuellement car CameraSource pas configuré. Faisons-le.


Si vous ne réussissez pas, vous pouvez ouvrir un projet ocr-reader-complete et assurez-vous qu'il fonctionne correctement. Ce projet est une version prête à l'emploi de la leçon, et si cette version ne fonctionne pas, vous devez vérifier que tout est en ordre avec votre appareil et Android Studio paramètres d' Android Studio .


Configurer TextRecognizer et CameraSource


Pour commencer, nous allons créer notre TextRecognizer . Cet objet détecteur traite les images et détermine le texte qui apparaît à l'intérieur. Après l'initialisation, TextRecognizer peut être utilisé pour détecter du texte dans tous les types d'images. Recherchez la méthode createCameraSource et créez un 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. } 

TextRecognizer maintenant prêt à TextRecognizer . Cependant, il se peut que cela ne fonctionne pas encore. Si l'appareil ne dispose pas de suffisamment de mémoire ou si Google Play Services ne peuvent pas charger les dépendances OCR , l'objet TextRecognizer ne fonctionnera pas. Avant de commencer à l'utiliser pour la reconnaissance de texte, nous devons vérifier qu'il est prêt. Nous ajouterons cette vérification à createCameraSource après avoir initialisé 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)); } } 

Maintenant que nous avons vérifié que TextRecognizer prêt à l'emploi, nous pouvons l'utiliser pour reconnaître des cadres individuels. Mais nous voulons faire quelque chose de plus intéressant: lire le texte en mode vidéo. Pour ce faire, nous allons créer une CameraSource pré-configurée pour contrôler la caméra. Nous devons définir une haute résolution pour la prise de vue et activer la mise au point automatique pour faire face à la tâche de reconnaissance des petits textes. Si vous êtes sûr que vos utilisateurs regarderont de gros blocs de texte, par exemple des signes, vous pouvez utiliser une résolution inférieure, puis le traitement des cadres sera plus rapide:


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(); 

Voici à quoi devrait ressembler la méthode createCameraSource :


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(); } 

Si vous exécutez l'application, vous verrez que la vidéo a commencé! Mais pour traiter les images de la caméra, nous devons ajouter ce dernier TODO à createCameraSource : créer un Processor pour traiter le texte à son arrivée.


Création de OcrDetectorProcessor


Votre application peut désormais détecter du texte sur des cadres individuels à l'aide de la méthode de découverte de TextRecognizer . Ainsi, vous pouvez trouver du texte, par exemple, sur une photo. Mais pour lire le texte directement pendant l'enregistrement vidéo, vous devez implémenter un Processor qui traitera le texte dès qu'il apparaîtra à l'écran.


Accédez à la classe OcrDetectorProcessor implémentez l'interface Detector.Processor :


OcrDetectorProcessor.java


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

Pour implémenter cette interface, vous devez remplacer deux méthodes. Le premier, receiveDetections , reçoit les TextBlocks de TextRecognizer lorsqu'ils sont détectés. La seconde, release , est utilisée pour libérer des ressources lorsqu'un TextRecognizer détruit. Dans ce cas, il suffit d'effacer le canevas graphique, ce qui entraînera la suppression de tous les objets OcrGraphic .


Nous obtiendrons TextBlocks et OcrGraphic objets OcrGraphic pour chaque bloc de texte détecté par le processeur. Nous implémentons la logique de leur dessin dans l'étape suivante.


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(); } 

Maintenant que le processeur est prêt, nous devons configurer textRecognizer pour l'utiliser. Revenez au dernier TODO restant dans la méthode OcrCaptureActivity dans OcrCaptureActivity :


OcrCaptureActivity.java


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

Exécutez maintenant l'application. À ce stade, lorsque vous passez la caméra sur du texte, vous verrez les messages de débogage "Texte détecté!" dans Android Monitor Logcat ! Mais ce n'est pas une façon très visuelle de visualiser ce que TextRecognizer voit, non?


Dans l'étape suivante, nous allons dessiner ce texte à l'écran.


Dessin de texte à l'écran


OcrGraphic méthode draw dans OcrGraphic . Nous devons comprendre s'il y a du texte dans l'image, convertir les coordonnées de ses bordures en cadres de toile, puis dessiner à la fois les bordures et le texte.


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); } 

Lancez l'application et testez-la sur cet exemple de texte:



Vous devriez voir qu'un cadre apparaît à l'écran avec du texte dedans! Vous pouvez jouer avec la couleur du texte en utilisant TEXT_COLOR .


Et ça?



Le cadre autour du texte semble correct, mais le texte est en bas.




En effet, le moteur transfère tout le texte qu'il reconnaît dans le TextBlock comme une seule phrase, même s'il voit une phrase divisée en plusieurs lignes. Si vous avez besoin d'obtenir toute l'offre, c'est très pratique. Mais que faire si vous voulez savoir où se trouve chaque ligne de texte individuelle?


Vous pouvez obtenir des Lines partir d'un TextBlock en appelant getComponents , puis, en triant chaque ligne, vous pouvez facilement obtenir son emplacement et le texte qu'il getComponents . Cela vous permet de dessiner du texte à l'endroit où il apparaît réellement.


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); } } 

Essayez à nouveau ce texte:



Super! Vous pouvez même diviser le texte trouvé en composants encore plus petits, en fonction de vos besoins. Vous pouvez appeler getComponents sur chaque ligne et obtenir des Elements (mots latins). Il est possible de configurer textSize sorte que le texte occupe autant d'espace que le texte réel à l'écran.




Lire du texte lorsque vous cliquez dessus


Maintenant, le texte de la caméra est converti en lignes structurées et ces lignes s'affichent à l'écran. Faisons autre chose avec eux.


En utilisant l' TextToSpeech API intégrée à Android et la méthode OcrGraphic dans OcrGraphic , nous pouvons apprendre à l'application à parler à voix haute lorsque vous cliquez sur le texte.


Tout d'abord, implémentons la méthode OcrGraphic dans OcrGraphic . Nous avons juste besoin de vérifier si les coordonnées x et y sont dans les limites du texte affiché.
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); } 

Vous remarquerez peut-être qu'il y a beaucoup en commun avec la méthode Draw ! Dans ce projet, vous devriez être en mesure de réutiliser le code, mais ici, nous laissons tout comme pour le simple exemple.


Passons maintenant à la méthode onTap dans OcrCaptureActivity et traitons le clic sur le texte, s'il y en a un à cet endroit.


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; } 

Vous pouvez exécuter l'application et vous assurer que cliquer sur le texte est réellement traité via Android Monitor Logcat .


Faisons parler notre application! Allez au début de l' Activity et trouvez la méthode onCreate . Lors du démarrage de l'application, nous devons initialiser le moteur TextToSpeech pour une utilisation future.


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); } 

Malgré le fait que nous ayons correctement initialisé TextToSpeech , en règle générale, vous devez toujours gérer les erreurs générales, par exemple, lorsque le moteur n'est toujours pas prêt la première fois que vous cliquez sur le texte.


TextToSpeech également de la langue. Vous pouvez changer la langue en fonction de la langue du texte reconnu. La reconnaissance de la langue n'est pas intégrée à l' Mobile Vision Text API , mais elle est disponible via l' Google Translate API . En tant que langue pour la reconnaissance de texte, vous pouvez utiliser la langue de la machine utilisateur.


onTap bien, il ne reste plus qu'à ajouter le code de lecture de texte dans la méthode 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; } 

Maintenant, lorsque vous démarrez l'application et cliquez sur le texte détecté, votre appareil le lira. Essayez-le!


Achèvement


Maintenant, vous avez une application qui peut reconnaître le texte de la caméra et le parler à haute voix!


Vous pouvez appliquer les connaissances acquises de la reconnaissance de texte dans vos autres applications. Par exemple, lisez les adresses et les numéros de téléphone des cartes de visite, recherchez le texte des photographies de divers documents. En bref, utilisez l' OCR partout où vous pouvez avoir besoin de reconnaître du texte dans une image.


Source

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


All Articles