Detectar objetos em imagens com o kit de ML: Android

1. Antes de começar

O Kit de ML é um SDK para dispositivos móveis que leva a experiência em aprendizado de máquina do Google para apps Android e iOS. Você pode usar as APIs Vision e Natural Language, mas elas são simples e eficientes, para resolver desafios comuns nos apps ou criar novas experiências do usuário. Todos usam os melhores modelos de ML do Google e são oferecidos sem custos financeiros.

Todas as APIs do Kit de ML são executadas no dispositivo, o que permite casos de uso em tempo real em que você quer processar um stream da câmera ao vivo, por exemplo. Isso também significa que a funcionalidade está disponível off-line.

Este codelab mostrará etapas simples para adicionar a detecção e o rastreamento de objetos (ODT, na sigla em inglês) de uma determinada imagem ao seu app Android. Este codelab usa alguns atalhos para destacar o uso de ODT do kit de ML.

O que você criará

Neste codelab, você criará um app Android com o kit de ML. Seu app usará a API de rastreamento e detecção de objetos do Kit de ML para detectar objetos em uma determinada imagem.No final, você verá algo semelhante à imagem à direita.

O que você aprenderá

  • Como integrar o SDK do Kit de ML ao seu app Android.
  • API ML Kit Object Detection and Tracking

Pré-requisitos

  • Uma versão recente do Android Studio (v4.1.2 ou mais recente)
  • Android Studio Emulator ou um dispositivo Android físico
  • Código de amostra
  • Conhecimento básico de desenvolvimento Android no Kotlin.

Este codelab é focado no kit de ML. Conceitos não-relevantes e blocos de código são citados rapidamente e fornecidos para que você simplesmente os copie e cole.

2. Começar a configuração

Fazer o download do código

Clique no link abaixo para fazer o download de todo o código para este codelab:

Descompacte o arquivo ZIP transferido por download. Isso descompactará uma pasta raiz (mlkit-android-main) com todos os recursos necessários. Neste codelab, você só precisará das origens no subdiretório object-detection.

O subdiretório de detecção de objetos no repositório mlkit-android contém dois diretórios:

  • android_studio_folder.pngstarter: o código inicial que você usará como base para este codelab.
  • android_studio_folder.pngfinal: o código concluído do app de exemplo finalizado.

3. Adicionar a API Object Detection e Tracking do ML ao projeto

Importar o app para o Android Studio

Vamos começar importando o app inicial para o Android Studio.

Abra o Android Studio, selecione Import Project (Gradle, Eclipse ADT, etc.) e escolha a pasta starter no código-fonte que você já baixou.

7c0f27882a2698ac.png

Adicionar as dependências da detecção e do rastreamento do objeto do Kit de ML

As dependências do kit de ML permitem que você integre o SDK do kit de ML ODT ao seu app. Adicione as seguintes linhas no fim do arquivo app/build.gradle do projeto:

build.gradle

dependencies {
  // ...
  implementation 'com.google.mlkit:object-detection:16.2.4'
}

Sincronizar seu projeto com arquivos do Gradle

Para garantir que todas as dependências estejam disponíveis para seu app, nesse ponto, você deve sincronizar seu projeto com arquivos do Gradle.

Selecione Sync Project with Gradle Files ( b451ab2d04d835f9.png) na barra de ferramentas do Android Studio.

Se esse botão estiver desativado, importe apenasstarter/app/build.gradle , não o repositório inteiro.

4. Executar o app inicial

Agora que você importou o projeto para o Android Studio e adicionou as dependências para detecção e rastreamento de objetos do Kit de ML, está pronto para executar o app pela primeira vez.

Conecte o dispositivo Android via USB ao seu host ou Iniciar o Android Studio e clique em Run ( execute.png) na barra de ferramentas do Android Studio.

Executar e conhecer o app

O app será aberto no dispositivo Android. Ele tem um código boilerplate que permite capturar uma foto ou selecionar uma imagem predefinida e a alimentar em um pipeline de detecção e rastreamento de objetos que será criado neste codelab. Vamos explorar o app um pouco antes de escrever código.

Primeiro, há um Button ( c6d965d639c3646.png) na parte inferior para:

  • Abra o app Câmera integrado no seu dispositivo/emulador
  • tire uma foto no app de câmera
  • receber a imagem capturada no app inicial
  • exibir a imagem

Teste o botão Tirar foto, siga as instruções para tirar uma foto, aceite-a e observe-a exibida no app inicial..

Repita algumas vezes para ver como funciona:

9ec541980dbe2d31.png. 8312dde41425ba4b.png fa8492bfc1914ff0.png.

Há também três imagens predefinidas que você pode escolher. É possível usar essas imagens mais tarde para testar o código de detecção de objetos se você estiver executando em um Android Emulator.

Selecione uma das três imagens predefinidas. Veja que a imagem é exibida em uma visualização maior:

1dd41b3ec978f1d9.png

5. Adicionar detecção de objetos no dispositivo

Nesta etapa, você adicionará a funcionalidade ao app inicial para detectar objetos em imagens. Como você viu na etapa anterior, o app inicial contém um código boilerplate para tirar fotos com o app de câmera do dispositivo. Há também três imagens predefinidas no app que podem ser usadas para detecção de objetos se você estiver executando o codelab em um Android Emulator.

Quando você selecionar uma imagem, seja das imagens predefinidas ou tirar uma foto com o app Câmera, o código boilerplate a decodificará para uma instância Bitmap, a mostrará na tela e chamará o método runObjectDetection com a imagem.

Nesta etapa, você adicionará um código ao método runObjectDetection para fazer a detecção de objetos.

Configurar e executar a detecção de objetos no dispositivo em uma imagem

Você só precisa de três etapas simples com três APIs para configurar o ODT do kit de ML:

  • preparar uma imagem: InputImage
  • crie um objeto detector: ObjectDetection.getClient(options)
  • Conecte os dois objetos acima: process(image)

Isso é feito dentro da função runObjectDetection(bitmap: Bitmap) no arquivo MainActivity.kt.

/**
 * ML Kit Object Detection Function
 */
private fun runObjectDetection(bitmap: Bitmap) {
}

No momento, a função está vazia. Avance para as etapas a seguir para implementar a ODT do kit de ML. O Android Studio solicitará que você adicione as importações necessárias:

  • com.google.mlkit.vision.common.InputImage
  • com.google.mlkit.vision.objects.ObjectDetection
  • com.google.mlkit.vision.objects.defaults.ObjectDetectorOptions

Etapa 1: criar uma InputImage

O Kit de ML fornece uma API simples para criar um InputImage usando um Bitmap. Em seguida, é possível alimentar um InputImage nas APIs do Kit de ML.

// Step 1: create ML Kit's InputImage object
val image = InputImage.fromBitmap(bitmap, 0)

Adicione o código acima à parte superior do runObjectDetection(bitmap:Bitmap).

Etapa 2: criar uma instância de detector

O kit de ML segue o Builder Design Pattern. Você transmitirá a configuração para o builder e, em seguida, receberá um detector dele. Há três opções de configuração (as opções em negrito são usadas neste codelab):

  • modo do detector (imagem única ou stream)
  • modo de detecção (uma ou várias detecção de objetos)
  • modo de classificação (ativado ou desativado)

Este codelab é para imagem única: detecção e classificação de vários objetos. Adicione isso agora:

// Step 2: acquire detector object
val options = ObjectDetectorOptions.Builder()
   .setDetectorMode(ObjectDetectorOptions.SINGLE_IMAGE_MODE)
   .enableMultipleObjects()
   .enableClassification()
   .build()
val objectDetector = ObjectDetection.getClient(options)

Etapa 3: enviar imagens para o detector

A detecção e classificação de objetos é um processamento assíncrono:

  • Você envia uma imagem para o detector via process().
  • O detector está muito difícil.
  • O detector informa o resultado de volta para você por um callback.

O código a seguir faz isso (copie e anexe o código existente ao fun runObjectDetection(bitmap:Bitmap)):)

// Step 3: feed given image to detector and setup callback
objectDetector.process(image)
   .addOnSuccessListener {
       // Task completed successfully
        debugPrint(it)
   }
   .addOnFailureListener {
       // Task failed with an exception
       Log.e(TAG, it.message.toString())
   }

Após a conclusão, o detector notificará você com:

  • O número total de objetos detectados. Cada objeto detectado é descrito com:
  • trackingId: um número inteiro que você usa para rastreá-lo em vários frames (NÃO usado neste codelab).
  • boundingBox: a caixa delimitadora do objeto.
  • labels: exibe uma lista de rótulos para o objeto detectado (somente quando a classificação está ativada):
  • index: veja o índice desse rótulo.
  • text (Encontre o texto deste rótulo, incluindo "Moda", "Comida", "Produtos domésticos", "Lugar", "Planta")
  • confidence ( uma vírgula entre 0,0 e 1,0 com 1,0 significa 100%)

Você provavelmente percebeu que o código faz um tipo de processamento de impressão do resultado detectado com debugPrint().

Adicione-o à classe MainActivity:

private fun debugPrint(detectedObjects: List<DetectedObject>) {
   detectedObjects.forEachIndexed { index, detectedObject ->
       val box = detectedObject.boundingBox

       Log.d(TAG, "Detected object: $index")
       Log.d(TAG, " trackingId: ${detectedObject.trackingId}")
       Log.d(TAG, " boundingBox: (${box.left}, ${box.top}) - (${box.right},${box.bottom})")
       detectedObject.labels.forEach {
           Log.d(TAG, " categories: ${it.text}")
           Log.d(TAG, " confidence: ${it.confidence}")
       }
   }
}

Agora você já pode aceitar imagens para detecção.

Para executar o codelab, clique em Run ( execute.png) na barra de ferramentas do Android Studio. Tente selecionar uma imagem predefinida ou tire uma foto e olhe a janela do logcat(16bd6ea224cf8cf1.png.) no ambiente de desenvolvimento integrado.

Você verá algo como:

D/MLKit Object Detection: Detected object: 0
D/MLKit Object Detection:  trackingId: null
D/MLKit Object Detection:  boundingBox: (481, 2021) - (2426,3376)
D/MLKit Object Detection:  categories: Food
D/MLKit Object Detection:  confidence: 0.90234375
D/MLKit Object Detection: Detected object: 1
D/MLKit Object Detection:  trackingId: null
D/MLKit Object Detection:  boundingBox: (2639, 2633) - (3058,3577)
D/MLKit Object Detection: Detected object: 2
D/MLKit Object Detection:  trackingId: null
D/MLKit Object Detection:  boundingBox: (3, 1816) - (615,2597)
D/MLKit Object Detection:  categories: Home good
D/MLKit Object Detection:  confidence: 0.75390625

...o que significa que o detector viu três objetos:

  • As categorias são Comida e Boa casa.
  • Nenhuma categoria foi retornada para a segunda porque é uma classe desconhecida.
  • Não há trackingId, porque esse é o modo de detecção de imagem única.
  • A posição dentro do retângulo boundingBox (por exemplo, (481, 2021) (2426, 3376))
  • O detector tem certeza de que o primeiro é Alimentação (90% de confiança, era salada).

Tecnicamente, isso é tudo o que você precisa para que a detecção de objetos do Kit de ML funcione. Você tem tudo isso neste momento. Parabéns!

No lado da IU, você ainda está no estágio inicial, mas pode usar os resultados detectados na IU, como desenhar a caixa delimitadora para criar uma experiência melhor. Vamos para a próxima etapa: pós-processamento os resultados detectados.

6. Pós-processamento dos resultados da detecção

Nas etapas anteriores, você exibe o resultado detectado no logcat: simples e rápido.

Nesta seção, você usará o resultado na imagem:

  • desenhar a caixa delimitadora na imagem
  • desenhar o nome da categoria e a confiança na caixa delimitadora

Entender os utilitários de visualização

Há um código boilerplate no codelab para ajudar você a visualizar o resultado da detecção. Use estes utilitários para simplificar o código de visualização:

  • data class BoxWithText(val box: Rect, val text: String) Essa é uma classe de dados para armazenar um resultado de detecção de objetos para visualização. box é a caixa delimitadora onde o objeto localiza, e text é a string de resultado de detecção a ser exibida com a caixa delimitadora do objeto.
  • fun drawDetectionResult(bitmap: Bitmap, detectionResults: List<BoxWithText>): Bitmap Esse método exibe os resultados da detecção de objetos no detectionResults na entrada bitmap e retorna a cópia modificada dele.

Veja um exemplo de saída do método utilitário drawDetectionResult:

58c6f1d4ddb00dfa.png

Visualizar o resultado da detecção do kit de ML

Use os utilitários de visualização para desenhar o resultado da detecção de objetos do Kit de ML na imagem de entrada.

Acesse a chamada debugPrint() e adicione o seguinte snippet de código abaixo:

// Parse ML Kit's DetectedObject and create corresponding visualization data
val detectedObjects = it.map { obj ->
    var text = "Unknown"

    // We will show the top confident detection result if it exist
    if (obj.labels.isNotEmpty()) {
        val firstLabel = obj.labels.first()
        text = "${firstLabel.text}, ${firstLabel.confidence.times(100).toInt()}%"
    }
    BoxWithText(obj.boundingBox, text)
}

// Draw the detection result on the input bitmap
val visualizedResult = drawDetectionResult(bitmap, detectedObjects)

// Show the detection result on the app screen
runOnUiThread {
    inputImageView.setImageBitmap(visualizedResult)
}
  • Comece analisando o DetectedObject do Kit de ML e criando uma lista de objetos BoxWithText para exibir o resultado da visualização.
  • Em seguida, desenhe o resultado da detecção na parte superior da imagem de entrada usando o método utilitário drawDetectionResult e mostre-o na tela.

Executar

Agora, clique em Run ( execute.png) na barra de ferramentas do Android Studio.

Após o carregamento do app, pressione o botão com o ícone de câmera, aponte a câmera para um objeto, tire uma foto, aceite a foto (no app Câmera) ou toque em qualquer imagem predefinida. Você verá os resultados da detecção. Pressione o botão novamente ou selecione outra imagem para repetir algumas vezes e vivencie a ODT mais recente do Kit de ML.

a03109cb30d5014d.png

7. Parabéns!

Você usou o kit de ML para adicionar recursos de detecção de objetos ao seu app:

  • Três etapas com três APIs
  • Criar imagem de entrada
  • Criar detector
  • Enviar imagem para o detector

Isso é tudo o que você precisa para começar a usar.

Ao continuar, talvez seja necessário melhorar o modelo. Como o modelo padrão só reconhece cinco categorias, ele não conhece as facas, os garfos e as garrafas. Confira o outro codelab em nosso programa de aprendizado de máquina no dispositivo: detecção de objetos para aprender a treinar um modelo personalizado.

O que vimos

  • Como adicionar a detecção e o rastreamento de objetos do Kit de ML ao seu app Android
  • Como usar a detecção e o rastreamento de objetos no dispositivo para detectar objetos em imagens

Próximas etapas

  • Explore mais com o ML Kit ODT, com mais imagens e vídeos ao vivo para ter precisão na detecção e classificação e no desempenho
  • Confira o programa de aprendizado de detecção de objetos do objeto de aprendizado de máquina no dispositivo para aprender a treinar um modelo personalizado.
  • Aplicar o ODT do kit de ML no seu próprio app Android

Saiba mais