Después de entrenar tu propio modelo con AutoML Vision Edge, puedes usarlo en tu app para detectar objetos en imágenes.
Hay dos formas de integrar los modelos entrenados desde AutoML Vision Edge: puedes agrupar el modelo colocándolo dentro de la carpeta de elementos de tu app o puedes descargarlo de forma dinámica desde Firebase.
Opciones de agrupación de modelos | |
---|---|
Agrupados en tu app |
|
Alojado en Firebase |
|
Antes de comenzar
Si quieres descargar un modelo, asegúrate de agregar Firebase a tu proyecto de Android, en caso de que aún no lo hayas hecho. Esto no es obligatorio cuando se agrupa un modelo.
Agrega las dependencias para la biblioteca de tareas de TensorFlow Lite al archivo Gradle de nivel de la app del módulo, que generalmente es
app/build.gradle
:Para empaquetar un modelo con tu app, sigue estos pasos:
dependencies { // ... // Object detection with a bundled Auto ML model implementation 'org.tensorflow:tensorflow-lite-task-vision:0.0.0-nightly-SNAPSHOT' }
Si quieres descargar un modelo de Firebase de forma dinámica, agrega también la dependencia del AA de Firebase:
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. Carga el modelo
Configura una fuente de modelo local
Sigue estos pasos para empaquetar el modelo con tu app:
- Extrae el modelo del archivo ZIP que descargaste de la consola de Google Cloud.
- Incluye tu modelo en el paquete de tu app:
- Si no tienes una carpeta de elementos en tu proyecto, debes crear una.
Para ello, haz clic con el botón derecho en la carpeta
app/
y, luego, haz clic en Nuevo > Carpeta > Carpeta de elementos. - Copia el archivo del modelo
tflite
con metadatos incorporados a la carpeta de elementos.
- Si no tienes una carpeta de elementos en tu proyecto, debes crear una.
Para ello, haz clic con el botón derecho en la carpeta
Agrega lo siguiente al archivo
build.gradle
de tu app para asegurarte de que Gradle no comprima el archivo del modelo cuando se compile la app:android { // ... aaptOptions { noCompress "tflite" } }
El archivo del modelo se incluirá en el paquete de la app y estará disponible como elemento sin procesar.
Configura una fuente de modelo alojada en Firebase
Para usar el modelo alojado de forma remota, crea un objeto RemoteModel
y especifica el nombre que le asignaste al modelo cuando lo publicaste:
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()
Luego, inicia la tarea de descarga del modelo y especifica las condiciones en las que deseas permitir la descarga. Si el modelo no está en el dispositivo o si hay una versión más reciente de este, la tarea descargará el modelo de Firebase de forma asíncrona:
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.
}
Muchas apps comienzan la tarea de descarga en su código de inicialización, pero puedes hacerlo en cualquier momento antes de usar el modelo.
Crea un detector de objetos a partir de tu modelo
Después de configurar las fuentes de tu modelo, crea un objeto ObjectDetector
a partir de una de ellas.
Si solo tienes un modelo empaquetado a nivel local, crea un detector de objetos a partir del archivo de modelo y configura el umbral de puntuación de confianza que deseas solicitar (consulta Evalúa tu 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)
Si tienes un modelo alojado de forma remota, comprueba si se descargó antes de ejecutarlo. Puedes verificar el estado de la tarea de descarga del modelo con el método isModelDownloaded()
del administrador del modelo.
Aunque solo debes confirmarlo antes de ejecutar el detector de objetos, si tienes un modelo alojado de forma remota y uno empaquetado localmente, sería acertado realizar esta verificación cuando se crea una instancia de detector de objetos: crea un intérprete desde el modelo remoto si se descargó o, en su defecto, desde el modelo local.
Java
FirebaseModelManager.getInstance().isModelDownloaded(remoteModel)
.addOnSuccessListener(new OnSuccessListener<Boolean>() {
@Override
public void onSuccess(Boolean isDownloaded) {
}
});
Kotlin
FirebaseModelManager.getInstance().isModelDownloaded(remoteModel)
.addOnSuccessListener { success ->
}
Si solo tienes un modelo alojado de forma remota, debes inhabilitar la funcionalidad relacionada con el modelo, por ejemplo, ocultar o inhabilitar parte de tu IU, hasta que confirmes que el modelo se descargó. Puedes hacerlo si adjuntas un objeto de escucha al método download()
del administrador de modelos.
Una vez que confirmes que se descargó el modelo, crea un detector de objetos a partir del archivo 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. Prepara la imagen de entrada
Luego, deberás crear un objeto TensorImage
a partir de tu imagen por cada imagen que quieras etiquetar. Puedes crear un objeto TensorImage
a partir de un Bitmap
con el método fromBitmap
:
Java
TensorImage image = TensorImage.fromBitmap(bitmap);
Kotlin
val image = TensorImage.fromBitmap(bitmap)
Si los datos de tus imágenes no están en un Bitmap
, puedes cargar un arreglo de píxeles como se muestra en la documentación de TensorFlow Lite.
3. Ejecuta el detector de objetos
Para detectar los objetos de una imagen, pasa el objeto TensorImage
al método detect()
de ObjectDetector
.
Java
List<Detection> results = objectDetector.detect(image);
Kotlin
val results = objectDetector.detect(image)
4. Obtén información sobre los objetos etiquetados
Si la operación de detección de objetos se ejecuta correctamente, se mostrará una lista de objetos Detection
. Cada objeto Detection
representa un elemento detectado en la imagen. Puedes obtener el cuadro de límite de cada objeto y sus etiquetas.
Por ejemplo:
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()
}
Sugerencias para mejorar el rendimiento en tiempo real
Si quieres etiquetar imágenes en una aplicación en tiempo real, sigue estos lineamientos para lograr la mejor velocidad de fotogramas:
- Limita las llamadas al etiquetador de imágenes. Si surge un fotograma de video nuevo mientras se ejecuta el etiquetador de imágenes, ignora ese fotograma. Consulta la clase
VisionProcessorBase
de la app de ejemplo de la guía de inicio rápido para ver un ejemplo. - Si usas la salida del etiquetador de imágenes para superponer gráficos en la imagen de entrada, primero obtén el resultado y, luego, renderiza la imagen y la superposición en un solo paso. De esta manera, renderizas en la superficie de visualización
solo una vez por cada fotograma de entrada. Consulta las clases
CameraSourcePreview
yGraphicOverlay
en la app de ejemplo de la guía de inicio rápido para ver un ejemplo. -
Si usas la API de Camera2, captura imágenes en formato
ImageFormat.YUV_420_888
.Si usas la API de Camera más antigua, captura imágenes en formato
ImageFormat.NV21
.