IA y Visión ArtificialIngeniero

Clasificador de enfermedades de plantas con un modelo TensorFlow Lite

Apunta la cámara a una hoja y un modelo de clasificación de imágenes te dice si se ve sana o muestra señales de una enfermedad común.

NivelIngeniero
Tiempo3 h
Costo est.~$147
Pasos5

Los clasificadores de imágenes aprenden de miles de fotos etiquetadas. Entrenas un modelo pequeño con un conjunto público de hojas enfermas en tu computadora o en un cuaderno gratuito, lo exportas como archivo .tflite y el Pi lo corre localmente con LiteRT en una fracción de segundo.

Pasos de la misión

  1. Entrena un modelo

    Entrena un clasificador de imágenes con un conjunto público como PlantVillage (o tus propias fotos etiquetadas) y expórtalo a TensorFlow Lite con un archivo labels.txt.

  2. Instala el runtime

    En un venv creado con --system-site-packages, corre pip install ai-edge-litert numpy.

  3. Copia los archivos

    Pon plant_model.tflite y labels.txt junto al script en el Pi.

  4. Clasifica una hoja

    Llena el cuadro con una sola hoja sobre un fondo liso con luz de día y corre el script.

  5. Revisa el resultado

    Toma las respuestas de baja confianza como 'desconocido' y confirma cualquier enfermedad con un servicio de extensión agrícola local.

Código

import numpy as np
from picamera2 import Picamera2
from ai_edge_litert.interpreter import Interpreter

labels = [l.strip() for l in open('labels.txt')]
interp = Interpreter(model_path='plant_model.tflite')
interp.allocate_tensors()
inp, out = interp.get_input_details()[0], interp.get_output_details()[0]
h, w = inp['shape'][1:3]

cam = Picamera2()
cam.configure(cam.create_still_configuration(main={'size': (int(w), int(h)), 'format': 'RGB888'}))
cam.start()
img = cam.capture_array()[..., ::-1]               # BGR -> RGB

x = np.expand_dims(img, 0)
if inp['dtype'] == np.float32:
    x = x.astype(np.float32) / 127.5 - 1.0         # match how your model was trained
else:
    x = x.astype(inp['dtype'])
interp.set_tensor(inp['index'], x)
interp.invoke()
scores = interp.get_tensor(out['index'])[0].astype(float)
best = int(np.argmax(scores))
print(f"{labels[best]}  ({scores[best] / scores.sum():.0%})")

Code comments are in English, like most libraries and docs — a good habit for makers.

Preguntas

Funciona con las fotos del conjunto pero no con mis plantas.

Las fotos de laboratorio tienen fondo liso y luz pareja. Agrega de 50 a 100 fotos de tus propias plantas por clase y vuelve a entrenar; casi siempre se arregla.