import streamlit as st from PIL import Image, UnidentifiedImageError import numpy as np import tensorflow as tf from tensorflow.keras.applications.resnet50 import preprocess_input as preprocess_input_resnet50 import os # --- Page Config --- st.set_page_config( page_title="Ai-Generated vs. Real Detector", page_icon="./logo.png", layout="wide" ) # --- Path Setup --- MODEL_PATH = os.path.join(os.path.dirname(__file__), 'my_ai_detector_resnet50.keras') SAMPLE_DIR = os.path.join(os.path.dirname(__file__), 'samples') FILES_DIR = os.path.join(os.path.dirname(__file__), 'files') IMAGE_SIZE = (224, 224) # --- Custom CSS --- st.markdown(""" """, unsafe_allow_html=True) # --- Model Loading --- @st.cache_resource def load_my_model(model_path): try: model = tf.keras.models.load_model(model_path) return model except Exception as e: st.error(f"Error loading model: {e}") return None # --- Preprocessing --- def preprocess_image_for_resnet50(image_pil, target_size): if image_pil.mode != "RGB": image_pil = image_pil.convert("RGB") image_pil_resized = image_pil.resize(target_size) image_array = np.array(image_pil_resized) image_array_expanded = np.expand_dims(image_array, axis=0) processed_image = preprocess_input_resnet50(image_array_expanded.astype('float32')) return processed_image model = load_my_model(MODEL_PATH) # --- Sidebar: Project Summary & Files --- with st.sidebar: st.header("Project Background") st.markdown(""" **The Generative AI Challenge** We developed this model thinking of the possible future consequences that we will be facing with Gen-AI. As synthetic media becomes indistinguishable from reality, the need for automated verification tools is critical. """) st.markdown("---") # 1. SAMPLE SELECTOR st.markdown( "
Developed by Ignacio Alarcon & Bernardo Gandara
""", unsafe_allow_html=True ) st.markdown( """ Upload an image to inspect digital artifacts and determine authenticity. **We encourage you to test the model's accuracy against synthetic content, such as images autogenerated by this site: [thispersondoesnotexist.com](https://thispersondoesnotexist.com/)** """ ) # --- Image Loading --- uploaded_file = st.file_uploader("Choose an image file:", type=["jpg", "jpeg", "png"]) active_image = None # --- CRASH PROTECTION LOGIC --- if uploaded_file: try: active_image = Image.open(uploaded_file) except Exception as e: st.error("⚠️ Format not supported. Please upload a valid image file (JPG, PNG).") # We leave active_image as None, so the code below won't run. elif sample_choice != "None": if sample_choice == "Sample Real (Organic)": file_path = os.path.join(SAMPLE_DIR, "real.jpg") else: file_path = os.path.join(SAMPLE_DIR, "fake.jpg") if os.path.exists(file_path): active_image = Image.open(file_path) # --- Analysis Logic --- if active_image: col1, col2 = st.columns([0.5, 0.5], gap="large") with col1: st.image(active_image, caption="Input Image") with col2: st.subheader("Analysis Results") with st.status("Scanning image artifacts...", expanded=True) as status: st.write("Preprocessing image (ResNet50 standard)...") processed_image = preprocess_image_for_resnet50(active_image, IMAGE_SIZE) st.write("Running inference...") prediction_probs = model.predict(processed_image) status.update(label="Analysis Complete!", state="complete", expanded=False) prob_real = float(prediction_probs[0][0]) if prob_real > 0.5: pred_class = "REAL" sub_text = "Organic Photography" confidence_val = f"{prob_real:.2%}" st.markdown(f"""{sub_text}
{sub_text}