Inicio rápido para Android

Esta página le muestra cómo crear una aplicación de Android con TensorFlow Lite para analizar la transmisión de una cámara en vivo e identificar objetos. Este caso de uso de aprendizaje automático se llama detección de objetos . La aplicación de ejemplo utiliza la biblioteca de tareas de TensorFlow Lite para la visión a través de los servicios de Google Play para permitir la ejecución del modelo de aprendizaje automático de detección de objetos, que es el enfoque recomendado para crear una aplicación de aprendizaje automático con TensorFlow Lite.

Demostración animada de detección de objetos

Configurar y ejecutar el ejemplo

Para la primera parte de este ejercicio, descargue el código de ejemplo de GitHub y ejecútelo con Android Studio . Las siguientes secciones de este documento exploran las secciones relevantes del ejemplo de código, para que pueda aplicarlas a sus propias aplicaciones de Android. Necesita tener instaladas las siguientes versiones de estas herramientas:

  • Android Estudio 4.2 o superior
  • Android SDK versión 21 o superior

Obtenga el código de ejemplo

Cree una copia local del código de ejemplo para poder compilarlo y ejecutarlo.

Para clonar y configurar el código de ejemplo:

  1. Clonar el repositorio git
    git clone https://github.com/tensorflow/examples.git
    
  2. Configure su instancia de git para usar pago disperso, de modo que solo tenga los archivos para la aplicación de ejemplo de detección de objetos:
    cd examples
    git sparse-checkout init --cone
    git sparse-checkout set lite/examples/object_detection/android_play_services
    

Importar y ejecutar el proyecto.

Utilice Android Studio para crear un proyecto a partir del código de ejemplo descargado, compilar el proyecto y ejecutarlo.

Para importar y construir el proyecto de código de ejemplo:

  1. Inicie Android Studio .
  2. En la página de bienvenida de Android Studio, elija Importar proyecto o seleccione Archivo > Nuevo > Importar proyecto .
  3. Navegue hasta el directorio del código de ejemplo que contiene el archivo build.gradle ( ...examples/lite/examples/object_detection/android_play_services/build.gradle ) y seleccione ese directorio.

Después de seleccionar este directorio, Android Studio crea un nuevo proyecto y lo compila. Cuando se completa la compilación, Android Studio muestra un mensaje BUILD SUCCESSFUL en el panel de estado de Salida de la compilación .

Para ejecutar el proyecto:

  1. Desde Android Studio, ejecute el proyecto seleccionando Ejecutar > Ejecutar… y MainActivity .
  2. Seleccione un dispositivo Android conectado con una cámara para probar la aplicación.

Cómo funciona la aplicación de ejemplo

La aplicación de ejemplo utiliza un modelo de detección de objetos previamente entrenado, como mobilenetv1.tflite , en formato TensorFlow Lite busca objetos en una transmisión de video en vivo desde la cámara de un dispositivo Android. El código para esta característica se encuentra principalmente en estos archivos:

  • ObjectDetectorHelper.kt : inicializa el entorno de ejecución, habilita la aceleración de hardware y ejecuta el modelo ML de detección de objetos.
  • CameraFragment.kt : crea el flujo de datos de imágenes de la cámara, prepara datos para el modelo y muestra los resultados de la detección de objetos.

Las siguientes secciones le muestran los componentes clave de estos archivos de código, para que pueda modificar una aplicación de Android para agregar esta funcionalidad.

Construye la aplicación

Las siguientes secciones explican los pasos clave para crear su propia aplicación de Android y ejecutar el modelo que se muestra en la aplicación de ejemplo. Estas instrucciones utilizan la aplicación de ejemplo que se mostró anteriormente como punto de referencia.

Agregar dependencias del proyecto

En su aplicación básica de Android, agregue las dependencias del proyecto para ejecutar modelos de aprendizaje automático de TensorFlow Lite y acceder a funciones de utilidad de datos de ML. Estas funciones de utilidad convierten datos como imágenes en un formato de datos tensorial que puede ser procesado por un modelo.

La aplicación de ejemplo utiliza la biblioteca de tareas TensorFlow Lite para la visión de los servicios de Google Play para permitir la ejecución del modelo de aprendizaje automático de detección de objetos. Las siguientes instrucciones explican cómo agregar las dependencias de biblioteca necesarias a su propio proyecto de aplicación de Android.

Para agregar dependencias de módulos:

  1. En el módulo de la aplicación de Android que usa TensorFlow Lite, actualice el archivo build.gradle del módulo para incluir las siguientes dependencias. En el código de ejemplo, este archivo se encuentra aquí: ...examples/lite/examples/object_detection/android_play_services/app/build.gradle

    ...
    dependencies {
    ...
        // Tensorflow Lite dependencies
        implementation 'org.tensorflow:tensorflow-lite-task-vision-play-services:0.4.2'
        implementation 'com.google.android.gms:play-services-tflite-gpu:16.1.0'
    ...
    }
    
  2. En Android Studio, sincronice las dependencias del proyecto seleccionando: Archivo > Sincronizar proyecto con archivos Gradle .

Inicializar los servicios de Google Play

Cuando utiliza los servicios de Google Play para ejecutar modelos de TensorFlow Lite, debe inicializar el servicio antes de poder usarlo. Si desea utilizar soporte de aceleración de hardware con el servicio, como aceleración de GPU, también debe habilitar ese soporte como parte de esta inicialización.

Para inicializar TensorFlow Lite con los servicios de Google Play:

  1. Cree un objeto TfLiteInitializationOptions y modifíquelo para habilitar la compatibilidad con GPU:

    val options = TfLiteInitializationOptions.builder()
        .setEnableGpuDelegateSupport(true)
        .build()
    
  2. Utilice el método TfLiteVision.initialize() para habilitar el uso del tiempo de ejecución de los servicios de Play y configure un detector para verificar que se cargó correctamente:

    TfLiteVision.initialize(context, options).addOnSuccessListener {
        objectDetectorListener.onInitialized()
    }.addOnFailureListener {
        // Called if the GPU Delegate is not supported on the device
        TfLiteVision.initialize(context).addOnSuccessListener {
            objectDetectorListener.onInitialized()
        }.addOnFailureListener{
            objectDetectorListener.onError("TfLiteVision failed to initialize: "
                    + it.message)
        }
    }
    

Inicializar el intérprete del modelo ML

Inicialice el intérprete del modelo de aprendizaje automático de TensorFlow Lite cargando el archivo del modelo y configurando los parámetros del modelo. Un modelo de TensorFlow Lite incluye un archivo .tflite que contiene el código del modelo. Debes almacenar tus modelos en el directorio src/main/assets de tu proyecto de desarrollo, por ejemplo:

.../src/main/assets/mobilenetv1.tflite`

Para inicializar el modelo:

  1. Agregue un archivo de modelo .tflite al directorio src/main/assets de su proyecto de desarrollo, como ssd_mobilenet_v1 .
  2. Configure la variable modelName para especificar el nombre de archivo de su modelo ML:

    val modelName = "mobilenetv1.tflite"
    
  3. Establezca las opciones para el modelo, como el umbral de predicción y el tamaño del conjunto de resultados:

    val optionsBuilder =
        ObjectDetector.ObjectDetectorOptions.builder()
            .setScoreThreshold(threshold)
            .setMaxResults(maxResults)
    
  4. Habilite la aceleración de GPU con las opciones y permita que el código falle correctamente si la aceleración no es compatible con el dispositivo:

    try {
        optionsBuilder.useGpu()
    } catch(e: Exception) {
        objectDetectorListener.onError("GPU is not supported on this device")
    }
    
    
  5. Utilice la configuración de este objeto para construir un objeto ObjectDetector de TensorFlow Lite que contenga el modelo:

    objectDetector =
        ObjectDetector.createFromFileAndOptions(
            context, modelName, optionsBuilder.build())
    

Para obtener más información sobre el uso de delegados de aceleración de hardware con TensorFlow Lite, consulte Delegados de TensorFlow Lite .

Preparar datos para el modelo.

Los datos se preparan para que el modelo los interprete transformando datos existentes, como imágenes, al formato de datos Tensor , para que su modelo pueda procesarlos. Los datos de un tensor deben tener dimensiones o formas específicas que coincidan con el formato de los datos utilizados para entrenar el modelo. Dependiendo del modelo que utilice, es posible que necesite transformar los datos para que se ajusten a lo que espera el modelo. La aplicación de ejemplo utiliza un objeto ImageAnalysis para extraer fotogramas de imágenes del subsistema de la cámara.

Para preparar datos para su procesamiento por el modelo:

  1. Cree un objeto ImageAnalysis para extraer imágenes en el formato requerido:

    imageAnalyzer =
        ImageAnalysis.Builder()
            .setTargetAspectRatio(AspectRatio.RATIO_4_3)
            .setTargetRotation(fragmentCameraBinding.viewFinder.display.rotation)
            .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
            .setOutputImageFormat(OUTPUT_IMAGE_FORMAT_RGBA_8888)
            .build()
            ...
    
  2. Conecte el analizador al subsistema de la cámara y cree un búfer de mapa de bits para contener los datos recibidos de la cámara:

            .also {
            it.setAnalyzer(cameraExecutor) { image ->
                if (!::bitmapBuffer.isInitialized) {
                    bitmapBuffer = Bitmap.createBitmap(
                        image.width,
                        image.height,
                        Bitmap.Config.ARGB_8888
                    )
                }
                detectObjects(image)
            }
        }
    
  3. Extraiga los datos de imagen específicos que necesita el modelo y pase la información de rotación de la imagen:

    private fun detectObjects(image: ImageProxy) {
        // Copy out RGB bits to the shared bitmap buffer
        image.use { bitmapBuffer.copyPixelsFromBuffer(image.planes[0].buffer) }
        val imageRotation = image.imageInfo.rotationDegrees
        objectDetectorHelper.detect(bitmapBuffer, imageRotation)
    }    
    
  4. Complete cualquier transformación de datos final y agregue los datos de la imagen a un objeto TensorImage , como se muestra en el método ObjectDetectorHelper.detect() de la aplicación de ejemplo:

    val imageProcessor = ImageProcessor.Builder().add(Rot90Op(-imageRotation / 90)).build()
    
    // Preprocess the image and convert it into a TensorImage for detection.
    val tensorImage = imageProcessor.process(TensorImage.fromBitmap(image))
    

Ejecutar predicciones

Una vez que crea un objeto TensorImage con datos de imagen en el formato correcto, puede ejecutar el modelo con esos datos para producir una predicción o inferencia . En la aplicación de ejemplo, este código está contenido en el método ObjectDetectorHelper.detect() .

Para ejecutar el modelo y generar predicciones a partir de datos de imágenes:

  • Ejecute la predicción pasando los datos de la imagen a su función de predicción:

    val results = objectDetector?.detect(tensorImage)
    

Manejar la salida del modelo

Después de ejecutar datos de imagen en el modelo de detección de objetos, se produce una lista de resultados de predicción que el código de su aplicación debe manejar ejecutando lógica empresarial adicional, mostrando resultados al usuario o realizando otras acciones. El modelo de detección de objetos en la aplicación de ejemplo produce una lista de predicciones y cuadros delimitadores para los objetos detectados. En la aplicación de ejemplo, los resultados de la predicción se pasan a un objeto de escucha para su posterior procesamiento y visualización al usuario.

Para manejar los resultados de la predicción del modelo:

  1. Utilice un patrón de escucha para pasar resultados al código de su aplicación o a los objetos de la interfaz de usuario. La aplicación de ejemplo usa este patrón para pasar los resultados de la detección del objeto ObjectDetectorHelper al objeto CameraFragment :

    objectDetectorListener.onResults( // instance of CameraFragment
        results,
        inferenceTime,
        tensorImage.height,
        tensorImage.width)
    
  2. Actuar sobre los resultados, como mostrar la predicción al usuario. La aplicación de ejemplo dibuja una superposición en el objeto CameraPreview para mostrar el resultado:

    override fun onResults(
      results: MutableList<Detection>?,
      inferenceTime: Long,
      imageHeight: Int,
      imageWidth: Int
    ) {
        activity?.runOnUiThread {
            fragmentCameraBinding.bottomSheetLayout.inferenceTimeVal.text =
                String.format("%d ms", inferenceTime)
    
            // Pass necessary information to OverlayView for drawing on the canvas
            fragmentCameraBinding.overlay.setResults(
                results ?: LinkedList<Detection>(),
                imageHeight,
                imageWidth
            )
    
            // Force a redraw
            fragmentCameraBinding.overlay.invalidate()
        }
    }
    

Próximos pasos