# -*- coding: utf-8 -*- """ Created on Mon Apr 7 13:43:34 2025 @author: camaac """ import streamlit as st import os import random import pandas as pd from PIL import Image, ImageEnhance import numpy as np import gspread from oauth2client.service_account import ServiceAccountCredentials from skimage.exposure import match_histograms import time from streamlit_autorefresh import st_autorefresh # ------------------------- # Global parameters # ------------------------- IMAGE_DIR = "images" # Folder containing images NUM_PAIRS = 25 # Total number of pairs to be assessed RESULTS_FILE = "results.csv" # CSV file for saving responses # ------------------------- # Helper functions # ------------------------- def load_image_pair(index): """ For a given index (integer), returns the path of the ground truth and the path of AI generated image. Files are named with a 5-digit index. """ idx_str = str(index).zfill(5) gt_path = os.path.join(IMAGE_DIR, f"{idx_str}.png") pred_path = os.path.join(IMAGE_DIR, f"{idx_str}_gen0.png") return gt_path, pred_path def match_brightness(source_img, target_img): source_brightness = np.mean(np.array(source_img)) target_brightness = np.mean(np.array(target_img)) if target_brightness == 0: factor = 1 # avoid division by zero else: factor = source_brightness / target_brightness enhancer = ImageEnhance.Brightness(target_img) adjusted = enhancer.enhance(factor) return adjusted def match_histograms_pil(img_reference, img_to_adjust): """ Layer the histogram of `img_reference` on `img_to_adjust` (both images are PIL.Image objects). Returns a PIL image with adjusted histogram. """ # Convertir les deux images en tableaux numpy ref_array = np.array(img_reference) adj_array = np.array(img_to_adjust) # Ajuster l'histogramme matched = match_histograms(adj_array, ref_array, channel_axis=-1) # Reconvertir en image PIL matched_img = Image.fromarray(np.uint8(matched)) return matched_img # ------------------------- # Navigation via st.session_state # ------------------------- if "page" not in st.session_state: st.session_state.page = "intro" if "user_name" not in st.session_state: st.session_state.user_name = "" if "current_index" not in st.session_state: st.session_state.current_index = 0 if "results" not in st.session_state: st.session_state.results = [] if "list_pair" not in st.session_state: st.session_state.list_pair = [] if "list_pair_ID" not in st.session_state: st.session_state.list_pair_ID = [] if "results_tot" not in st.session_state: st.session_state.results_tot = 0 if "submitted" not in st.session_state: st.session_state.submitted = False # ------------------------- # Intro page # ------------------------- if st.session_state.page == "intro": st.title("AI Wood Generation Evaluation Study") st.markdown( """ **Welcome!** In this study, you will be shown pairs of wood surface images. One image is a real photograph and the other is generated by AI. Your task is to select the image you believe is **real**. ⌛ *Each image pair will be visible for 10 seconds only, be quick!* ⌛ Please enter your name below and click **Start Evaluation** to begin. """ ) name = st.text_input("Enter your name:") if st.button("Start Evaluation") and name: st.session_state.user_name = name st.session_state.page = "evaluation" st.rerun() st.session_state.list_pair_ID = random.sample(range(1, 51), NUM_PAIRS) for i, index in enumerate(st.session_state.list_pair_ID): gt_path, pred_path = load_image_pair(index) pair = [("GT", gt_path), ("Pred", pred_path)] random.shuffle(pair) st.session_state.list_pair.append(pair) st.stop() # ------------------------- # Evaluation page # ------------------------- if st.session_state.page == "evaluation": st.title("AI Wood Generation Evaluation") # st.write(f"User: **{st.session_state.user_name}**") if "start_time" not in st.session_state or st.session_state.page_changed: st.session_state.start_time = time.time() st.session_state.page_changed = False # If all pairs have been evaluated, display a message and save the results if st.session_state.current_index+1 > NUM_PAIRS: st.markdown("