CarolineM5 commited on
Commit
ddcf446
·
verified ·
1 Parent(s): 2917c09

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +70 -71
app.py CHANGED
@@ -8,52 +8,46 @@ import streamlit as st
8
  import os
9
  import random
10
  import pandas as pd
11
- import base64
12
- from io import BytesIO
13
  from PIL import Image
14
 
15
- # --- Global parameters ---
16
- IMAGE_DIR = "images" # Dossier contenant les images.
17
- # Naming convention: ground truth image: "00001.png", generated image: "00001_gen0.png"
18
- NUM_PAIRS = 10 # Nombre de paires à évaluer.
19
- RESULTS_FILE = "results.csv" # Fichier sauvegarder les résultats.
20
-
21
- # --- Fonctions utilitaires ---
22
 
 
 
 
23
  def load_image_pair(index):
24
- """Retourne le chemin de la ground truth et du generated pour un index donné.
25
- Les index sont des entiers convertis en chaînes à 5 chiffres.
 
26
  """
27
  idx_str = str(index).zfill(5)
28
  gt_path = os.path.join(IMAGE_DIR, f"{idx_str}.png")
29
  pred_path = os.path.join(IMAGE_DIR, f"{idx_str}_gen0.png")
30
  return gt_path, pred_path
31
 
32
- def load_and_open_image(path):
33
- """Charge l'image depuis le chemin et retourne un objet PIL.Image."""
34
  return Image.open(path)
35
 
36
  def get_shuffled_pair(index):
37
- """Charge la paire d'images, puis renvoie une liste contenant tuples (label, image)
38
- dans un ordre aléatoire. Le label est "GT" pour ground truth et "Pred" pour generated.
39
  """
40
  gt_path, pred_path = load_image_pair(index)
41
- img_gt = load_and_open_image(gt_path)
42
- img_pred = load_and_open_image(pred_path)
43
  pair = [("GT", img_gt), ("Pred", img_pred)]
44
  random.shuffle(pair)
45
  return pair
46
 
47
- def image_to_base64(image, width=300):
48
- """Convertit une image PIL en code base64, pour l'inclure dans du HTML."""
49
- buffered = BytesIO()
50
- image.save(buffered, format="PNG")
51
- img_str = base64.b64encode(buffered.getvalue()).decode()
52
- html_code = f'<a href="?selected={{}}"><img src="data:image/png;base64,{img_str}" width="{width}"></a>'
53
- return html_code
54
-
55
- # --- Gestion de la navigation entre pages via st.session_state ---
56
-
57
  if "page" not in st.session_state:
58
  st.session_state.page = "intro"
59
  if "user_name" not in st.session_state:
@@ -62,21 +56,23 @@ if "current_index" not in st.session_state:
62
  st.session_state.current_index = 1
63
  if "results" not in st.session_state:
64
  st.session_state.results = []
65
- if "pair_order" not in st.session_state:
66
- st.session_state.pair_order = {}
67
 
68
- # --- Page d'introduction ---
 
 
69
  if st.session_state.page == "intro":
70
  st.title("Wood Surface Evaluation Study")
71
- st.markdown("""
72
- **Welcome!**
 
73
 
74
- In this study, you will be shown pairs of wood surface images.
75
- One image is a real photograph (Ground Truth) and the other is generated by AI.
76
- Your task is to select, by clicking on the image, the one you believe is **real**.
77
-
78
- Please enter your name below and click "Start Evaluation" to begin.
79
- """)
 
80
  name = st.text_input("Enter your name:")
81
  if st.button("Start Evaluation") and name:
82
  st.session_state.user_name = name
@@ -84,57 +80,60 @@ if st.session_state.page == "intro":
84
  st.rerun()
85
  st.stop()
86
 
87
- # --- Page d'évaluation ---
 
 
88
  if st.session_state.page == "evaluation":
89
  st.title("Wood Surface Evaluation")
90
  st.write(f"User: **{st.session_state.user_name}**")
91
 
 
92
  if st.session_state.current_index > NUM_PAIRS:
93
  st.success("Thank you for completing the evaluation!")
94
- # Exporter les résultats sous forme de CSV
95
  results_df = pd.DataFrame(st.session_state.results)
96
  results_df.to_csv(RESULTS_FILE, index=False)
97
- st.write("Results saved in:", RESULTS_FILE)
98
  st.stop()
99
 
100
  st.write(f"Image Pair {st.session_state.current_index} of {NUM_PAIRS}")
101
 
102
  # Charger et mélanger la paire pour l'index courant
103
  pair = get_shuffled_pair(st.session_state.current_index)
104
- st.session_state.pair_order[st.session_state.current_index] = [label for label, _ in pair]
105
-
106
- # Afficher les deux images dans deux colonnes, en les rendant cliquables via HTML
107
  col1, col2 = st.columns(2)
 
108
  with col1:
109
- # On prépare le HTML avec un placeholder pour la clé "1"
110
- img_html = image_to_base64(pair[0][1])
111
- # On injecte le code HTML en remplaçant {} par "1"
112
- st.markdown(img_html.format("1"), unsafe_allow_html=True)
113
- st.caption("Image 1")
114
  with col2:
115
- img_html = image_to_base64(pair[1][1])
116
- st.markdown(img_html.format("2"), unsafe_allow_html=True)
117
- st.caption("Image 2")
118
 
119
- st.markdown("**Click on the image you believe is real.**")
120
-
121
- # Récupérer les paramètres de la requête
122
- query_params = st.query_params
123
- if "selected" in query_params:
124
- selected = query_params["selected"] # "1" ou "2"
125
- selected_label = pair[int(selected) - 1][0] # "GT" ou "Pred"
126
- st.write(f"You selected: **Image {selected}** (label: **{selected_label}**)")
127
- # Enregistrer le résultat pour cette paire
128
- st.session_state.results.append({
129
- "pair_index": st.session_state.current_index,
130
- "pair_order": st.session_state.pair_order[st.session_state.current_index],
131
- "selected": selected_label,
132
- })
133
- # Nettoyer les query params pour éviter la sélection persistante
134
- st.experimental_set_query_params()
135
- # Passer à la paire suivante
136
- st.session_state.current_index += 1
137
- st.rerun()
 
 
 
 
 
 
138
 
139
  # import streamlit as st
140
  # import os
 
8
  import os
9
  import random
10
  import pandas as pd
 
 
11
  from PIL import Image
12
 
13
+ # -------------------------
14
+ # Global parameters
15
+ # -------------------------
16
+ IMAGE_DIR = "images" # Dossier contenant les images
17
+ NUM_PAIRS = 25 # Nombre total de paires à évaluer
18
+ RESULTS_FILE = "results.csv" # Fichier CSV de sauvegarde des réponses
 
19
 
20
+ # -------------------------
21
+ # Helper functions
22
+ # -------------------------
23
  def load_image_pair(index):
24
+ """
25
+ Pour un index donné (entier), retourne le chemin du ground truth et celui de la génération.
26
+ Les fichiers sont nommés avec un index à 5 chiffres.
27
  """
28
  idx_str = str(index).zfill(5)
29
  gt_path = os.path.join(IMAGE_DIR, f"{idx_str}.png")
30
  pred_path = os.path.join(IMAGE_DIR, f"{idx_str}_gen0.png")
31
  return gt_path, pred_path
32
 
33
+ def open_image(path):
34
+ """Ouvre l'image avec PIL."""
35
  return Image.open(path)
36
 
37
  def get_shuffled_pair(index):
38
+ """Charge la paire d'images et retourne une liste de tuples (label, image) dans un ordre aléatoire.
39
+ Le label est 'GT' pour ground truth et 'Pred' pour generated.
40
  """
41
  gt_path, pred_path = load_image_pair(index)
42
+ img_gt = open_image(gt_path)
43
+ img_pred = open_image(pred_path)
44
  pair = [("GT", img_gt), ("Pred", img_pred)]
45
  random.shuffle(pair)
46
  return pair
47
 
48
+ # -------------------------
49
+ # Navigation via st.session_state
50
+ # -------------------------
 
 
 
 
 
 
 
51
  if "page" not in st.session_state:
52
  st.session_state.page = "intro"
53
  if "user_name" not in st.session_state:
 
56
  st.session_state.current_index = 1
57
  if "results" not in st.session_state:
58
  st.session_state.results = []
 
 
59
 
60
+ # -------------------------
61
+ # Intro page
62
+ # -------------------------
63
  if st.session_state.page == "intro":
64
  st.title("Wood Surface Evaluation Study")
65
+ st.markdown(
66
+ """
67
+ **Welcome!**
68
 
69
+ In this study, you will be shown pairs of wood surface images.
70
+ One image is a real photograph (Ground Truth) and the other is generated by AI.
71
+ Your task is to select, by answering below each image, which one you believe is **real**.
72
+
73
+ Please enter your name below and click **Start Evaluation** to begin.
74
+ """
75
+ )
76
  name = st.text_input("Enter your name:")
77
  if st.button("Start Evaluation") and name:
78
  st.session_state.user_name = name
 
80
  st.rerun()
81
  st.stop()
82
 
83
+ # -------------------------
84
+ # Evaluation page
85
+ # -------------------------
86
  if st.session_state.page == "evaluation":
87
  st.title("Wood Surface Evaluation")
88
  st.write(f"User: **{st.session_state.user_name}**")
89
 
90
+ # Si toutes les paires ont été évaluées, afficher un message et sauvegarder les résultats
91
  if st.session_state.current_index > NUM_PAIRS:
92
  st.success("Thank you for completing the evaluation!")
 
93
  results_df = pd.DataFrame(st.session_state.results)
94
  results_df.to_csv(RESULTS_FILE, index=False)
95
+ st.write(f"Results saved in: **{RESULTS_FILE}**")
96
  st.stop()
97
 
98
  st.write(f"Image Pair {st.session_state.current_index} of {NUM_PAIRS}")
99
 
100
  # Charger et mélanger la paire pour l'index courant
101
  pair = get_shuffled_pair(st.session_state.current_index)
102
+ # Affichage dans deux colonnes avec radio buttons sous chacune
 
 
103
  col1, col2 = st.columns(2)
104
+
105
  with col1:
106
+ st.image(pair[0][1], caption="Image 1", use_column_width=True)
107
+ choice1 = st.radio("Is this image real?", options=["No", "Yes"], index=0, key=f"choice_{st.session_state.current_index}_1")
 
 
 
108
  with col2:
109
+ st.image(pair[1][1], caption="Image 2", use_column_width=True)
110
+ choice2 = st.radio("Is this image real?", options=["No", "Yes"], index=0, key=f"choice_{st.session_state.current_index}_2")
 
111
 
112
+ if st.button("Submit Evaluation"):
113
+ selections = [choice1, choice2]
114
+ yes_count = selections.count("Yes")
115
+ if yes_count != 1:
116
+ st.error("Please select exactly one image as real (one Yes and one No).")
117
+ else:
118
+ if choice1 == "Yes":
119
+ selected_label = pair[0][0] # "GT" ou "Pred"
120
+ chosen_image = "Image 1"
121
+ else:
122
+ selected_label = pair[1][0]
123
+ chosen_image = "Image 2"
124
+
125
+ st.success(f"You selected **{chosen_image}** as the real image.")
126
+
127
+ # Enregistrer le résultat
128
+ st.session_state.results.append({
129
+ "pair_index": st.session_state.current_index,
130
+ "pair_order": [pair[0][0], pair[1][0]], # ordre des labels affichés
131
+ "selected": selected_label,
132
+ })
133
+
134
+ # Passer à la paire suivante
135
+ st.session_state.current_index += 1
136
+ st.rerun()
137
 
138
  # import streamlit as st
139
  # import os