Inicio rápido para Android

Esta página le muestra cómo crear una aplicación de Android con TensorFlow Lite para analizar una transmisión de cámara en vivo e identificar objetos. Este caso de uso de aprendizaje automático se denomina detección de objetos . La aplicación de ejemplo usa 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 ML 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 Studio 4.2 o superior
  • Android SDK versión 21 o superior

Obtener el código de ejemplo

Cree una copia local del código de ejemplo para que pueda 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 el 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

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

Para importar y compilar 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 de 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 construye. 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 adjunto 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 para buscar objetos en una transmisión de video en vivo desde la cámara de un dispositivo Android. El código para esta función se encuentra principalmente en estos archivos:

  • ObjectDetectorHelper.kt : inicializa el entorno de tiempo de ejecución, habilita la aceleración de hardware y ejecuta el modelo de aprendizaje automático de detección de objetos.
  • CameraFragment.kt : crea el flujo de datos de imagen de la cámara, prepara los 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.

Crea 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 muestra 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 las funciones de utilidad de datos de ML. Estas funciones de utilidad convierten datos como imágenes en un formato de datos de tensor que puede procesar un modelo.

La aplicación de ejemplo usa 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 requeridas 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 .

Inicializa los servicios de Google Play

Cuando usa los servicios de Google Play para ejecutar modelos de TensorFlow Lite, debe inicializar el servicio antes de poder usarlo. Si desea utilizar el soporte de aceleración de hardware con el servicio, como la aceleración de GPU, también habilite 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. Use el método TfLiteVision.initialize() para habilitar el uso del tiempo de ejecución de los servicios de Play y configure un oyente 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. Debe almacenar sus modelos en el directorio src/main/assets de su 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. Configure 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. Usa 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.

Usted prepara los datos para que el modelo los interprete transformando los datos existentes, como imágenes, en el 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. Según el modelo que utilice, es posible que deba transformar los datos para que se ajusten a lo que espera el modelo. La aplicación de ejemplo usa un objeto ImageAnalysis para extraer fotogramas de imágenes del subsistema de la cámara.

Para preparar los datos para que los procese 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 las transformaciones de datos finales 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 creas un objeto TensorImage con datos de imagen en el formato correcto, puedes ejecutar el modelo contra 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 un modelo y generar predicciones a partir de datos de imagen:

  • 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 imágenes en el modelo de detección de objetos, genera una lista de resultados de predicción que el código de su aplicación debe manejar mediante la ejecución de lógica comercial adicional, la visualización de resultados al usuario o la realización de 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. Use un patrón de escucha para pasar los 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 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