A tarefa do MediaPipe Image Classifier permite que você faça a classificação de imagens. É possível usar essa tarefa para identificar o que uma imagem representa entre um conjunto de categorias definidas no tempo de treinamento. Estas instruções mostram como usar o classificador de imagem com apps Android. O exemplo de código descrito nestas instruções está disponível ativado GitHub.
Para saber como essa tarefa funciona, confira a demonstração na Web. Para mais informações sobre recursos, modelos e opções de configuração, desta tarefa, consulte a Visão geral.
Exemplo de código
O código de exemplo do MediaPipe Tasks é uma implementação simples de um classificador de imagem para Android. O exemplo usa a câmera de um dispositivo Android físico para classificar continuamente objetos, e também pode usar imagens e vídeos do da galeria de dispositivos para classificar objetos estaticamente.
Você pode usar o app como ponto de partida para seu próprio app Android ou consultá-lo ao modificar um aplicativo existente. O exemplo de código do Image Classifier está hospedado GitHub.
Fazer o download do código
As instruções a seguir mostram como criar uma cópia local do exemplo. usando a ferramenta de linha de comando git.
Para fazer o download do código de exemplo:
- Clone o repositório git usando o seguinte comando:
git clone https://github.com/google-ai-edge/mediapipe-samples
- Como opção, configure sua instância do Git para usar a finalização esparsa.
então, você tem apenas os arquivos do app de exemplo do Image Classifier:
cd mediapipe git sparse-checkout init --cone git sparse-checkout set examples/image_classification/android
Depois de criar uma versão local do código de exemplo, você pode importar o projeto no Android Studio e executar o app. Para instruções, consulte a Guia de configuração para Android.
Principais componentes
Os arquivos a seguir contêm o código crucial para esta imagem aplicação de exemplo de classificação:
- ImageClassifierHelper.kt: Inicializa o classificador de imagens, processa o modelo e o delegado
- MainActivity.kt (link em inglês):
Implementa o aplicativo, incluindo a chamada de
ImageClassificationHelper
eClassificationResultsAdapter
. - ClassificationResultsAdapter.kt: Processa e formata os resultados.
Configuração
Esta seção descreve as principais etapas para configurar seu ambiente de desenvolvimento e projetos de código para usar o classificador de imagem. Para informações gerais a configuração do seu ambiente de desenvolvimento para usar tarefas do MediaPipe, incluindo requisitos de versão da plataforma, consulte Guia de configuração para Android.
Dependências
O Image Classificador usa a biblioteca com.google.mediapipe:tasks-vision
. Adicionar
dependência do arquivo build.gradle
da
Projeto de desenvolvimento de apps Android. Importe as dependências necessárias com
o seguinte código:
dependencies {
...
implementation 'com.google.mediapipe:tasks-vision:latest.release'
}
Modelo
A tarefa do classificador de imagem do MediaPipe requer um modelo treinado que seja compatível com essa tarefa. Para mais informações sobre modelos treinados disponíveis para o classificador de imagem, consulte na seção de visão geral da tarefa Modelos.
Selecione e faça o download do modelo e armazene-o no diretório do projeto:
<dev-project-root>/src/main/assets
Use o método BaseOptions.Builder.setModelAssetPath()
para especificar o caminho.
usados pelo modelo. Esse método é mencionado no exemplo de código nos próximos
nesta seção.
Na
Exemplo de código do classificador de imagem
o modelo é definido em ImageClassifierHelper.kt
.
Criar a tarefa
Use a função createFromOptions
para criar a tarefa. A
A função createFromOptions
aceita opções de configuração, incluindo
modo, nome de exibição, localidade, número máximo de resultados, limite de confiança,
e uma lista de permissões ou de bloqueio. Para mais informações sobre configurações
opções, consulte Visão geral da configuração.
A tarefa Classificador de imagem oferece suporte a três tipos de dados de entrada: imagens estáticas, arquivos de vídeo e transmissões de vídeo ao vivo. Você precisa especificar o modo de corrida correspondente o tipo de dados de entrada ao criar a tarefa. Escolha a guia correspondente ao seu tipo de dados de entrada para ver como criar a tarefa e executar a inferência.
Imagem
ImageClassifierOptions options = ImageClassifierOptions.builder() .setBaseOptions( BaseOptions.builder().setModelAssetPath("model.tflite").build()) .setRunningMode(RunningMode.IMAGE) .setMaxResults(5) .build(); imageClassifier = ImageClassifier.createFromOptions(context, options);
Vídeo
ImageClassifierOptions options = ImageClassifierOptions.builder() .setBaseOptions( BaseOptions.builder().setModelAssetPath("model.tflite").build()) .setRunningMode(RunningMode.VIDEO) .setMaxResults(5) .build(); imageClassifier = ImageClassifier.createFromOptions(context, options);
Transmissão ao vivo
ImageClassifierOptions options = ImageClassifierOptions.builder() .setBaseOptions( BaseOptions.builder().setModelAssetPath("model.tflite").build()) .setRunningMode(RunningMode.LIVE_STREAM) .setMaxResults(5) .setResultListener((result, inputImage) -> { // Process the classification result here. }) .setErrorListener((result, inputImage) -> { // Process the classification errors here. }) .build() imageClassifier = ImageClassifier.createFromOptions(context, options)
A implementação de código de exemplo do classificador de imagem permite que o usuário alterne entre
os modos de processamento. A abordagem torna o código de criação da tarefa mais complicado
podem não ser adequados para seu caso de uso. Confira esse código
função setupImageClassifier()
do
ImageClassifierHelper.kt
.
Opções de configuração
Esta tarefa tem as seguintes opções de configuração para apps Android:
Nome da opção | Descrição | Intervalo de valor | Valor padrão |
---|---|---|---|
runningMode |
Define o modo de execução da tarefa. Existem três
modos: IMAGEM: o modo para entradas de imagem única. VÍDEO: o modo para frames decodificados de um vídeo. LIVE_STREAM: o modo de transmissão ao vivo da entrada dados de uma câmera, por exemplo. Neste modo, resultListener deve ser chamado para configurar um listener e receber resultados de forma assíncrona. |
{IMAGE, VIDEO, LIVE_STREAM } |
IMAGE |
displayNamesLocale |
Define o idioma dos rótulos a serem usados para nomes de exibição fornecidos no
metadados do modelo da tarefa, se disponíveis. O padrão é en para
inglês. É possível adicionar rótulos localizados aos metadados de um modelo personalizado
usando a API Metadata Writer do TensorFlow Lite; |
Código da localidade | en |
maxResults |
Define o número máximo opcional de resultados da classificação com maior pontuação como voltar. Se < 0, todos os resultados disponíveis serão retornados. | Qualquer número positivo | -1 |
scoreThreshold |
Define o limite de pontuação da previsão que substitui o fornecido no os metadados do modelo (se houver). Resultados abaixo desse valor são rejeitados. | Qualquer flutuação | Não definido |
categoryAllowlist |
Define a lista opcional de nomes de categorias permitidos. Se não estiver vazio,
resultados de classificação cujo nome de categoria não esteja neste conjunto serão
que foram filtradas. Nomes de categorias duplicados ou desconhecidos são ignorados.
Essa opção é mutuamente exclusiva com categoryDenylist e usando
os dois resultarão em erro. |
Qualquer string | Não definido |
categoryDenylist |
Define a lista opcional de nomes de categorias que não são permitidos. Se
não vazio, os resultados de classificação cujo nome de categoria estiver neste conjunto serão filtrados
para fora. Nomes de categorias duplicados ou desconhecidos são ignorados. Essa opção é mutuamente
exclusivo com categoryAllowlist e usar ambos resulta em um erro. |
Qualquer string | Não definido |
resultListener |
Define o listener de resultados para receber os resultados da classificação.
de forma assíncrona quando o classificador de imagem está na transmissão ao vivo
modo Só pode ser usado quando o modo de corrida está definido como LIVE_STREAM |
N/A | Não definido |
errorListener |
Define um listener de erro opcional. | N/A | Não definido |
Preparar dados
O Image Classificador funciona com imagens, arquivos de vídeo e streaming de vídeo ao vivo. A tarefa lida com o pré-processamento de entrada de dados, incluindo redimensionamento, rotação e valor. normalização.
Você precisa converter a imagem ou frame de entrada
com.google.mediapipe.framework.image.MPImage
antes de transmiti-lo ao
Classificador de imagem.
Imagem
import com.google.mediapipe.framework.image.BitmapImageBuilder; import com.google.mediapipe.framework.image.MPImage; // Load an image on the user’s device as a Bitmap object using BitmapFactory. // Convert an Android’s Bitmap object to a MediaPipe’s Image object. Image mpImage = new BitmapImageBuilder(bitmap).build();
Vídeo
import com.google.mediapipe.framework.image.BitmapImageBuilder; import com.google.mediapipe.framework.image.MPImage; // Load a video file on the user's device using MediaMetadataRetriever // From the video’s metadata, load the METADATA_KEY_DURATION and // METADATA_KEY_VIDEO_FRAME_COUNT value. You’ll need them // to calculate the timestamp of each frame later. // Loop through the video and load each frame as a Bitmap object. // Convert the Android’s Bitmap object to a MediaPipe’s Image object. Image mpImage = new BitmapImageBuilder(frame).build();
Transmissão ao vivo
import com.google.mediapipe.framework.image.MediaImageBuilder; import com.google.mediapipe.framework.image.MPImage; // Create a CameraX’s ImageAnalysis to continuously receive frames // from the device’s camera. Configure it to output frames in RGBA_8888 // format to match with what is required by the model. // For each Android’s ImageProxy object received from the ImageAnalysis, // extract the encapsulated Android’s Image object and convert it to // a MediaPipe’s Image object. android.media.Image mediaImage = imageProxy.getImage() Image mpImage = new MediaImageBuilder(mediaImage).build();
Na
de exemplo do classificador de imagem, a preparação dos dados é processada no
ImageClassifierHelper.kt
.
Executar a tarefa
É possível chamar a função classify
correspondente ao modo de execução para acionar inferências. A API Image Classifier retorna as categorias possíveis para o objeto na imagem de entrada ou no frame.
Imagem
ImageClassifierResult classifierResult = imageClassifier.classify(image);
Vídeo
// Calculate the timestamp in milliseconds of the current frame. long frame_timestamp_ms = 1000 * video_duration * frame_index / frame_count; // Run inference on the frame. ImageClassifierResult classifierResult = imageClassifier.classifyForVideo(image, frameTimestampMs);
Transmissão ao vivo
// Run inference on the frame. The classifications results will be available // via the `resultListener` provided in the `ImageClassifierOptions` when // the image classifier was created. imageClassifier.classifyAsync(image, frameTimestampMs);
Observe o seguinte:
- Ao executar nos modos de vídeo ou de transmissão ao vivo, você também precisa forneça o carimbo de data/hora do frame de entrada para a tarefa Classificador de imagem.
- Ao executar no modo de imagem ou vídeo, a tarefa Classificador de imagem bloqueia a linha de execução atual até terminar de processar a imagem de entrada ou frame. Para evitar o bloqueio da interface do usuário, execute o processamento em um linha de execução em segundo plano.
- Quando a visualização é executada no modo de transmissão ao vivo, a tarefa do classificador de imagem não bloqueia
thread atual, mas retorna imediatamente. Ele vai invocar seu resultado
com o resultado da detecção sempre que ele terminar de processar um erro.
frame de entrada. Se a função
classifyAsync
for chamada quando o classificador de imagem estiver ocupada processando outro frame, a tarefa ignora o novo frame de entrada.
Na
exemplo de código do classificador de imagem, as funções classify
são definidas na
ImageClassifierHelper.kt
.
Gerenciar e exibir resultados
Ao executar a inferência, a tarefa do classificador de imagem retorna um objeto ImageClassifierResult
que contém a lista de categorias possíveis para os objetos na imagem de entrada ou no frame.
Confira abaixo um exemplo dos dados de saída desta tarefa:
ImageClassifierResult:
Classifications #0 (single classification head):
head index: 0
category #0:
category name: "/m/01bwb9"
display name: "Passer domesticus"
score: 0.91406
index: 671
category #1:
category name: "/m/01bwbt"
display name: "Passer montanus"
score: 0.00391
index: 670
Esse resultado foi obtido executando o Bird Classifier em:
Na
Exemplo de código do classificador de imagem, a classe ClassificationResultsAdapter
na
ClassificationResultsAdapter.kt
gerencia os resultados:
fun updateResults(imageClassifierResult: ImageClassifierResult? = null) {
categories = MutableList(adapterSize) { null }
if (imageClassifierResult != null) {
val sortedCategories = imageClassifierResult.classificationResult()
.classifications()[0].categories().sortedBy { it.index() }
val min = kotlin.math.min(sortedCategories.size, categories.size)
for (i in 0 until min) {
categories[i] = sortedCategories[i]
}
}
}