import streamlit as st
from huggingface_hub import snapshot_download
import tensorflow as tf
import numpy as np
from PIL import Image
import requests
import os
import csv
import datetime
from huggingface_hub import HfApi, Repository
import subprocess
# Configuración de página y tema
st.set_page_config(page_title="GreenVision", page_icon="🌿", layout="centered")
# Banner con logo y título
logo = Image.open("greenvision_logo.png")
st.image(logo, width=70)
st.markdown(
"""
GreenVision
¿No sabes cómo separar tus residuos?
¡Usa GreenVision y descúbrelo al instante!
Sube una foto y nuestra IA te dirá el tipo de residuo.
""",
unsafe_allow_html=True,
)
CACHE_DIR = "/tmp/hf_cache"
os.makedirs(CACHE_DIR, exist_ok=True)
os.environ["HF_HOME"] = CACHE_DIR
@st.cache_resource
def load_model():
model_dir = snapshot_download(
repo_id="LuisTo97/greenvisionmodel",
cache_dir=CACHE_DIR
)
return tf.keras.models.load_model(model_dir, compile=False)
model = load_model()
CLASS_NAMES = ['Hazardous', 'Organic', 'Recyclable', 'Non-Recyclable']
uploaded_file = st.file_uploader("Sube aquí tus residuos", type=["jpg", "jpeg", "png"])
if uploaded_file is not None:
image = Image.open(uploaded_file).convert("RGB")
img = image.resize((224, 224))
arr = np.array(img, dtype=np.float32) / 255.0
arr = np.expand_dims(arr, axis=0)
preds = model.predict(arr)[0]
idx = np.argmax(preds)
prediction = CLASS_NAMES[idx]
# Tarjeta de predicción y sugerencia
suggestions = {
"Hazardous": "Llévalo a un punto limpio o centro de acopio especializado.",
"Organic": "Puedes compostarlo o tirarlo en el contenedor orgánico.",
"Recyclable": "¡No olvides enjuagarlo antes de reciclar!",
"Non-Recyclable": "Deposítalo en el contenedor gris o de basura general."
}
st.markdown(
f"""
✅
¡Listo! Este residuo es:
{prediction}
Sugerencia: {suggestions.get(prediction, '')}
""",
unsafe_allow_html=True,
)
# Imagen cargada
st.image(image, caption="Imagen subida", use_container_width=True)
# Feedback
st.markdown("---")
st.markdown(
"¿La predicción fue correcta? ¡Ayúdanos a mejorar!
",
unsafe_allow_html=True,
)
col1, col2 = st.columns(2)
with col1:
correct_prediction = st.radio("¿Es correcta la predicción?", ["Sí", "No"], horizontal=True)
with col2:
true_label = st.selectbox("Si no es correcta, ¿cuál debería ser?", CLASS_NAMES)
if st.button("Enviar Feedback"):
api = HfApi()
FEED_PATH = "/tmp/feedback_log.csv"
try:
api.download_file(
repo_id="LuisTo97/GreenVision-Docker",
repo_type="space",
path_in_repo="feedback_log.csv",
local_path=FEED_PATH,
token=os.getenv("HUGGINGFACE_HUB_TOKEN")
)
file_exists = True
except Exception:
# no existía aún
file_exists = False
with open(FEED_PATH, "a", newline="", encoding="utf-8") as f:
writer = csv.writer(f)
if not file_exists:
writer.writerow(["predicted", "correct", "timestamp"])
writer.writerow([
prediction,
true_label if correct_prediction == "No" else prediction,
datetime.datetime.utcnow().isoformat()
])
st.success("¡Feedback guardado localmente en /tmp!")
api.upload_file(
path_or_fileobj=FEED_PATH,
path_in_repo="feedback_log.csv",
repo_id="LuisTo97/GreenVision-Docker",
repo_type="space",
token=os.getenv("HUGGINGFACE_HUB_TOKEN"),
commit_message="Add new feedback entry"
)
st.info("¡Feedback subido y acumulado en el repositorio!")
else:
# Mensaje de espera
st.markdown(
""
"Arrastra o selecciona una imagen para descubrir cómo clasificar tu residuo ♻️"
"
",
unsafe_allow_html=True,
)