Isolate_color / src /streamlit_app.py
Eric2mangel's picture
Update src/streamlit_app.py
03264f9 verified
Raw
History Blame Contribute Delete
5.84 kB
import os
# Fix pour les erreurs de permission Streamlit sur Hugging Face
if "HOME" not in os.environ or os.environ["HOME"] == "/":
os.environ["HOME"] = "/tmp"
os.makedirs("/tmp/.streamlit", exist_ok=True)
import streamlit as st
import cv2
import numpy as np
from PIL import Image
st.set_page_config(layout="wide")
st.title("Détection et Isolation de Couleurs sur Image")
st.sidebar.header("Paramètres de l'image et de la couleur")
# 1. Téléchargement de l'image
uploaded_file = st.sidebar.file_uploader("Choisissez une image...", type=["jpg", "jpeg", "png"])
if uploaded_file is not None:
# --- DÉBUT DU BLOC DE TRAITEMENT LORSQU'UNE IMAGE EST TÉLÉCHARGÉE ---
st.sidebar.success("Fichier chargé avec succès !") # Pour confirmer que le fichier est bien là
# Lire le fichier BINAIRE UNE SEULE FOIS ici
file_bytes = np.asarray(bytearray(uploaded_file.read()), dtype=np.uint8)
st.sidebar.text(f"Taille du fichier en bytes: {len(file_bytes)}") # Vérifier si les bytes sont lus
# Décodage de l'image BGR avec OpenCV
img_bgr = cv2.imdecode(file_bytes, 1)
if img_bgr is None:
st.sidebar.error("Impossible de décoder l'image. Est-ce un format supporté ?")
st.stop() # Arrête l'exécution du script Streamlit pour ce cycle
else:
st.sidebar.success(f"Image décodée. Dimensions: {img_bgr.shape}")
# Convertir BGR en RGB pour l'affichage Streamlit (image originale)
img_rgb = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB)
st.subheader("Image Originale")
st.image(img_rgb, caption="Image Originale", use_column_width=True)
# 2. Choix de la couleur (tout le reste du code de traitement est maintenant ici)
color_choice = st.sidebar.selectbox(
"Choisissez une couleur prédéfinie ou personnalisée :",
("Bleu", "Vert", "Rouge", "Jaune", "Orange", "Violet", "Personnalisé")
)
h_lower, s_lower, v_lower = 0, 0, 0
h_upper, s_upper, v_upper = 179, 255, 255
if color_choice == "Bleu":
lower_bound = np.array([100, 150, 0])
upper_bound = np.array([140, 255, 255])
elif color_choice == "Vert":
lower_bound = np.array([40, 50, 50])
upper_bound = np.array([80, 255, 255])
elif color_choice == "Rouge":
# Le rouge est spécial car il chevauche le 0/179 sur le cercle chromatique HSV
# Il faut généralement deux plages pour le rouge pur
st.sidebar.warning("Le rouge peut nécessiter deux plages HSV. Cette démo utilise une plage simple.")
lower_bound = np.array([0, 100, 100])
upper_bound = np.array([10, 255, 255])
# Second range for red (optional, for more complete red detection)
# lower_red2 = np.array([160, 100, 100])
# upper_red2 = np.array([179, 255, 255])
elif color_choice == "Jaune":
lower_bound = np.array([20, 100, 100])
upper_bound = np.array([40, 255, 255])
elif color_choice == "Orange":
lower_bound = np.array([10, 100, 100])
upper_bound = np.array([25, 255, 255])
elif color_choice == "Violet":
lower_bound = np.array([130, 50, 50])
upper_bound = np.array([160, 255, 255])
elif color_choice == "Personnalisé":
st.sidebar.subheader("Définir la plage HSV personnalisée")
h_lower = st.sidebar.slider("Teinte (H) Min", 0, 179, 0)
h_upper = st.sidebar.slider("Teinte (H) Max", 0, 179, 179)
s_lower = st.sidebar.slider("Saturation (S) Min", 0, 255, 0)
s_upper = st.sidebar.slider("Saturation (S) Max", 0, 255, 255)
v_lower = st.sidebar.slider("Valeur (V) Min", 0, 255, 0)
v_upper = st.sidebar.slider("Valeur (V) Max", 0, 255, 255)
lower_bound = np.array([h_lower, s_lower, v_lower])
upper_bound = np.array([h_upper, s_upper, v_upper])
if uploaded_file is not None:
# Convertir l'image BGR en HSV
hsv_image = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2HSV)
# Créer un masque pour la couleur sélectionnée
mask = cv2.inRange(hsv_image, lower_bound, upper_bound)
# Appliquer le masque à l'image originale
# On utilise bitwise_and pour n'afficher que les pixels qui correspondent au masque
isolated_color_bgr = cv2.bitwise_and(img_bgr, img_bgr, mask=mask)
# Convertir le résultat en RGB pour l'affichage Streamlit
isolated_color_rgb = cv2.cvtColor(isolated_color_bgr, cv2.COLOR_BGR2RGB)
st.subheader(f"Couleur isolée : {color_choice}")
st.image(isolated_color_rgb, caption=f"{color_choice} isolé", use_column_width=True)
st.subheader("Masque généré")
st.image(mask, caption="Masque (blanc = couleur détectée)", use_column_width=True)
st.markdown("""
**Comment ça marche ?**
1. **Conversion HSV :** L'image originale est convertie de l'espace couleur BGR (utilisé par OpenCV) à HSV (Teinte, Saturation, Valeur). HSV est idéal pour la détection de couleurs car la teinte (H) isole la couleur elle-même, indépendamment de la luminosité ou de l'intensité.
2. **Définition de la Plage HSV :** Pour chaque couleur, une plage inférieure (`lower_bound`) et une plage supérieure (`upper_bound`) sont définies en termes de valeurs H, S et V.
3. **Création du Masque :** La fonction `cv2.inRange()` est utilisée pour créer un masque binaire. Tous les pixels de l'image HSV qui tombent dans la plage définie obtiennent une valeur de 255 (blanc), les autres 0 (noir).
4. **Application du Masque :** La fonction `cv2.bitwise_and()` combine l'image originale avec le masque. Seuls les pixels où le masque est blanc sont conservés de l'image originale ; les autres deviennent noirs.
""")
else:
st.info("Veuillez télécharger une image pour commencer.")