Criando um aplicativo Android para reconhecimento de texto em 10 minutos. Mobile Vision CodeLab

Versão em vídeo do tutorial



O reconhecimento óptico de caracteres ( OCR ) fornece ao computador a capacidade de ler texto em uma imagem, permitindo que os aplicativos compreendam sinais, artigos, folhetos, páginas de texto, menus ou qualquer coisa na forma de texto. Mobile Vision Text API fornece aos desenvolvedores do Android um recurso OCR poderoso e confiável que suporta a maioria dos dispositivos Android e não aumenta o tamanho do seu aplicativo.


Neste tutorial, você criará um aplicativo no qual todo o texto que cai no quadro será reconhecido e reproduzido durante o processo de gravação de vídeo.


Também publicamos artigos sobre outros recursos do Mobile Vision:



O código-fonte pode ser baixado aqui .


Ou clone o repositório GitHub na linha de comando:


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

O repositório visionSamples contém muitos projetos de amostra relacionados ao Mobile Vision . Apenas dois são usados ​​nesta lição:


  • ocr-codelab / ocr-reader-start é o código inicial que você usará nesta lição.
  • ocr-codelab / ocr-reader-complete - o código completo para o aplicativo finalizado. Você pode usá-lo para solucionar problemas ou ir diretamente para o aplicativo em funcionamento.

Atualização dos serviços do Google Play


Pode ser necessário atualizar a versão instalada do Google Repository para usar a Mobile Vision Text API do Mobile Vision Text API .


Abra o Android Studio e abra o SDK Manager :




Verifique se o Google Repository do Google Repository atualizado. Deve ser pelo menos a versão 26 .




Adicione uma dependência dos Serviços do Google Play e crie um aplicativo iniciador


Agora você pode abrir o projeto inicial:


  1. Escolha um diretório de inicialização ocr-reader partir do código baixado ( Arquivo > Abrir > ocr-codelab/ocr-reader-start ).


  2. Adicione a dependência do Google Play Services ao aplicativo. Sem essa dependência, a Text API não estará disponível.



O projeto pode indicar a ausência do arquivo inteiro / google_play_services_version e cometer um erro. Isso é normal, vamos corrigi-lo na próxima etapa.


Abra o arquivo build.gradle no módulo do app e altere o bloco de dependência para incluir a dependência play-services-vision nele. Quando tudo estiver pronto, o arquivo deve ficar assim:


 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. Clique em Botão de sincronização Gradle .


  2. Clique em botão iniciar.



Após alguns segundos, você verá a tela Ler texto, mas esta é apenas uma tela preta.




Nada está acontecendo agora, porque o CameraSource não CameraSource configurado. Vamos fazer isso.


Se você não conseguir, pode abrir um projeto ocr-reader-complete e verifique se ele funciona corretamente. Este projeto é uma versão pronta da lição e, se essa versão não funcionar, verifique se tudo está em ordem com o dispositivo e as configurações do Android Studio .


Configurar TextRecognizer e CameraSource


Para começar, criaremos nosso TextRecognizer . Este objeto detector processa as imagens e determina qual texto aparece dentro delas. Após a inicialização, o TextRecognizer pode ser usado para detectar texto em todos os tipos de imagens. Encontre o método createCameraSource e crie um 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. } 

Agora o TextRecognizer pronto para TextRecognizer . No entanto, pode não estar funcionando ainda. Se o dispositivo não tiver memória suficiente ou o Google Play Services não puder carregar dependências de OCR , o objeto TextRecognizer não funcionará. Antes de começarmos a usá-lo para reconhecimento de texto, devemos verificar se está pronto. Adicionaremos essa verificação para createCameraSource após a inicialização do 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)); } } 

Agora que verificamos que o TextRecognizer pronto para uso, podemos usá-lo para reconhecer quadros individuais. Mas queremos fazer algo mais interessante: leia o texto no modo de vídeo. Para fazer isso, criaremos um CameraSource pré-configurado para controlar a câmera. Precisamos definir uma alta resolução para fotografar e habilitar o foco automático para lidar com a tarefa de reconhecer texto pequeno. Se você tiver certeza de que seus usuários examinarão grandes blocos de texto, por exemplo, sinais, poderá usar uma resolução mais baixa e o processamento de quadros será mais rápido:


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

Aqui está a createCameraSource método createCameraSource quando terminar:


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

Se você executar o aplicativo, verá que o vídeo foi iniciado! Mas, para processar imagens da câmera, precisamos adicionar este último TODO para createCameraSource : criar um Processor para processar o texto à medida que ele chega.


Criando OcrDetectorProcessor


Seu aplicativo agora pode detectar texto em quadros individuais usando o método de descoberta no TextRecognizer . Assim, você pode encontrar texto, por exemplo, em uma fotografia. Mas, para ler o texto diretamente durante a gravação de vídeo, você precisa implementar um Processor que processará o texto assim que ele aparecer na tela.


Vá para a classe OcrDetectorProcessor implemente a interface Detector.Processor :


OcrDetectorProcessor.java


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

Para implementar essa interface, você precisa substituir dois métodos. O primeiro, receiveDetections , recebe TextBlocks do TextRecognizer medida que são detectados. O segundo, release , é usado para liberar recursos quando um TextRecognizer destruído. Nesse caso, precisamos apenas limpar a tela gráfica, o que levará à exclusão de todos os objetos OcrGraphic .


OcrGraphic TextBlocks e OcrGraphic objetos OcrGraphic para cada bloco de texto detectado pelo processador. Implementamos a lógica de seu desenho na próxima etapa.


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

Agora que o processador está pronto, precisamos configurar o textRecognizer para usá-lo. Retorne ao último TODO restante no método OcrCaptureActivity em OcrCaptureActivity :


OcrCaptureActivity.java


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

Agora execute o aplicativo. Nesse ponto, quando você passa a câmera sobre o texto, você verá as mensagens de depuração "Texto detectado!" no Android Monitor Logcat ! Mas essa não é uma maneira muito visual de visualizar o que o TextRecognizer vê, certo?


Na próxima etapa, desenharemos esse texto na tela.


Desenho de texto na tela


Vamos implementar o método draw em OcrGraphic . Precisamos entender se há texto na imagem, converter as coordenadas de suas bordas em quadros de tela e desenhar as bordas e o texto.


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

Inicie o aplicativo e teste-o neste texto de exemplo:



Você deve ver que um quadro aparece na tela com texto! Você pode brincar com a cor do texto usando TEXT_COLOR .


Que tal isso?



O quadro ao redor do texto parece correto, mas o texto está na parte inferior.




Isso ocorre porque o mecanismo transfere todo o texto que ele reconhece no TextBlock como uma única frase, mesmo que veja uma frase dividida em várias linhas. Se você precisar obter toda a oferta, isso é muito conveniente. Mas e se você quiser saber onde cada linha de texto está localizada?


Você pode obter Lines de um TextBlock chamando getComponents e, classificando cada linha, pode facilmente obter sua localização e o texto dentro dela. Isso permite desenhar texto no local onde ele realmente aparece.


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

Tente este texto novamente:



Ótimo! Você pode até dividir o texto encontrado em componentes ainda menores, com base em suas necessidades. Você pode chamar getComponents em cada linha e obter Elements (palavras latinas). É possível configurar o textSize para que o texto textSize tanto espaço quanto o texto real na tela.




Reproduzir texto quando clicado nele


Agora, o texto da câmera é convertido em linhas estruturadas e essas linhas são exibidas na tela. Vamos fazer outra coisa com eles.


Usando a TextToSpeech API embutida no Android e o método contains em OcrGraphic , podemos ensinar o aplicativo a falar em voz alta quando você clica no texto.


Primeiro, vamos implementar o método contains em OcrGraphic . Só precisamos verificar se as coordenadas y estão dentro dos limites do texto exibido.
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); } 

Você pode perceber que há muito em comum com o método Draw ! Neste projeto, você deve poder reutilizar o código, mas aqui deixamos tudo como é apenas por uma questão de exemplo.


Agora, vamos seguir para o método onTap em OcrCaptureActivity e processar o clique no texto, se houver um nesse local.


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

Você pode executar o aplicativo e garantir que o clique no texto esteja sendo processado pelo Android Monitor Logcat .


Vamos fazer nosso aplicativo falar! Vá para o início da Activity e encontre o método onCreate . Ao iniciar o aplicativo, precisamos inicializar o mecanismo TextToSpeech para uso futuro.


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

Apesar de termos iniciado corretamente o TextToSpeech , como regra, você ainda precisa lidar com erros gerais, por exemplo, quando o mecanismo ainda não está pronto na primeira vez em que você clica no texto.


TextToSpeech também depende do idioma. Você pode alterar o idioma com base no idioma do texto reconhecido. O reconhecimento de idiomas não está incorporado na Mobile Vision Text API do Mobile Vision Text API , mas está disponível na Google Translate API do Google Translate API . Como idioma para reconhecimento de texto, você pode usar o idioma do dispositivo do usuário.


Ótimo, tudo o que resta é adicionar o código de reprodução de texto no método 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; } 

Agora, quando você inicia o aplicativo e clica no texto detectado, seu dispositivo o reproduz. Experimente!


Conclusão


Agora você tem um aplicativo que pode reconhecer texto da câmera e falar em voz alta!


Você pode aplicar o conhecimento adquirido de reconhecimento de texto em seus outros aplicativos. Por exemplo, leia endereços e números de telefone de cartões de visita, pesquise o texto de fotografias de vários documentos. Em resumo, use o OCR sempre que precisar reconhecer o texto em uma imagem.


Fonte

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


All Articles