import streamlit as st import cv2 import numpy as np from PIL import Image from io import BytesIO import barcode from barcode.writer import ImageWriter import qrcode import tempfile def image_to_bytes(img): pil_image = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) buffer = BytesIO() pil_image.save(buffer, format="PNG") return buffer.getvalue() def generate_barcode(link): code128 = barcode.get_barcode_class('code128') barcode_image = code128(link, writer=ImageWriter()) buffer = BytesIO() barcode_image.write(buffer) return Image.open(buffer) def generate_qrcode(link): qr = qrcode.QRCode( version=2, error_correction=qrcode.constants.ERROR_CORRECT_L, box_size=4, border=2, ) qr.add_data(link) qr.make(fit=True) qr_image = qr.make_image(fill_color="black", back_color="white") small_qr_image = qr_image.resize((512, 512), Image.Resampling.LANCZOS) buffer = BytesIO() small_qr_image.save(buffer, format="PNG") return Image.open(buffer) def add_custom_css(): css = """ """ st.markdown(css, unsafe_allow_html=True) def add_custom_js(): js = """ """ st.markdown(js, unsafe_allow_html=True) def main(): st.set_page_config(page_title="ADS VISOR - Un autre regard", layout="wide") add_custom_css() add_custom_js() logo_path = "logo.jpg" logo = Image.open(logo_path) st.image(logo, width=150, caption="ADS VISOR") st.title("ADS VISOR - Un autre regard") st.sidebar.header("Chargement de l'image") if "default_image" not in st.session_state: st.session_state["default_image"] = None uploaded_file = st.sidebar.file_uploader("Charge une image", type=["png", "jpg", "jpeg"]) if uploaded_file is not None: image = Image.open(uploaded_file) st.session_state["default_image"] = np.array(image) st.sidebar.image(image, caption="Image par défaut", use_container_width=True) if st.session_state["default_image"] is None: st.sidebar.warning("Veuillez charger une image pour commencer.") return st.sidebar.header("Fonctionnalités") menu_option = st.sidebar.selectbox( "Choisissez une fonctionnalité", ["Accueil", "Transformations d'image", "Cropping", "Rotation", "Floutage", "Contours", "Génération de Code-barres et QR Code", "Détection Faciale"], format_func=lambda x: { "Accueil": "🏠 Accueil", "Transformations d'image": "🖼️ Niveaux de couleurs", "Cropping": "✂️ Cropping", "Rotation": "🔄 Rotation", "Floutage": "🌫️ Floutage", "Contours": "🔍 Contours", "Génération de Code-barres et QR Code": "📇 Codes numériques", "Détection Faciale": "🙂 Détection Faciale" }.get(x, x) ) image_np = st.session_state["default_image"] if menu_option == "Accueil": st.header("Bienvenue sur ADS VISOR") st.markdown( """

ADS VISOR est une application innovante pour analyser, transformer et explorer vos images. 🖼️✨

Que vous soyez un professionnel ou un passionné, découvrez un large éventail de fonctionnalités interactives !

""", unsafe_allow_html=True ) st.write("### Équipe :") st.markdown( """ | **Nom** | **Niveau** | |------------------------|---------------------------| | **Ngoue David** | Master 2 Intelligence Artificielle et Big Data | | **Bidzanga Armel** | Master 2 Intelligence Artificielle et Big Data | | **Nziou Serena** | Master 2 Administration de Systèmes d'Information | """, unsafe_allow_html=True ) elif menu_option == "Transformations d'image": st.subheader("Transformations d'image") tab1, tab2, tab3, tab4 = st.tabs([ "Gris 🖤", "Rouge ❤️", "Vert 💚", "Jaune 💛" ]) with tab1: gray_image = cv2.cvtColor(image_np, cv2.COLOR_BGR2GRAY) st.image(gray_image, caption="Image en Niveaux de Gris", use_container_width=True) st.download_button( label="Télécharger l'image en gris", data=image_to_bytes(gray_image), file_name="image_gris.png", mime="image/png" ) with tab2: red = image_np.copy() red[:, :, 1:] = 0 st.image(red, caption="Image Rouge", use_container_width=True) st.download_button( label="Télécharger l'image rouge", data=image_to_bytes(red), file_name="image_rouge.png", mime="image/png" ) with tab3: green = image_np.copy() green[:, :, [0, 2]] = 0 st.image(green, caption="Image Verte", use_container_width=True) st.download_button( label="Télécharger l'image verte", data=image_to_bytes(green), file_name="image_verte.png", mime="image/png" ) with tab4: yellow = image_np.copy() yellow[:, :, 0] = 0 st.image(yellow, caption="Image Jaune", use_container_width=True) st.download_button( label="Télécharger l'image jaune", data=image_to_bytes(yellow), file_name="image_jaune.png", mime="image/png" ) elif menu_option == "Cropping": st.subheader("Cropping") # Explications pour les paramètres st.markdown( """ ### Légende : Fonctionnement du recadrage - **`x1` (Coordonnée x du coin supérieur gauche)** : Position horizontale du début du rectangle (0 ≤ `x1` < largeur-1). - **`y1` (Coordonnée y du coin supérieur gauche)** : Position verticale du début du rectangle (0 ≤ `y1` < hauteur-1). - **`x2` (Coordonnée x du coin inférieur droit)** : Position horizontale de la fin du rectangle (1 ≤ `x2` ≤ largeur). - **`y2` (Coordonnée y du coin inférieur droit)** : Position verticale de la fin du rectangle (1 ≤ `y2` ≤ hauteur). """ ) # Entrée des coordonnées try: x1 = st.number_input("x1 (Coordonnée x du coin supérieur gauche)", 0, image_np.shape[1] - 1, step=1) y1 = st.number_input("y1 (Coordonnée y du coin supérieur gauche)", 0, image_np.shape[0] - 1, step=1) x2 = st.number_input("x2 (Coordonnée x du coin inférieur droit)", 1, image_np.shape[1], step=1) y2 = st.number_input("y2 (Coordonnée y du coin inférieur droit)", 1, image_np.shape[0], step=1) # Validation des coordonnées if x1 >= x2: st.error("`x2` doit être strictement supérieur à `x1`. Veuillez corriger vos entrées.") elif y1 >= y2: st.error("`y2` doit être strictement supérieur à `y1`. Veuillez corriger vos entrées.") else: # Recadrage de l'image cropped = image_np[int(y1):int(y2), int(x1):int(x2)] st.image(cropped, caption="Image Croppée", use_container_width=True) # Bouton de téléchargement st.download_button( label="Télécharger l'image croppée", data=image_to_bytes(cropped), file_name="image_cropped.png", mime="image/png" ) except Exception as e: st.error(f"Une erreur est survenue : {e}") elif menu_option == "Rotation": st.subheader("Rotation") angle = st.selectbox("Angle de rotation", [45, 90, 180]) rows, cols, _ = image_np.shape rotation_matrix = cv2.getRotationMatrix2D((cols / 2, rows / 2), angle, 1) rotated = cv2.warpAffine(image_np, rotation_matrix, (cols, rows)) st.image(rotated, caption=f"Image Rotée de {angle} degrés", use_container_width=True) # Bouton de téléchargement st.download_button( label="Télécharger l'image rotée", data=image_to_bytes(rotated), file_name=f"image_rotated_{angle}.png", mime="image/png" ) elif menu_option == "Floutage": st.subheader("Floutage") blur_level = st.slider("Niveau de flou (k)", min_value=1, max_value=51, step=2, value=15) blurred = cv2.GaussianBlur(image_np, (blur_level, blur_level), 0) st.image(blurred, caption=f"Image Floutée (k={blur_level})", use_container_width=True) # Bouton de téléchargement st.download_button( label="Télécharger l'image floutée", data=image_to_bytes(blurred), file_name=f"image_blurred_k{blur_level}.png", mime="image/png" ) elif menu_option == "Contours": st.subheader("Contours") gray = cv2.cvtColor(image_np, cv2.COLOR_BGR2GRAY) edges = cv2.Canny(gray, 100, 200) st.image(edges, caption="Contours de l'Image", use_container_width=True) # Bouton de téléchargement st.download_button( label="Télécharger l'image avec contours", data=image_to_bytes(edges), file_name=f"image_edges.png", mime="image/png" ) elif menu_option == "Génération de Code-barres et QR Code": st.subheader("Génération de Code-barres et QR Code") # Entrée utilisateur pour le lien ou le texte link = st.text_input("Entre un lien ou un texte pour générer les codes") # Ajout du bouton pour confirmer la génération if st.button("Générer"): if link: try: # Génération du code-barres barcode_image = generate_barcode(link) st.image(barcode_image, caption="Code-barres généré", use_container_width=True) barcode_buffer = BytesIO() barcode_image.save(barcode_buffer, format="PNG") barcode_buffer.seek(0) st.download_button( label="Télécharger le Code-barres", data=barcode_buffer, file_name="barcode.png", mime="image/png" ) # Génération du QR Code qrcode_image = generate_qrcode(link) st.image(qrcode_image, caption="QR Code généré", use_container_width=True) # Bouton de téléchargement pour le code-barres # Bouton de téléchargement pour le QR code qrcode_buffer = BytesIO() qrcode_image.save(qrcode_buffer, format="PNG") qrcode_buffer.seek(0) st.download_button( label="Télécharger le QR Code", data=qrcode_buffer, file_name="qrcode.png", mime="image/png" ) except Exception as e: st.error(f"Une erreur est survenue : {e}") else: st.error("Veuillez entrer un lien ou un texte valide pour générer les codes.") elif menu_option == "Détection Faciale": st.subheader("Détection Faciale") # Sélectionner la source de l'image source_option = st.radio("Choisissez la source", ("Image Importée", "Autre Image", "Webcam", "Vidéo")) # Charger le classificateur de visages pré-entrainé de OpenCV face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + "haarcascade_frontalface_default.xml") if source_option == "Image Importée": if st.session_state["default_image"] is not None: img = image_np gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30)) # Dessiner des rectangles autour des visages for (x, y, w, h) in faces: cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2) st.image(img, caption="Image avec Visages Détectés", use_container_width=True) elif source_option == "Autre Image": uploaded_file_2 = st.file_uploader("Charge une autre image", type=["png", "jpg", "jpeg"]) if uploaded_file_2 is not None: image_2 = Image.open(uploaded_file_2) img = np.array(image_2) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30)) # Dessiner des rectangles autour des visages for (x, y, w, h) in faces: cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2) st.image(img, caption="Autre Image avec Visages Détectés", use_container_width=True) elif source_option == "Webcam": stframe = st.empty() cap = cv2.VideoCapture(0) while True: ret, frame = cap.read() if not ret: st.write("Erreur dans la lecture de la webcam.") break gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30)) # Dessiner des rectangles autour des visages for (x, y, w, h) in faces: cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 0), 2) # Affichage dans le streamlit stframe.image(frame, channels="BGR", use_container_width=True) if cv2.waitKey(1) & 0xFF == ord("q"): # Quitter avec la touche 'q' break cap.release() elif source_option == "Vidéo": video_file = st.file_uploader("Charge une vidéo", type=["mp4", "avi", "mov"]) if video_file is not None: video_bytes = video_file.read() with tempfile.NamedTemporaryFile(delete=False) as tmp_file: tmp_file.write(video_bytes) video_path = tmp_file.name cap = cv2.VideoCapture(video_path) while cap.isOpened(): ret, frame = cap.read() if not ret: break gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30)) # Dessiner des rectangles autour des visages for (x, y, w, h) in faces: cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 0), 2) st.image(frame, caption="Vidéo avec Visages Détectés", use_container_width=True) cap.release() if __name__ == "__main__": main()