Curso de Integración Módulos Nativos iOS/Android para Flutter

Procesar imágenes reales con TensorFlow Lite

Curso de Integración Módulos Nativos iOS/Android para Flutter

Contenido del curso

Acceso a sensores y cámara

Procesar imágenes reales con TensorFlow Lite

Resumen

Procesar imágenes reales con TensorFlow Lite en Flutter requiere modificar la función runModel para que reciba un archivo de imagen en lugar de un input generado por código. Este flujo te permite decodificar, redimensionar y normalizar píxeles RGB para que el modelo entregue predicciones precisas desde la galería del dispositivo.

Cómo recibir un archivo de imagen en el servicio runModel

El primer cambio ocurre en el servicio donde antes pasábamos una lista generada manualmente. Ahora la función debe aceptar un archivo real desde la galería.

En lugar de un listado, declara el parámetro imageFile y asegúrate de importar la librería de Dart que permite tratarlo como un objeto de tipo archivo. La validación inicial sobre si el modelo está cargado se mantiene intacta, porque sigue siendo la primera barrera antes de procesar cualquier entrada [00:30].

¿Por qué cambiar el input por un archivo? Porque generar imágenes desde código sirve solo para pruebas. Con un archivo real puedes alimentar al modelo con fotos del dispositivo y obtener resultados aplicables.

Cómo decodificar y redimensionar la imagen para el modelo

Antes de pasar la imagen al intérprete, hay que transformarla a un formato que TensorFlow Lite entienda. Aquí entra la librería image.dart.

Usa el prefijo img al importar para evitar conflictos de nombres. Luego declara una variable imageInput que reciba el resultado de img.decodeImage, esperando que imageFile se convierta en bytes con readAsBytes. Añade el operador ? para que el proceso solo corra si llega el archivo [01:30].

Luego viene la redimensión. El modelo espera entradas de 224x224 píxeles, así que aplica img.copyResized con tres argumentos:

  • La imagen decodificada como fuente.
  • El ancho objetivo en 224.
  • El alto objetivo en 224.

Esta etapa es crítica: si la imagen no coincide con las dimensiones esperadas por el modelo, el intérprete no podrá procesarla.

Cómo normalizar los píxeles RGB a valores entre 0 y 1

Una vez redimensionada, hay que recorrer cada píxel y convertir sus valores RGB en datos que el modelo pueda interpretar. Los modelos suelen trabajar con valores normalizados entre 0 y 1, no en el rango original 0 a 255.

Para lograrlo, arma un doble bucle for: uno que recorra el alto (y) y otro anidado que recorra el ancho (x), ambos limitados por resizeImage.height y resizeImage.width. Dentro del bucle interno usa getPixel(x, y) para extraer cada píxel.

Cómo asignar los canales R, G y B al tensor de entrada

Acá está el detalle que suele dar errores. En un primer intento, intentamos hacer la conversión usando operadores hexadecimales, pero los píxeles no se pueden asignar directamente a variables de tipo entero. La solución es usar las propiedades del objeto pixel:

  • pixel.r para el canal rojo.
  • pixel.g para el canal verde.
  • pixel.b para el canal azul.

Cada valor se divide entre 255 y se asigna a input[0][y][x][0], input[0][y][x][1] e input[0][y][x][2] respectivamente. Así normalizas los tres canales a un rango binario manejable por la red neuronal.

Cómo definir el estado inicial del input y cerrar el intérprete

Antes del bucle de píxeles necesitas un estado inicial para input. Si no llega imagen o no hay cambios en los colores, el modelo necesita una estructura base sobre la cual operar.

Usa List.generate para crear una matriz con la forma [1][224][224][3], donde:

  1. El primero es el batch size.
  2. Los siguientes dos representan alto y ancho.
  3. El último corresponde a los tres canales RGB.

Inicializa todos los valores en cero y sin filtros adicionales. Esto garantiza que el tensor tenga la forma correcta antes de poblarlo con los píxeles reales [05:40].

¿Qué hace interpreter.close()? Libera los recursos del modelo cuando ya no lo necesitas. Se invoca dentro de un condicional que verifica si el intérprete sigue existiendo, evitando errores de referencia nula.

Finalmente, ejecuta el intérprete con input y output como parámetros para obtener las predicciones. El output contiene el filtrado de probabilidades entre las clases del modelo y la imagen cargada.

Cómo probar el flujo completo en el emulador

Con el código listo, divide la terminal y corre flutter run en el emulador. La pantalla mostrará los dos botones del paso anterior y un mensaje indicando que no hay imagen seleccionada.

Al tocar seleccionar, accedes a la galería del dispositivo. Elige una imagen y verás cómo se carga con el tamaño definido. Pulsa el botón de ejecutar y el modelo devolverá los resultados con los match correspondientes a la imagen [08:30].

Con este flujo dejas atrás las imágenes generadas por código y trabajas con fotos reales. ¿Qué imagen vas a probar primero en tu modelo de TensorFlow Lite? Cuéntame en los comentarios.