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 você pode apontar a câmera do smartphone para um objeto e descobrir onde comprá-lo 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 aprendizado que ensina a criar um recurso de pesquisa de imagens de produtos 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 o rastreamento de objetos do Kit de ML para criar esse recurso.

Você pode aprender sobre as etapas restantes, incluindo como criar um back-end de pesquisa de produtos com a Pesquisa de produtos da API Vision, no caminho de aprendizado.

O que você vai criar

  • Neste codelab, você vai criar um app Android com o ML Kit. O app vai usar a API de detecção e rastreamento de objetos do Kit de ML para detectar objetos em uma determinada imagem. Em seguida, o usuário escolhe um objeto que quer pesquisar no nosso banco de dados de produtos.
  • No final, você 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. Outros conceitos e blocos de código não são estudados e são fornecidos para que você simplesmente 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 vai descompactar uma pasta raiz (odml-pathways-main) com todos os recursos necessários. Para este codelab, você só vai precisar das origens no subdiretório product-search/codelab1/android.

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

Comece importando o app starter para o Android Studio.

Acesse o Android Studio, selecione "Import Project" (Gradle, Eclipse ADT etc.) e escolha a pasta starter no 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 Kit de ML permitem integrar o SDK 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'
}

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. Conheça um pouco o app antes de escrever o código:

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

  • iniciar o app de câmera integrado no 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 a exibição dela no app inicial.

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.

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

1290481786af21b9.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 ML Kit.

  • 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. Continue com as etapas a seguir para integrar o ODT do Kit de ML. 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ê precisa transmitir a configuração para o builder e, em seguida, adquirir um detector dele. Há três opções para configurar (a em negrito é usada no 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 uma única imagem: detecção e classificação de vários objetos. 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: 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())
   }

Após a conclusão, 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 frames cruzados (NÃO usado neste codelab)
  • boundingBox: caixa delimitadora do objeto
  • labels: 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 mostra 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. 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: 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 detectou três objetos:

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

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

Sim, do lado 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
  • 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:

  • class ImageClickableView Esta é uma classe de visualização de imagem 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)) Esse é um callback para receber a imagem cortada que contém apenas o objeto que o usuário tocou. Você vai enviar essa imagem cortada para o back-end da pesquisa de imagens em um codelab posterior para conseguir 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 snippet de código abaixo:

runOnUiThread {
    viewBinding.ivPreview.drawDetectionResults(it)
}

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. O resultado da detecção vai aparecer. Pressione o botão novamente ou selecione outra imagem para repetir o processo algumas vezes e conferir a ODT mais recente do ML Kit.

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 a usar.

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

  • Tente este codelab sobre como enviar o objeto detectado para um back-end de pesquisa de produtos e mostrar os resultados da pesquisa.
  • 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 Programa de treinamento Avançar com a detecção de objetos para saber como treinar um modelo personalizado.
  • Leia sobre as recomendações do Material Design para a detecção de objetos câmera ao vivo e imagem estática.
  • Aplicar o ODT do Kit de ML no seu app Android

Saiba mais