Detecta objetos en imágenes con ML Kit: Android

1. Antes de comenzar

El Kit de AA es un SDK para dispositivos móviles que lleva la experiencia de Google en el aprendizaje automático integrado en el dispositivo a las apps para iOS y Android. Puedes usar las APIs de Vision y Natural Language, potentes y fáciles de usar, para resolver desafíos comunes en tus apps o crear experiencias del usuario nuevas. Todas se basan en los mejores modelos de AA de Google y se ofrecen sin costo.

Todas las APIs de ML Kit se ejecutan en el dispositivo, lo que permite casos de uso en tiempo real, por ejemplo, cuando quieres procesar una transmisión de cámara en vivo. Esto también significa que la funcionalidad está disponible sin conexión.

En este codelab, se te indicarán pasos simples para agregar la detección y el seguimiento de objetos (ODT) de una imagen determinada a tu app para Android existente. Ten en cuenta que este codelab usa algunos atajos para destacar el uso de la ODT de ML Kit.

Qué compilarás

En este codelab, compilarás una app para Android con ML Kit. Tu app usará la API de detección y seguimiento de objetos de ML Kit para detectar objetos en una imagen determinada.Al final, deberías ver algo similar a la imagen de la derecha.

Qué aprenderás

  • Cómo integrar el SDK de ML Kit en tu aplicación para Android
  • API de detección y seguimiento de objetos de ML Kit

Requisitos

  • Una versión reciente de Android Studio (v4.1.2 o posterior)
  • Emulador de Android Studio o un dispositivo Android físico
  • El código de muestra
  • Conocimientos básicos sobre el desarrollo de Android en Kotlin

Este codelab se enfoca en ML Kit. Los conceptos y los bloques de código no relevantes se pasan por alto y se proporcionan para que simplemente los copies y pegues.

2. Prepárate

Descarga el código

Haz clic en el siguiente vínculo a fin de descargar todo el código de este codelab:

Descomprime el archivo zip descargado. Esto descomprimirá una carpeta raíz (mlkit-android-main) con todos los recursos que necesitarás. Para este codelab, solo necesitarás las fuentes del subdirectorio object-detection.

El subdirectorio object-detection del repositorio mlkit-android contiene dos directorios:

  • android_studio_folder.pngstarter: Código inicial en el que se basa este codelab
  • android_studio_folder.pngfinal: Es el código completo de la app de ejemplo finalizada.

3. Agrega la API de detección y seguimiento de objetos de ML Kit al proyecto

Importa la app a Android Studio

Comencemos por importar la app de partida a Android Studio.

Abre Android Studio, selecciona Import Project (Gradle, Eclipse ADT, etc.) y elige la carpeta starter del código fuente que descargaste antes.

7c0f27882a2698ac.png

Cómo agregar las dependencias de la detección y el seguimiento de objetos de ML Kit

Las dependencias de ML Kit te permiten integrar el SDK de ODT de ML Kit en tu app. Agrega las siguientes líneas al final del archivo app/build.gradle de tu proyecto:

build.gradle

dependencies {
  // ...
  implementation 'com.google.mlkit:object-detection:16.2.4'
}

Sincroniza tu proyecto con archivos de Gradle

Para asegurarte de que todas las dependencias estén disponibles para tu app, debes sincronizar tu proyecto con los archivos Gradle en este punto.

Selecciona Sync Project with Gradle Files ( b451ab2d04d835f9.png) en la barra de herramientas de Android Studio.

(Si este botón está inhabilitado, asegúrate de importar solo starter/app/build.gradle , no todo el repositorio).

4. Ejecuta la app de partida

Ahora que importaste el proyecto a Android Studio y agregaste las dependencias para la detección y el seguimiento de objetos del Kit de AA, tienes todo listo para ejecutar la app por primera vez.

Conecta tu dispositivo Android a través de USB al host o inicia el emulador de Android Studio y haz clic en Run ( execute.png) en la barra de herramientas de Android Studio.

Cómo ejecutar y explorar la app

La app debería iniciarse en tu dispositivo Android. Tiene código de plantilla para que puedas capturar una foto o seleccionar una imagen predeterminada y enviarla a una canalización de detección y seguimiento de objetos que compilarás en este codelab. Exploremos un poco la app antes de escribir código.

Primero, hay un botón ( c6d965d639c3646.png) en la parte inferior para lo siguiente:

  • abre la app de cámara integrada en tu dispositivo o emulador
  • tomar una foto en la app de la cámara
  • recibe la imagen capturada en la app de partida
  • muestra la imagen

Prueba el botón Take photo, sigue las indicaciones para tomar una foto, acepta la foto y observa cómo se muestra en la app de partida.

Repite el proceso algunas veces para ver cómo funciona:

9ec541980dbe2d31.png 8312dde41425ba4b.png fa8492bfc1914ff0.png

En segundo lugar, puedes elegir entre 3 imágenes predeterminadas. Puedes usar estas imágenes más adelante para probar el código de detección de objetos si ejecutas el código en un emulador de Android.

Selecciona una imagen de las 3 imágenes predeterminadas. Observa que la imagen aparece en la vista ampliada:

1dd41b3ec978f1d9.png

5. Cómo agregar la detección de objetos integrada en el dispositivo

En este paso, agregarás la funcionalidad a la app de partida para detectar objetos en imágenes. Como viste en el paso anterior, la app de partida contiene código de plantilla para tomar fotos con la app de cámara del dispositivo. También hay 3 imágenes predeterminadas en la app en las que puedes probar la detección de objetos si ejecutas el codelab en un emulador de Android.

Cuando seleccionas una imagen, ya sea de las imágenes predeterminadas o tomas una foto con la app de la cámara, el código de plantilla de texto decodifica esa imagen en una instancia de Bitmap, la muestra en la pantalla y llama al método runObjectDetection con la imagen.

En este paso, agregarás código al método runObjectDetection para realizar la detección de objetos.

Configura y ejecuta la detección de objetos integrada en el dispositivo en una imagen

Solo hay 3 pasos simples con 3 APIs para configurar el ODT de ML Kit:

  • Prepara una imagen: InputImage
  • Crea un objeto detector: ObjectDetection.getClient(options)
  • conecta los 2 objetos anteriores: process(image)

Puedes hacerlo dentro de la función runObjectDetection(bitmap: Bitmap) en el archivo MainActivity.kt.

/**
 * ML Kit Object Detection Function
 */
private fun runObjectDetection(bitmap: Bitmap) {
}

En este momento, la función está vacía. Continúa con los siguientes pasos para implementar el ODT de ML Kit. Durante el proceso, Android Studio te pedirá que agregues las importaciones necesarias:

  • com.google.mlkit.vision.common.InputImage
  • com.google.mlkit.vision.objects.ObjectDetection
  • com.google.mlkit.vision.objects.defaults.ObjectDetectorOptions

Paso 1: Crea un InputImage

ML Kit proporciona una API simple para crear un InputImage a partir de un Bitmap. Luego, puedes ingresar un InputImage en las APIs de ML Kit.

// Step 1: create ML Kit's InputImage object
val image = InputImage.fromBitmap(bitmap, 0)

Agrega el código anterior a la parte superior de runObjectDetection(bitmap:Bitmap).

Paso 2: Crea una instancia del detector

ML Kit sigue el patrón de diseño del compilador. Pasarás la configuración al compilador y, luego, adquirirás un detector a partir de ella. Hay 3 opciones para configurar (en este codelab, se usan las opciones en negrita):

  • modo de detector (imagen única o transmisión)
  • modo de detección (detección de objetos única o múltiple)
  • modo de clasificación (activado o desactivado)

Este codelab es para una sola imagen: detección y clasificación de varios objetos. Agrégala ahora:

// Step 2: acquire detector object
val options = ObjectDetectorOptions.Builder()
   .setDetectorMode(ObjectDetectorOptions.SINGLE_IMAGE_MODE)
   .enableMultipleObjects()
   .enableClassification()
   .build()
val objectDetector = ObjectDetection.getClient(options)

Paso 3: Envía imágenes al detector

La detección y clasificación de objetos es un procesamiento asíncrono:

  • Enviaste una imagen al detector (a través de process()).
  • El detector trabaja bastante en ello.
  • El detector te informa el resultado mediante una devolución de llamada.

El siguiente código hace exactamente eso (lo copia y lo agrega al código existente dentro de fun runObjectDetection(bitmap:Bitmap)):.

// Step 3: feed given image to detector and setup callback
objectDetector.process(image)
   .addOnSuccessListener {
       // Task completed successfully
        debugPrint(it)
   }
   .addOnFailureListener {
       // Task failed with an exception
       Log.e(TAG, it.message.toString())
   }

Cuando finalice, el detector te notificará lo siguiente:

  • Es la cantidad total de objetos detectados. Cada objeto detectado se describe con lo siguiente:
  • trackingId: Es un número entero que usas para hacer un seguimiento de los fotogramas cruzados (NO se usa en este codelab).
  • boundingBox: Es el cuadro de límite del objeto.
  • labels: Una lista de etiquetas para el objeto detectado (solo cuando la clasificación está habilitada):
  • index (Obtén el índice de esta etiqueta)
  • text (Obtén el texto de esta etiqueta, incluidas las palabras "Productos de moda", "Comida", "Productos para el hogar", "Lugar" y "Planta")
  • confidence ( un número de punto flotante entre 0.0 y 1.0, en el que 1.0 significa 100%)

Es probable que hayas notado que el código realiza un tipo de procesamiento printf para el resultado detectado con debugPrint().

Agrégalo a la clase MainActivity:

private fun debugPrint(detectedObjects: List<DetectedObject>) {
   detectedObjects.forEachIndexed { index, detectedObject ->
       val box = detectedObject.boundingBox

       Log.d(TAG, "Detected object: $index")
       Log.d(TAG, " trackingId: ${detectedObject.trackingId}")
       Log.d(TAG, " boundingBox: (${box.left}, ${box.top}) - (${box.right},${box.bottom})")
       detectedObject.labels.forEach {
           Log.d(TAG, " categories: ${it.text}")
           Log.d(TAG, " confidence: ${it.confidence}")
       }
   }
}

Ya está todo listo para aceptar imágenes para la detección.

Ejecutemos el codelab haciendo clic en Run ( execute.png) en la barra de herramientas de Android Studio. Intenta seleccionar una imagen predeterminada o toma una foto y, luego, observa la ventana de Logcat( 16bd6ea224cf8cf1.png) dentro del IDE.

Deberías ver un resultado similar a este:

D/MLKit Object Detection: Detected object: 0
D/MLKit Object Detection:  trackingId: null
D/MLKit Object Detection:  boundingBox: (481, 2021) - (2426,3376)
D/MLKit Object Detection:  categories: Food
D/MLKit Object Detection:  confidence: 0.90234375
D/MLKit Object Detection: Detected object: 1
D/MLKit Object Detection:  trackingId: null
D/MLKit Object Detection:  boundingBox: (2639, 2633) - (3058,3577)
D/MLKit Object Detection: Detected object: 2
D/MLKit Object Detection:  trackingId: null
D/MLKit Object Detection:  boundingBox: (3, 1816) - (615,2597)
D/MLKit Object Detection:  categories: Home good
D/MLKit Object Detection:  confidence: 0.75390625

… lo que significa que el detector vio 3 objetos:

  • Las categorías son Comida y Artículos para el hogar.
  • No se muestra ninguna categoría para el segundo puesto porque es una clase desconocida.
  • No hay trackingId (porque este es el modo de detección de imágenes individuales).
  • Es la posición dentro del rectángulo boundingBox (p. ej., (481, 2021) – (2426, 3376)).
  • El detector tiene bastante confianza en que la primera es una Comida (90% de confianza, era una ensalada).

Técnicamente, eso es todo lo que necesitas para que funcione la detección de objetos de ML Kit. Ya lo tienes todo en este momento. ¡Felicitaciones!

En el lado de la IU, todavía estás en la etapa en la que empezaste, pero podrías usar los resultados detectados en la IU, como dibujar el cuadro de límite para crear una mejor experiencia. Pasemos al siguiente paso: el procesamiento posterior de los resultados detectados.

6. Procesamiento posterior de los resultados de la detección

En los pasos anteriores, imprimiste el resultado detectado en logcat: es simple y rápido.

En esta sección, usarás el resultado en la imagen:

  • dibuja el cuadro de límite en la imagen
  • dibuja el nombre de la categoría y la confianza dentro del cuadro de límite

Información sobre las utilidades de visualización

Hay un código de plantilla en el codelab para ayudarte a visualizar el resultado de la detección. Aprovecha estas utilidades para simplificar nuestro código de visualización:

  • data class BoxWithText(val box: Rect, val text: String) Esta es una clase de datos para almacenar un resultado de detección de objetos para la visualización. box es el cuadro de límite en el que se encuentra el objeto, y text es la cadena de resultados de detección que se mostrará junto con el cuadro de límite del objeto.
  • fun drawDetectionResult(bitmap: Bitmap, detectionResults: List<BoxWithText>): Bitmap Este método dibuja los resultados de la detección de objetos en detectionResults en la entrada bitmap y muestra la copia modificada.

Este es un ejemplo de un resultado del método de utilidad drawDetectionResult:

58c6f1d4ddb00dfa.png

Visualiza el resultado de la detección de ML Kit

Usa las utilidades de visualización para dibujar el resultado de la detección de objetos de ML Kit sobre la imagen de entrada.

Ve a la ubicación a la que llamas a debugPrint() y agrega el siguiente fragmento de código debajo:

// Parse ML Kit's DetectedObject and create corresponding visualization data
val detectedObjects = it.map { obj ->
    var text = "Unknown"

    // We will show the top confident detection result if it exist
    if (obj.labels.isNotEmpty()) {
        val firstLabel = obj.labels.first()
        text = "${firstLabel.text}, ${firstLabel.confidence.times(100).toInt()}%"
    }
    BoxWithText(obj.boundingBox, text)
}

// Draw the detection result on the input bitmap
val visualizedResult = drawDetectionResult(bitmap, detectedObjects)

// Show the detection result on the app screen
runOnUiThread {
    inputImageView.setImageBitmap(visualizedResult)
}
  • Primero, debes analizar el DetectedObject de ML Kit y crear una lista de objetos BoxWithText para mostrar el resultado de la visualización.
  • Luego, dibujas el resultado de la detección sobre la imagen de entrada con el método de utilidad drawDetectionResult y lo muestras en la pantalla.

Ejecución

Ahora, haz clic en Run ( execute.png) en la barra de herramientas de Android Studio.

Una vez que se cargue la app, presiona el botón con el ícono de cámara, apunta la cámara a un objeto, toma una foto, acepta la foto (en la app de Cámara) o presiona fácilmente cualquier imagen predeterminada. Deberías ver los resultados de la detección. Vuelve a presionar el botón o selecciona otra imagen para repetir el proceso un par de veces y probar la ODT de ML Kit más reciente.

a03109cb30d5014d.png

7. ¡Felicitaciones!

Usaste ML Kit para agregar capacidades de detección de objetos a tu app:

  • 3 pasos con 3 APIs
  • Crea una imagen de entrada
  • Cómo crear un detector
  • Cómo enviar una imagen al detector

Eso es todo lo que necesitas para comenzar a usarlo.

A medida que avances, te recomendamos que mejores el modelo: como puedes ver, el modelo predeterminado solo puede reconocer 5 categorías, y ni siquiera sabe qué son un cuchillo, un tenedor ni una botella. Consulta el otro codelab de nuestra ruta de aprendizaje de Aprendizaje automático integrado en el dispositivo: Detección de objetos para aprender a entrenar un modelo personalizado.

Temas abordados

  • Cómo agregar la detección y el seguimiento de objetos del Kit de AA a tu app para Android
  • Cómo usar la detección y el seguimiento de objetos integrados en el dispositivo en ML Kit para detectar objetos en imágenes

Próximos pasos

  • Explora más con el ODT de ML Kit con más imágenes y videos en vivo para experimentar la precisión y el rendimiento de la detección y la clasificación
  • Consulta la ruta de aprendizaje de detección de objetos de Aprendizaje automático integrado en el dispositivo para aprender a entrenar un modelo personalizado.
  • Aplica el ODT de ML Kit en tu propia app para Android

Más información