La tarea de MediaPipe Image Segmenter te permite dividir las imágenes en regiones según categorías predefinidas para aplicar efectos visuales, como desenfoque de fondo. En estas instrucciones, se muestra cómo usar el Segmentador de imágenes con apps para Android. El ejemplo de código que se describe en estas instrucciones está disponible en GitHub. Para obtener más información sobre las funciones, los modelos y las opciones de configuración de esta tarea, consulta la descripción general.
Ejemplo de código
El ejemplo de código de MediaPipe Tasks contiene dos implementaciones simples de una app de Image Segmenter para Android:
- Segmentador de imágenes con una máscara de categoría
- Segmentador de imágenes con una máscara de confianza
En los ejemplos, se usa la cámara de un dispositivo Android físico para realizar la segmentación de imágenes en un feed de cámara en vivo, o bien puedes elegir imágenes y videos de la galería del dispositivo. Puedes usar las apps como punto de partida para tu propia app para Android o consultarlas cuando modifiques una app existente. El código de ejemplo de Image Segmenter se aloja en GitHub.
En las siguientes secciones, se hace referencia a la app Image Segmenter with a category mask.
Descarga el código
En las siguientes instrucciones, se muestra cómo crear una copia local del código de ejemplo con la herramienta de línea de comandos git.
Para descargar el código de ejemplo, sigue estos pasos:
- Clona el repositorio de git con el siguiente comando:
git clone https://github.com/google-ai-edge/mediapipe-samples
- De manera opcional, configura tu instancia de git para usar el control de revisión disperso, de modo que solo tengas los archivos de la app de ejemplo de Image Segmenter:
cd mediapipe git sparse-checkout init --cone git sparse-checkout set examples/image_segmentation/android
Después de crear una versión local del código de ejemplo, puedes importar el proyecto a Android Studio y ejecutar la app. Para obtener instrucciones, consulta la Guía de configuración para Android.
Componentes clave
Los siguientes archivos contienen el código fundamental de esta aplicación de ejemplo de segmentación de imágenes:
- ImageSegmenterHelper.kt: Inicializa la tarea de Image Segmenter y controla el modelo y la selección del delegado.
- CameraFragment.kt: Proporciona la interfaz de usuario y el código de control de una cámara.
- GalleryFragment.kt: Proporciona la interfaz de usuario y el código de control para seleccionar archivos de imagen y video.
- OverlayView.kt: Controla y da formato a los resultados de la segmentación.
Configuración
En esta sección, se describen los pasos clave para configurar tu entorno de desarrollo y proyectos de código para usar Image Segmenter. Si deseas obtener información general sobre cómo configurar tu entorno de desarrollo para usar tareas de MediaPipe, incluidos los requisitos de la versión de la plataforma, consulta la Guía de configuración para Android.
Dependencias
Image Segmenter usa la biblioteca com.google.mediapipe:tasks-vision
. Agrega esta dependencia al archivo build.gradle
de tu proyecto de desarrollo de apps para Android. Importa las dependencias requeridas con
el siguiente código:
dependencies {
...
implementation 'com.google.mediapipe:tasks-vision:latest.release'
}
Modelo
La tarea de MediaPipe Image Segmenter requiere un modelo entrenado que sea compatible con esta tarea. Para obtener más información sobre los modelos entrenados disponibles para Image Segmenter, consulta la sección Modelos de la descripción general de la tarea.
Selecciona y descarga el modelo, y guárdalo en el directorio de tu proyecto:
<dev-project-root>/src/main/assets
Usa el método BaseOptions.Builder.setModelAssetPath()
para especificar la ruta que usa el modelo. En el ejemplo de código de la siguiente sección, se hace referencia a este método.
En el código de ejemplo del segmentador de imágenes, el modelo se define en la clase ImageSegmenterHelper.kt
de la función setupImageSegmenter()
.
Crea la tarea
Puedes usar la función createFromOptions
para crear la tarea. La función createFromOptions
acepta opciones de configuración, incluidos los tipos de salida de la máscara. Para obtener más información sobre la configuración de tareas, consulta
Opciones de configuración.
La tarea de Segmentador de imágenes admite los siguientes tipos de datos de entrada: imágenes fijas, archivos de video y transmisiones de video en vivo. Cuando crees la tarea, debes especificar el modo de ejecución correspondiente al tipo de datos de entrada. Elige la pestaña de tu tipo de datos de entrada para ver cómo crear esa tarea.
Imagen
ImageSegmenterOptions options = ImageSegmenterOptions.builder() .setBaseOptions( BaseOptions.builder().setModelAssetPath("model.tflite").build()) .setRunningMode(RunningMode.IMAGE) .setOutputCategoryMask(true) .setOutputConfidenceMasks(false) .build(); imagesegmenter = ImageSegmenter.createFromOptions(context, options);
Video
ImageSegmenterOptions options = ImageSegmenterOptions.builder() .setBaseOptions( BaseOptions.builder().setModelAssetPath("model.tflite").build()) .setRunningMode(RunningMode.VIDEO) .setOutputCategoryMask(true) .setOutputConfidenceMasks(false) .build(); imagesegmenter = ImageSegmenter.createFromOptions(context, options);
Transmisión en vivo
ImageSegmenterOptions options = ImageSegmenterOptions.builder() .setBaseOptions( BaseOptions.builder().setModelAssetPath("model.tflite").build()) .setRunningMode(RunningMode.LIVE_STREAM) .setOutputCategoryMask(true) .setOutputConfidenceMasks(false) .setResultListener((result, inputImage) -> { // Process the segmentation result here. }) .setErrorListener((result, inputImage) -> { // Process the segmentation errors here. }) .build() imagesegmenter = ImageSegmenter.createFromOptions(context, options)
La implementación del código de ejemplo de Image Segmenter permite al usuario cambiar entre los modos de procesamiento. El enfoque hace que el código de creación de tareas sea más complicado y es posible que no sea adecuado para tu caso de uso. Puedes ver este código en la clase ImageSegmenterHelper
a través de la función setupImageSegmenter()
.
Opciones de configuración
Esta tarea tiene las siguientes opciones de configuración para apps para Android:
Nombre de la opción | Descripción | Rango de valores | Valor predeterminado |
---|---|---|---|
runningMode |
Establece el modo de ejecución de la tarea. Existen tres modos: IMAGE: Es el modo para entradas de una sola imagen. VIDEO: Es el modo para los fotogramas decodificados de un video. LIVE_STREAM: Es el modo de transmisión en vivo de datos de entrada, como los de una cámara. En este modo, se debe llamar a resultListener para configurar un objeto de escucha que reciba resultados de forma asíncrona. |
{IMAGE, VIDEO, LIVE_STREAM } |
IMAGE |
outputCategoryMask |
Si se establece en True , el resultado incluye una máscara de segmentación como una imagen uint8, en la que cada valor de píxel indica el valor de la categoría ganadora. |
{True, False } |
False |
outputConfidenceMasks |
Si se establece en True , el resultado incluye una máscara de segmentación como una imagen de valor de punto flotante, en la que cada valor de punto flotante representa el mapa de puntuación de confianza de la categoría. |
{True, False } |
True |
displayNamesLocale |
Establece el idioma de las etiquetas que se usarán para los nombres visibles proporcionados en los metadatos del modelo de la tarea, si están disponibles. El valor predeterminado es en para el inglés. Puedes agregar etiquetas localizadas a los metadatos de un modelo personalizado con la API de Metadata Writer de TensorFlow Lite. |
Código de configuración regional | en |
resultListener |
Establece el objeto de escucha de resultados para que reciba los resultados de la segmentación de forma asíncrona cuando el segmentador de imágenes esté en el modo LIVE_STREAM .
Solo se puede usar cuando el modo de ejecución está configurado como LIVE_STREAM . |
N/A | N/A |
errorListener |
Establece un objeto de escucha de errores opcional. | N/A | Sin establecer |
Preparar los datos
El Segmentador de imágenes funciona con imágenes, archivos de video y videos de transmisiones en vivo. La tarea controla el procesamiento previo de la entrada de datos, incluido el cambio de tamaño, la rotación y la normalización de valores.
Debes convertir la imagen o el fotograma de entrada en un objeto com.google.mediapipe.framework.image.MPImage
antes de pasarlo al segmentador de imágenes.
Imagen
import com.google.mediapipe.framework.image.BitmapImageBuilder; import com.google.mediapipe.framework.image.MPImage; // Load an image on the user’s device as a Bitmap object using BitmapFactory. // Convert an Android’s Bitmap object to a MediaPipe’s Image object. Image mpImage = new BitmapImageBuilder(bitmap).build();
Video
import com.google.mediapipe.framework.image.BitmapImageBuilder; import com.google.mediapipe.framework.image.MPImage; // Load a video file on the user's device using MediaMetadataRetriever // From the video’s metadata, load the METADATA_KEY_DURATION and // METADATA_KEY_VIDEO_FRAME_COUNT value. You’ll need them // to calculate the timestamp of each frame later. // Loop through the video and load each frame as a Bitmap object. // Convert the Android’s Bitmap object to a MediaPipe’s Image object. Image mpImage = new BitmapImageBuilder(frame).build();
Transmisión en vivo
import com.google.mediapipe.framework.image.MediaImageBuilder; import com.google.mediapipe.framework.image.MPImage; // Create a CameraX’s ImageAnalysis to continuously receive frames // from the device’s camera. Configure it to output frames in RGBA_8888 // format to match with what is required by the model. // For each Android’s ImageProxy object received from the ImageAnalysis, // extract the encapsulated Android’s Image object and convert it to // a MediaPipe’s Image object. android.media.Image mediaImage = imageProxy.getImage() Image mpImage = new MediaImageBuilder(mediaImage).build();
En el código de ejemplo de Image Segmenter, la función segmentLiveStreamFrame()
controla la preparación de los datos en la clase ImageSegmenterHelper
.
Ejecuta la tarea
Llamas a una función segment
diferente según el modo de ejecución que uses.
La función Image Segmenter muestra las regiones de segmentos identificadas dentro de la imagen o el fotograma de entrada.
Imagen
ImageSegmenterResult segmenterResult = imagesegmenter.segment(image);
Video
// Calculate the timestamp in milliseconds of the current frame. long frame_timestamp_ms = 1000 * video_duration * frame_index / frame_count; // Run inference on the frame. ImageSegmenterResult segmenterResult = imagesegmenter.segmentForVideo(image, frameTimestampMs);
Transmisión en vivo
// Run inference on the frame. The segmentations results will be available via // the `resultListener` provided in the `ImageSegmenterOptions` when the image // segmenter was created. imagesegmenter.segmentAsync(image, frameTimestampMs);
Ten en cuenta lo siguiente:
- Cuando se ejecuta en el modo de video o en el modo de transmisión en vivo, también debes proporcionar la marca de tiempo del fotograma de entrada a la tarea del segmentador de imágenes.
- Cuando se ejecuta en el modo de imagen o de video, la tarea del segmentador de imágenes bloquea el subproceso actual hasta que termina de procesar la imagen o el fotograma de entrada. Para evitar bloquear la interfaz de usuario, ejecuta el procesamiento en un subproceso en segundo plano.
- Cuando se ejecuta en el modo de transmisión en vivo, la tarea del segmentador de imágenes no bloquea el subproceso actual, sino que se muestra de inmediato. Invocará su objeto de escucha de resultados con el resultado de la detección cada vez que termine de procesar un fotograma de entrada. Si se llama a la función
segmentAsync
cuando la tarea del segmentador de imágenes está ocupada procesando otro fotograma, la tarea ignora el nuevo fotograma de entrada.
En el código de ejemplo de Image Segmenter, las funciones segment
se definen en el archivo ImageSegmenterHelper.kt
.
Cómo controlar y mostrar los resultados
Cuando se ejecuta la inferencia, la tarea del segmentador de imágenes muestra un objeto ImageSegmenterResult
que contiene los resultados de la tarea de segmentación. El contenido del resultado depende del outputType
que estableciste cuando configuraste la tarea.
En las siguientes secciones, se muestran ejemplos de los datos de resultado de esta tarea:
Confianza de la categoría
En las siguientes imágenes, se muestra una visualización del resultado de la tarea para una máscara de confianza de categoría. El resultado de la máscara de confianza contiene valores de números de punto flotante entre [0, 1]
.
Imagen original y resultado de la máscara de confianza de la categoría. Imagen de origen del conjunto de datos Pascal VOC 2012.
Valor de la categoría
En las siguientes imágenes, se muestra una visualización del resultado de la tarea para una máscara de valor de categoría. El rango de la máscara de categorías es [0, 255]
y cada valor de píxel representa el índice de categoría ganador del resultado del modelo. El índice de categoría ganador tiene la puntuación más alta entre las categorías que el modelo puede reconocer.
Imagen original y resultado de la máscara de categoría. Imagen de origen del conjunto de datos Pascal VOC 2012.