Clasificador de reciclaje con IA: cámara y servo
Pon una lata, botella o papel en la bandeja y un modelo entrenado inclina una rampa con servo hacia el contenedor correcto.
Este favorito de las ferias de ciencias combina aprendizaje automático y mecánica. Entrenas un modelo de imágenes con Teachable Machine usando fotos de tu propia basura reciclable, lo exportas como TensorFlow Lite y el Pi convierte cada predicción en un ángulo del servo.
Pasos de la misión
Arma el clasificador
Imprime o corta una bandeja sobre una rampa que un servo pueda inclinar hacia tres contenedores; monta la cámara arriba de la bandeja con fondo liso.
Entrena el modelo
En Teachable Machine crea un Image Project con clases como lata, plástico, papel y vacío; toma más de 100 fotos de cada una en la bandeja real.
Exporta y copia
Exporta como TensorFlow Lite (punto flotante) y copia model.tflite y labels.txt al Pi; instala ai-edge-litert en un venv.
Conecta servo y botón
Señal del servo a GPIO18 y un botón entre GPIO17 y GND para iniciar una clasificación.
Clasifica y ajusta
Presiona el botón, revisa el resultado y agrega fotos de los objetos que confunde.
Código
import numpy as np, time
from picamera2 import Picamera2
from gpiozero import AngularServo, Button
from ai_edge_litert.interpreter import Interpreter
ANGLE = {'can': -60, 'plastic': 0, 'paper': 60} # bin positions
labels = [l.strip().split(' ', 1)[-1] for l in open('labels.txt')] # '0 can' -> 'can'
interp = Interpreter(model_path='model.tflite'); interp.allocate_tensors()
inp, out = interp.get_input_details()[0], interp.get_output_details()[0]
cam = Picamera2()
cam.configure(cam.create_still_configuration(main={'size': (224, 224), 'format': 'RGB888'}))
cam.start()
chute, button = AngularServo(18, min_angle=-90, max_angle=90), Button(17)
chute.angle = 0
while True:
button.wait_for_press()
x = cam.capture_array()[..., ::-1].astype(np.float32) / 127.5 - 1.0
interp.set_tensor(inp['index'], x[np.newaxis])
interp.invoke()
scores = interp.get_tensor(out['index'])[0]
item = labels[int(np.argmax(scores))]
print(item, f"{scores.max():.0%}")
if item in ANGLE and scores.max() > 0.8:
chute.angle = ANGLE[item]; time.sleep(1.5); chute.angle = 0Code comments are in English, like most libraries and docs — a good habit for makers.
Preguntas
¿Sirve para el reciclaje real de la ciudad?
Es una demostración para aprender. Maneja un objeto limpio a la vez; las plantas reales usan muchos sensores. Sigue las reglas de reciclaje de tu ciudad para los contenedores de verdad.