Detectar objetos em imagens para criar uma pesquisa visual de produto com o kit de ML: Android

1. Antes de começar

727608486a28395d.png

Já viu a demonstração do Google Lens, onde você pode apontar a câmera do smartphone para um objeto e descobrir onde pode comprá-lo on-line? Se você quer saber como adicionar o mesmo recurso ao app, este codelab é ideal. 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ê aprenderá a primeira etapa para criar um recurso de pesquisa de imagens de produto: como detectar objetos em imagens e permitir que o usuário escolha os objetos que ele quer pesquisar. Você usará a detecção e o 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 aprendizado.

O que você criará

  • Neste codelab, você criará um app Android com o kit de ML. Seu app usará a API de detecção e rastreamento de objetos do ML Kit para detectar objetos em uma determinada imagem. Em seguida, o usuário escolherá um objeto que quer pesquisar em nosso banco de dados de produtos.
  • 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. Outros conceitos e blocos de código não são estudados e são fornecidos para que você apenas 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 (odml-pathways-main) com todos os recursos necessários. Neste codelab, você só 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: 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

Para começar, importe o app starter para o Android Studio.

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

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.

Acesse o arquivo app/build.gradle do seu 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 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 apenas o inicializador/app/build.gradle, e não todo o repositório.

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

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

  • Iniciar 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

Experimente o botão Tirar foto. Siga as instruções para tirar uma foto, aceitar a foto e notá-la exibida no app inicial.

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.

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

1290481786af21b9.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ê seleciona uma imagem, seja das imagens predefinidas ou tirando uma foto com o app Câmera, o código boilerplate decodifica essa imagem em uma instância Bitmap, mostra-a na tela e chama 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

Configure o ODT de ML em apenas três etapas simples com três APIs

  • 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 integrar 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ê passa a configuração para o builder e depois adquire um detector dele. Há três opções de configuração (a que está em negrito é usada no 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. Faça 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 para o detector

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

  • enviar uma imagem para o detector (via process())
  • o detector está trabalhando duro para isso
  • o detector reporta o resultado 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

  1. Número total de objetos detectados
  2. 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
  • Lista de marcadores labels: 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 variação entre 0,0 e 1,0 com 1,0 significa 100%)

Você provavelmente percebeu que o código imprime os resultados detectados no Logcat com o 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.

Execute o codelab clicando em Run ( execute.png) na barra de ferramentas do Android Studio. Tente selecionar uma imagem predefinida ou tirar uma foto. Depois, olhe para 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:

  • As categorias são Bons para a moda e Bons para casa.
  • nenhuma categoria foi retornada para a segunda porque é uma classe desconhecida.
  • não trackingId (porque esse é o modo de detecção de imagem única)
  • posição dentro do retângulo boundingBox (por exemplo, (481, 2021) a (2426, 3376))
  • o detector tem muita certeza de que o primeiro é um produto de moda (90%) (é um vestido)

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

Sim, do 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. A próxima etapa é visualizar os resultados detectados.

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

Nas etapas anteriores, você exibiu 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:

  • class ImageClickableView Essa é uma classe de visualização de imagem que oferece alguns utilitários 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)): é um callback para receber a imagem cortada que contém apenas o objeto em que o usuário tocou. Você 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 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 imagem de entrada.

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

runOnUiThread {
    viewBinding.ivPreview.drawDetectionResults(it)
}

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á o resultado da detecção: Pressione o botão novamente ou selecione outra imagem para repetir algumas vezes e veja a mais recente 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 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 para detectar objetos em imagens

Próximas etapas

  • Experimente este codelab sobre como enviar o objeto detectado a um back-end de pesquisa de produto e mostrar os resultados da pesquisa
  • 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 Vá mais com a detecção de objetos para aprender a treinar um modelo personalizado.
  • Leia sobre as recomendações do Material Design para detecção de objetos live-camera e static-image.
  • Aplicar o ODT do kit de ML no seu próprio app Android

Saiba mais