Depois de treinar seu modelo com o AutoML Vision Edge, você poderá usá-lo no seu app para detectar objetos nas imagens.
Há duas maneiras de integrar modelos treinados usando o AutoML Vision Edge: é possível agrupar o modelo colocando-o na pasta de recursos do app ou fazer o download dele dinamicamente usando o Firebase.
Opções de empacotamento de modelos | |
---|---|
Incluído no seu app |
|
Hospedado com o Firebase |
|
Antes de começar
Se você quiser fazer o download de um modelo, adicione o Firebase ao seu projeto do Android, caso ainda não tenha feito isso. Essa etapa não é necessária para empacotar o modelo.
Adicione as dependências da biblioteca de tarefas do TensorFlow Lite ao arquivo Gradle no nível do app do seu módulo, que geralmente é
app/build.gradle
:Para agrupar um modelo e seu app:
dependencies { // ... // Object detection with a bundled Auto ML model implementation 'org.tensorflow:tensorflow-lite-task-vision:0.0.0-nightly-SNAPSHOT' }
Para fazer o download dinâmico de um modelo do Firebase, adicione também a dependência do Firebase ML:
dependencies { // ... // Object detection with an Auto ML model deployed to Firebase implementation platform('com.google.firebase:firebase-bom:26.1.1') implementation 'com.google.firebase:firebase-ml-model-interpreter' implementation 'org.tensorflow:tensorflow-lite-task-vision:0.0.0-nightly' }
1. Carregar o modelo
Configurar uma fonte de modelo local
Para agrupar o modelo e o aplicativo, siga estas etapas:
- Extraia o modelo do arquivo zip que você salvou do Console do Google Cloud.
- Inclua o modelo no pacote de apps:
- Se você não tiver uma pasta de recursos no projeto, crie uma clicando com o botão direito do mouse na pasta
app/
e, em seguida, em Novo > Pasta > Pasta de recursos. - Copie o arquivo de modelo
tflite
com metadados incorporados para a pasta de recursos.
- Se você não tiver uma pasta de recursos no projeto, crie uma clicando com o botão direito do mouse na pasta
Adicione o seguinte ao arquivo
build.gradle
do app para garantir que o Gradle não compacte o arquivo de modelo ao criar o app:android { // ... aaptOptions { noCompress "tflite" } }
O arquivo de modelo será incluído no pacote de app e estará disponível como um recurso bruto.
Configurar uma fonte de modelos hospedada no Firebase
Para usar o modelo hospedado remotamente, crie um objeto RemoteModel
,
especificando o nome que você atribuiu ao modelo quando o publicou:
Java
// Specify the name you assigned when you deployed the model.
FirebaseCustomRemoteModel remoteModel =
new FirebaseCustomRemoteModel.Builder("your_model").build();
Kotlin
// Specify the name you assigned when you deployed the model.
val remoteModel =
FirebaseCustomRemoteModel.Builder("your_model_name").build()
Em seguida, inicie a tarefa de download do modelo, especificando as condições sob as quais você quer permitir o download. Se o modelo não estiver no dispositivo ou se uma versão mais recente do modelo estiver disponível, a tarefa fará o download do modelo de forma assíncrona do Firebase:
Java
DownloadConditions downloadConditions = new DownloadConditions.Builder()
.requireWifi()
.build();
RemoteModelManager.getInstance().download(remoteModel, downloadConditions)
.addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(@NonNull Task<Void> task) {
// Success.
}
});
Kotlin
val downloadConditions = DownloadConditions.Builder()
.requireWifi()
.build()
RemoteModelManager.getInstance().download(remoteModel, downloadConditions)
.addOnSuccessListener {
// Success.
}
Muitos apps iniciam a tarefa de download no código de inicialização, mas você pode fazer isso a qualquer momento antes de precisar usar o modelo.
Criar um detector de objetos do seu modelo
Depois de configurar as origens do modelo, crie um objeto ObjectDetector
a partir de uma delas.
Se você tiver somente um modelo agrupado localmente, basta criar um detector de objetos a partir do arquivo de modelo e configurar o limite de pontuação de confiança que quer exigir. Consulte Avaliar seu modelo:
Java
// Initialization
ObjectDetectorOptions options = ObjectDetectorOptions.builder()
.setScoreThreshold(0) // Evaluate your model in the Google Cloud Console
// to determine an appropriate value.
.build();
ObjectDetector objectDetector = ObjectDetector.createFromFileAndOptions(context, modelFile, options);
Kotlin
// Initialization
val options = ObjectDetectorOptions.builder()
.setScoreThreshold(0) // Evaluate your model in the Google Cloud Console
// to determine an appropriate value.
.build()
val objectDetector = ObjectDetector.createFromFileAndOptions(context, modelFile, options)
Se você tiver um modelo hospedado remotamente, será necessário verificar se foi feito
o download dele antes de executá-lo. É possível verificar o status da tarefa de download do modelo usando o método isModelDownloaded()
do gerenciador de modelos.
Embora isso só precise ser confirmado antes da execução do detector de objetos, se você tiver um modelo hospedado remotamente e um modelo agrupado localmente, talvez faça sentido realizar essa verificação ao instanciar o detector de objetos: crie um detector de objetos do modelo remoto, se ele tiver sido transferido por download. Caso contrário, crie a partir do modelo local.
Java
FirebaseModelManager.getInstance().isModelDownloaded(remoteModel)
.addOnSuccessListener(new OnSuccessListener<Boolean>() {
@Override
public void onSuccess(Boolean isDownloaded) {
}
});
Kotlin
FirebaseModelManager.getInstance().isModelDownloaded(remoteModel)
.addOnSuccessListener { success ->
}
Se você tiver apenas um modelo hospedado remotamente, desative o recurso relacionado ao modelo (por exemplo, ocultando ou esmaecendo parte da IU) até
confirmar que o download do modelo foi concluído. Para fazer isso, anexe um listener
ao método download()
do gerenciador de modelos:
Quando você souber que o modelo foi salvo, crie um detector de objetos a partir do arquivo de modelo:
Java
FirebaseModelManager.getInstance().getLatestModelFile(remoteModel)
.addOnCompleteListener(new OnCompleteListener<File>() {
@Override
public void onComplete(@NonNull Task<File> task) {
File modelFile = task.getResult();
if (modelFile != null) {
ObjectDetectorOptions options = ObjectDetectorOptions.builder()
.setScoreThreshold(0)
.build();
objectDetector = ObjectDetector.createFromFileAndOptions(
getApplicationContext(), modelFile.getPath(), options);
}
}
});
Kotlin
FirebaseModelManager.getInstance().getLatestModelFile(remoteModel)
.addOnSuccessListener { modelFile ->
val options = ObjectDetectorOptions.builder()
.setScoreThreshold(0f)
.build()
objectDetector = ObjectDetector.createFromFileAndOptions(
applicationContext, modelFile.path, options)
}
2. Preparar a imagem de entrada
Em seguida, para cada imagem que você quer rotular, crie um objeto TensorImage
a partir da sua
imagem. É possível criar um objeto TensorImage
a partir de um Bitmap
usando o
método fromBitmap
:
Java
TensorImage image = TensorImage.fromBitmap(bitmap);
Kotlin
val image = TensorImage.fromBitmap(bitmap)
Se os dados de imagem não estiverem em um Bitmap
, será possível carregar uma matriz de pixels conforme mostrado nos
documentos do TensorFlow Lite.
3. Executar o detector de objetos
Para rotular objetos em uma imagem, transmita o objeto TensorImage
para o
método detect()
do ObjectDetector
.
Java
List<Detection> results = objectDetector.detect(image);
Kotlin
val results = objectDetector.detect(image)
4. Ver informações sobre os objetos rotulados
Se a operação de detecção de objetos for bem-sucedida, ela retornará uma lista de
objetos Detection
. Cada objeto Detection
representa algo
que foi detectado na imagem. É possível receber a caixa delimitadora de cada objeto e os rótulos associados.
Exemplo:
Java
for (Detection result : results) {
RectF bounds = result.getBoundingBox();
List<Category> labels = result.getCategories();
}
Kotlin
for (result in results) {
val bounds = result.getBoundingBox()
val labels = result.getCategories()
}
Dicas para melhorar o desempenho em tempo real
Caso você queira rotular imagens em um aplicativo em tempo real, siga estas diretrizes para ter as melhores taxas de frames:
- Limite as chamadas para o rotulador de imagens. Se um novo quadro de vídeo ficar
disponível enquanto o rotulador de imagens estiver em execução, elimine o frame. Consulte a classe
VisionProcessorBase
no app de amostra do guia de início rápido para conferir um exemplo. - Se você estiver usando a saída do rotulador de imagens para sobrepor elementos gráficos na
imagem de entrada, primeiro acesse o resultado e, em seguida, renderize a imagem
e a sobreposição em uma única etapa. Ao fazer isso, você renderiza a superfície de exibição
apenas uma vez para cada quadro de entrada. Consulte as classes
CameraSourcePreview
eGraphicOverlay
no app de amostra do guia de início rápido para conferir um exemplo. -
Se você usar a API Camera2, capture imagens no formato
ImageFormat.YUV_420_888
.Se você usar a API Camera mais antiga, capture imagens no formato
ImageFormat.NV21
.