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, que são eficientes e simples, para resolver desafios comuns nos seus apps ou criar experiências de usuário totalmente novas. Todos são alimentados pelos melhores modelos de ML do Google e oferecidos sem custo.

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

Neste codelab, você vai aprender de forma simples a adicionar a detecção e o rastreamento de objetos (ODT, na sigla em inglês) de uma imagem específica ao seu app Android. Este codelab usa alguns atalhos para destacar o uso do ODT do ML Kit.

O que você vai criar

Neste codelab, você vai criar um app Android com o ML Kit. O app vai usar a API Object Detection and Tracking do ML Kit para detectar objetos em uma determinada imagem.No final, você vai ver algo semelhante à imagem à direita.

O que você vai aprender

  • Como integrar o SDK do Kit de ML ao seu aplicativo Android
  • API de detecção e rastreamento de objetos do Kit de ML

O que é necessário

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

Este codelab é focado no ML Kit. Conceitos e blocos de códigos sem relevância não serão abordados. Eles são incluídos somente para você copiar e colar.

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 vai descompactar uma pasta raiz (mlkit-android-main) com todos os recursos necessários. Para este codelab, você só vai 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: código inicial que você vai usar como base para este codelab.
  • android_studio_folder.pngfinal: código concluído para o app de exemplo finalizado.

3. Adicionar a API de detecção e rastreamento de objetos do Kit de ML ao projeto

Importar o app para o Android Studio

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

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

7c0f27882a2698ac.png

Adicionar as dependências para a detecção e o rastreamento de objetos do Kit de ML

As dependências do ML Kit permitem integrar o SDK ODT do ML Kit ao seu app. Adicione as linhas abaixo ao final 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 o app, sincronize o projeto com os 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 apenas starter/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 a detecção e o rastreamento de objetos do Kit de ML, está tudo pronto para executar o app pela primeira vez.

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

Executar e conhecer o app

O app será iniciado no dispositivo Android. Ele tem um código boilerplate para capturar uma foto ou selecionar uma imagem predefinida e enviá-la para um pipeline de detecção e rastreamento de objetos que você vai criar neste codelab. Vamos conhecer um pouco o app antes de escrever o código.

Primeiro, há um botão ( c6d965d639c3646.png) na parte de baixo para:

  • abrir o app da câmera integrado ao dispositivo/emulador;
  • tirar uma foto no app de câmera;
  • receber a imagem capturada no app inicial
  • Mostrar a imagem

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

Repita algumas vezes para ver como funciona:

9ec541980dbe2d31.png 8312dde41425ba4b.png fa8492bfc1914ff0.png

Em segundo lugar, há três imagens predefinidas para você escolher. Você pode usar essas imagens mais tarde para testar o código de detecção de objetos se estiver executando em um emulador Android.

Selecione uma imagem entre as três predefinidas. A imagem aparece na visualização maior:

1dd41b3ec978f1d9.png

5. Adicionar a detecção de objetos no dispositivo

Nesta etapa, você vai 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 clichê para tirar fotos com o app de câmera no dispositivo. Também há três imagens predefinidas no app que você pode usar para testar a detecção de objetos se estiver executando o codelab em um emulador do Android.

Quando você seleciona uma imagem, seja nas imagens predefinidas ou tirando uma foto com o app da câmera, o código boilerplate decodifica essa imagem em uma instância Bitmap, mostra na tela e chama o método runObjectDetection com a imagem.

Nesta etapa, você vai adicionar 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

Há apenas 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)

Você pode fazer isso na 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. Siga para as etapas a seguir para implementar o ODT do ML Kit. Ao longo do caminho, o Android Studio pedia para adicionar 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 a partir de um Bitmap. Em seguida, é possível inserir 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 ao início de runObjectDetection(bitmap:Bitmap).

Etapa 2: criar uma instância do detector

O Kit de ML segue o padrão de design do builder. Você vai transmitir a configuração para o builder e, em seguida, adquirir um detector dele. Há três opções para configurar (as opções em negrito são usadas neste codelab):

  • modo de detector (imagem única ou transmissão)
  • modo de detecção (único ou vários objetos).
  • modo de classificação (ativado ou desativado).

Este codelab é para detecção e classificação de vários objetos em uma única imagem. 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: alimentar o detector com imagens

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

  • Você envia uma imagem para o detector (via process()).
  • O detector trabalha muito nisso.
  • O detector informa o resultado a você por meio de um callback.

O código abaixo faz exatamente isso (copia e anexa 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())
   }

Ao terminar, o detector notifica você com:

  • O número total de objetos detectados. Cada objeto detectado é descrito com:
  • trackingId: um número inteiro usado para rastrear frames cruzados (NÃO usado neste codelab).
  • boundingBox: a caixa delimitadora do objeto.
  • labels: uma lista de rótulos para o objeto detectado (somente quando a classificação está ativada):
  • index (pegar o índice desse rótulo)
  • text (Receba o texto deste rótulo, incluindo "Fashion Goods", "Food", "Home Goods", "Place", "Plant")
  • confidence: um ponto flutuante entre 0,0 e 1,0, em que 1,0 significa 100%.

Você provavelmente notou que o código faz um tipo de processamento printf para o 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.

Vamos executar o codelab clicando em Run ( execute.png) na barra de ferramentas do Android Studio. Tente selecionar uma imagem predefinida ou tirar uma foto e observe 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 encontrou três objetos:

  • As categorias são Alimentos e Artigos para casa.
  • Não há uma categoria retornada para o segundo, 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 está bastante confiante de que o primeiro é um alimento (90% de confiança). Era salada.

Tecnicamente, isso é tudo o que você precisa para fazer o ML Kit Object Detection funcionar: você tem tudo no momento. Parabéns!

Na interface, você ainda está no estágio em que começou, mas pode usar os resultados detectados na interface, como desenhar a caixa delimitadora para criar uma experiência melhor. Vamos para a próxima etapa: pós-processar os resultados detectados.

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

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

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

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

Noções básicas sobre 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) É uma classe de dados para armazenar um resultado de detecção de objetos para visualização. box é a caixa delimitadora em que o objeto é localizado, e text é a string do resultado da detecção que será mostrada junto com a caixa delimitadora do objeto.
  • fun drawDetectionResult(bitmap: Bitmap, detectionResults: List<BoxWithText>): Bitmap Esse método desenha os resultados da detecção de objetos em detectionResults na entrada bitmap e retorna a cópia modificada.

Confira 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 parte de cima da imagem de entrada.

Acesse o local em que você chama debugPrint() e adicione o 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 mostrar o resultado da visualização.
  • Em seguida, você desenha o resultado da detecção na parte de cima da imagem de entrada, usando o método de utilitário drawDetectionResult, e mostra na tela.

Executar

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

Depois que o app carregar, 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. Os resultados da detecção vão aparecer. Pressione o botão novamente ou selecione outra imagem para repetir algumas vezes e conferir a ODT mais recente do ML Kit.

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.

À medida que você avança, talvez queira aprimorar o modelo. Como você pode ver, o modelo padrão só reconhece cinco categorias. Ele nem sabe o que é faca, garfo e garrafa. Confira o outro codelab no Programa de treinamentos de aprendizado de máquina no dispositivo: detecção de objetos para saber como 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 no Kit de ML para detectar objetos em imagens

Próximas etapas

  • Explore mais com o ODT do ML Kit com mais imagens e vídeos ao vivo para conferir a precisão e o desempenho da detecção e classificação
  • Confira o treinamento Detecção de objetos no dispositivo: aprendizado de máquina para saber como treinar um modelo personalizado.
  • Aplicar o ODT do Kit de ML no seu app Android

Saiba mais