Procesar imágenes reales con TensorFlow Lite
Curso de Integración Módulos Nativos iOS/Android para Flutter
Contenido del curso
Introducción a TensorFlow Lite
Integración de modelos y clasificación de imágenes
Reconocimiento de voz con Whisper
MethodChannel
Acceso a sensores y cámara
- 16

Configuración de Method Channel para cámara en Android desde Flutter
10:53 min - 17

Cámara iOS nativa con MethodChannel en Flutter
12:36 min - 18

Configuración de permisos y provider para cámara en Android
10:12 min - 19

Configuración de permisos de cámara en iOS para Flutter
06:38 min - 20

Integración de cámara nativa iOS en Flutter con Method Channels
13:51 min - 21

Controlador de cámara iOS con FlutterError
12:30 min - 22

Implementación de cámara nativa en apps Android con Flutter
12:22 min
Gestión de estado con BLoC
Reconocimiento de texto en imágenes
- 25

Parseo de montos desde texto OCR con regex
07:08 min - 26

Integración de UI con cámara para captura de fotos en Flutter
06:19 min - 27

Cámara en Flutter con BLoC y modal
08:59 min - 28

Actualización de dependencias y corrección de errores en Flutter iOS
15:44 min - 29

Diferencias entre Flutter y React Native para desarrollo móvil
11:54 min
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.rpara el canal rojo.pixel.gpara el canal verde.pixel.bpara 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:
- El primero es el batch size.
- Los siguientes dos representan alto y ancho.
- 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.