Detecte objetos em imagens para criar uma pesquisa visual de produtos com o Kit de ML: Android

1. Antes de começar

727608486a28395d.png

Você já viu a demonstração do Google Lens, em que é possível apontar a câmera do smartphone para um objeto e encontrar onde comprar on-line? Se você quiser aprender a adicionar o mesmo recurso ao seu app, este codelab é para você. Ele faz parte de um programa de cursos que ensina a criar um recurso de pesquisa por imagens de produto em um app para dispositivos móveis.

Neste codelab, você vai aprender a primeira etapa para criar um recurso de pesquisa de imagens de produtos: como detectar objetos em imagens e permitir que o usuário escolha os objetos que quer pesquisar. Você vai usar a detecção e rastreamento de objetos do Kit de ML para criar esse recurso.

Saiba mais sobre as etapas restantes, incluindo como criar um back-end de pesquisa de produtos com a Pesquisa de produtos da API Vision, no programa de cursos.

O que você vai criar

  • Neste codelab, você vai criar um app Android com o Kit de ML. O app vai usar a API Object Detection and Tracking do Kit de ML para detectar objetos em uma determinada imagem. Em seguida, o usuário escolhe um objeto que quer pesquisar no banco de dados de produtos.
  • No final, você vai ver algo parecido com a imagem à direita.

O que você vai aprender

  • Como integrar o Kit de ML SDK ao seu app 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 ou mais recente)
  • 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 Kit de ML. Outros conceitos e blocos de código não são estudados e são 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 descompacta uma pasta raiz (odml-pathways-main) com todos os recursos necessários. Neste codelab, você só vai precisar das fontes no subdiretório product-search/codelab1/android.

O subdiretório object-detection no repositório mlkit-android contém dois diretórios:

  • android_studio_folder.pngstarter: o código inicial que você vai usar como base neste codelab.
  • android_studio_folder.pngfinal: código completo do 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

Comece importando o app inicial para o Android Studio.

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

7c0f27882a2698ac.png

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

As dependências do kit de ML permitem integrar o SDK de ODT do kit de ML ao seu app.

Acesse o arquivo app/build.gradle do projeto e confirme se a dependência já está lá:

build.gradle

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

Sincronize seu projeto com arquivos do Gradle

Para garantir que todas as dependências estejam disponíveis para seu app, sincronize o projeto com os arquivos do Gradle neste momento.

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 detecção e rastreamento de objetos do Kit de ML, já pode executar o app pela primeira vez.

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

Executar e explorar o app

O app será iniciado no dispositivo Android. Ele tem um código boilerplate para permitir que você capture uma foto ou selecione uma imagem predefinida e a envie para um pipeline de detecção e rastreamento de objetos que você vai criar neste codelab. Explore um pouco o app antes de escrever o código:

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

  • inicie o app de câmera integrado ao dispositivo/emulador
  • tire 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 como ela aparece no app inicial.

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

  1. Selecione uma das três imagens predefinidas.
  2. Confira se a imagem aparece na visualização maior.

1290481786af21b9.png

5. Adicionar 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 código boilerplate para tirar fotos com o app de câmera no dispositivo. Há também três imagens predefinidas no app em que você pode testar a detecção de objetos se estiver executando o codelab em um emulador do Android.

Quando você seleciona uma imagem, seja das imagens predefinidas ou tirando uma foto com o app de 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 a ODT do Kit de ML.

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

Você faz 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 as etapas abaixo para integrar a ODT do Kit de ML. Ao longo do processo, o Android Studio vai pedir 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 um InputImage

O Kit de ML oferece uma API simples para criar um InputImage 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 à parte de cima de runObjectDetection(bitmap:Bitmap).

Etapa 2: criar uma instância de detector

O Kit de ML segue o padrão de design do builder. Você transmite a configuração para o builder e adquire um detector dele. Há três opções de configuração (a em negrito é usada no codelab):

  • modo de detector (imagem única ou stream)
  • modo de detecção (única ou múltipla detecção de objetos)
  • modo de classificação (ativado ou desativado)

Este codelab é para detecção e classificação de vários objetos em uma única imagem. Vamos fazer isso:

// 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 ao detector

A detecção e a classificação de objetos são processamentos assíncronos:

  • você envia uma imagem para o detector (via process())
  • detector trabalha bastante nisso
  • O detector informa o resultado para você por um callback.

O código a seguir faz exatamente isso. Copie e adicione ao código atual em 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 concluir, o detector notifica você com

  1. Número total de objetos detectados
  2. Cada objeto detectado é descrito com
  • trackingId: um número inteiro usado para rastrear quadros cruzados (NÃO usado neste codelab)
  • boundingBox: caixa delimitadora do objeto.
  • Lista labels: de rótulos para o objeto detectado (somente quando a classificação está ativada)
  • index (recebe o índice deste rótulo)
  • text (receba o texto deste rótulo, incluindo "Artigos de moda", "Alimentos", "Artigos para casa", "Lugar", "Planta")
  • confidence (um ponto flutuante entre 0,0 e 1,0, em que 1,0 significa 100%)

Você provavelmente já percebeu que o código imprime os resultados detectados no Logcat 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. Selecione uma imagem predefinida ou tire uma foto e confira a janela 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: Fashion good
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 de:

  • As categorias são Artigo de moda e Artigo para casa.
  • Não há categoria retornada para o segundo porque é uma classe desconhecida.
  • sem trackingId (porque este é o modo de detecção de imagem única)
  • posição dentro do retângulo boundingBox (por exemplo, (481, 2021) – (2426, 3376))
  • O detector está bem confiante de que o primeiro é um produto de moda (90%) (é um vestido)

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

Sim, na parte da 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. A próxima etapa é visualizar 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
  • extrair o nome da categoria e a confiança dentro da 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 essas utilidades para simplificar nosso código de visualização:

  • class ImageClickableView Essa é uma classe de visualização de imagens que oferece alguns utilitários convenientes para visualização e interação com o resultado da detecção.
  • fun drawDetectionResults(results: List<DetectedObject>): esse método desenha círculos brancos no centro de cada objeto detectado.
  • fun setOnObjectClickListener(listener: ((objectImage: Bitmap) -> Unit)) Este é um callback para receber a imagem cortada que contém apenas o objeto em que o usuário tocou. Você vai enviar essa imagem cortada para o back-end da pesquisa por imagens em um codelab posterior para receber um resultado visualmente semelhante. Neste codelab, você ainda não vai usar esse método.

Mostrar o resultado da detecção do Kit de ML

Use os utilitários de visualização para mostrar 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 seguinte snippet de código abaixo dele:

runOnUiThread {
    viewBinding.ivPreview.drawDetectionResults(it)
}

Executar

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

Depois que o app carregar, pressione o botão com o ícone da câmera, aponte a câmera para um objeto, tire uma foto, aceite a foto (no app Câmera) ou toque em qualquer uma das imagens predefinidas. Você vai ver o resultado da detecção. Pressione o botão de novo ou selecione outra imagem para repetir algumas vezes e testar a versão mais recente da ODT do Kit de ML.

5027148750dc0748.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!

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

  • Confira este codelab sobre como enviar o objeto detectado para um back-end de pesquisa de produtos e mostrar os resultados da pesquisa.
  • Aproveite mais com o Kit de ML ODT com mais imagens e vídeo ao vivo para testar a precisão e o desempenho da detecção e da classificação.
  • Confira o programa de cursos Avance ainda mais com a detecção de objetos para saber como treinar um modelo personalizado.
  • Leia sobre as recomendações do Material Design para detecção de objetos live-camera e static-image.
  • Aplicar a ODT do Kit de ML no seu próprio app Android

Saiba mais