import gradio as gr
import random
import os
import io
import json
import string
import secrets
from datetime import datetime
from huggingface_hub import HfApi
MAX_IMAGE_SIZE = 1024
NUM_GROUPS = 5
order = ["ours", "demo", "autotoon", "stylecari", "warpgan"]
user_results = []
max_len = 3
api = HfApi(token=os.getenv('HF_TOKEN'))
def write_log():
now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
json_buffer = io.BytesIO(json.dumps(user_results, indent=2).encode("utf-8"))
api.upload_file(
path_or_fileobj=json_buffer,
path_in_repo=f"./log/log_{now}_num_{len(user_results)}.txt",
repo_id="Dongyuu11/User-study-storage",
repo_type="space",
)
def reshuffle_with_indices(lst):
indexed_list = list(enumerate(lst)) # [(0, a), (1, b), ...]
random.shuffle(indexed_list)
reshuffled = [item for idx, item in indexed_list]
original_indices = [idx for idx, item in indexed_list]
return reshuffled, original_indices
def load_data():
data_all = []
for i in range(1216):
root_dir = f"./data/{str(i)}"
cond1 = os.path.join(root_dir, "id.jpg")
cond2 = os.path.join(root_dir, "ske.jpg")
outputs = [os.path.join(root_dir, "ours.jpg"),
os.path.join(root_dir, "demo.jpg"),
os.path.join(root_dir, "autotoon.jpg"),
os.path.join(root_dir, "stylecari.jpg"),
os.path.join(root_dir, "warpgan.jpg")]
outputs, original_indices = reshuffle_with_indices(outputs)
data_all.append({
"conditions": [cond1, cond2],
"outputs": outputs,
"samp_index": str(i),
"original_indices": original_indices
})
return data_all
def get_group_data(index):
global data_all
group = data_all[index]
return group["conditions"], group["outputs"]
def reload(current_index):
global data_all
random_global_index = random.sample(range(0, 1216), 1)[0]
conds, outputs = get_group_data(random_global_index)
return [
gr.update(value=conds[0]),
gr.update(value=conds[1]),
gr.update(value=outputs[0]),
gr.update(value=outputs[1]),
gr.update(value=outputs[2]),
gr.update(value=outputs[3]),
gr.update(value=outputs[4]),
gr.update(value=outputs[0]),
gr.update(value=outputs[1]),
gr.update(value=outputs[2]),
gr.update(value=outputs[3]),
gr.update(value=outputs[4]),
gr.update(value=outputs[0]),
gr.update(value=outputs[1]),
gr.update(value=outputs[2]),
gr.update(value=outputs[3]),
gr.update(value=outputs[4]),
gr.update(value=1),
gr.update(value=1),
gr.update(value=1),
gr.update(value=1),
gr.update(value=1),
gr.update(value=1),
gr.update(value=1),
gr.update(value=1),
gr.update(value=1),
gr.update(value=1),
gr.update(value=1),
gr.update(value=1),
gr.update(value=1),
gr.update(value=1),
gr.update(value=1),
gr.update(value="Portrait photo"),
gr.update(value="Sketch"),
gr.update(
value="Evaluation criterion: If the caricature's contour matches the sketch's shape? 10: Best match. 1: Worst match."),
gr.update(
value="Evaluation criterion: If the caricature sufficiently matches the facial features of the portrait photo? 10: Best match. 1: Worst match."),
gr.update(
value="Evaluation criterion: Based on the above two criteria, your overall assessment of the quality of the caricatures. 10: Best quality. 1: Worst quality."),
gr.update(
value="Thank you for supporting our research on AI-based caricature generation. In this questionnaire, you will be shown several portrait photos along with corresponding sketches that depict the contours of the desired caricatures. Please rate the generated caricatures according to the given evaluation criteria."),
gr.update(value=f"### Current progress: {current_index + 1}/{NUM_GROUPS}"),
random_global_index,
]
def generate_random_string(length=20):
alphabet = string.ascii_letters + string.digits
return ''.join(secrets.choice(alphabet) for _ in range(length))
def submit_eachtime(s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, random_global_index,
current_index):
global order, data_all, user_results
samp_index = data_all[random_global_index]["samp_index"]
original_indices = data_all[random_global_index]["original_indices"]
scores = [s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15]
shape_scores = {}
id_scores = {}
overall = {}
shape_scores[order[original_indices[0]]] = s1
shape_scores[order[original_indices[1]]] = s2
shape_scores[order[original_indices[2]]] = s3
shape_scores[order[original_indices[3]]] = s4
shape_scores[order[original_indices[4]]] = s5
id_scores[order[original_indices[0]]] = s6
id_scores[order[original_indices[1]]] = s7
id_scores[order[original_indices[2]]] = s8
id_scores[order[original_indices[3]]] = s9
id_scores[order[original_indices[4]]] = s10
overall[order[original_indices[0]]] = s11
overall[order[original_indices[1]]] = s12
overall[order[original_indices[2]]] = s13
overall[order[original_indices[3]]] = s14
overall[order[original_indices[4]]] = s15
user_results_per_iter = {
# "group_index": index,
"scores": scores,
"index": samp_index,
"shape": shape_scores,
"id": id_scores,
"overall": overall
}
user_results.append(user_results_per_iter)
if len(user_results) >= max_len:
write_log()
user_results = []
print(user_results_per_iter)
# append_to_json_file(user_results_per_iter, "./results.json")
new_current_index = current_index + 1
print(new_current_index, NUM_GROUPS)
if new_current_index >= NUM_GROUPS:
return [gr.update(visible=False)] * 38 + [
gr.update(value="The user study has been completed. Thank you again for your invaluable support of our research!"),
random_global_index,
new_current_index
]
else:
new_random_global_index = random.sample(range(0, 1216), 1)[0]
conds, outputs = get_group_data(new_random_global_index)
return [
gr.update(value=conds[0]),
gr.update(value=conds[1]),
gr.update(value=outputs[0]),
gr.update(value=outputs[1]),
gr.update(value=outputs[2]),
gr.update(value=outputs[3]),
gr.update(value=outputs[4]),
gr.update(value=outputs[0]),
gr.update(value=outputs[1]),
gr.update(value=outputs[2]),
gr.update(value=outputs[3]),
gr.update(value=outputs[4]),
gr.update(value=outputs[0]),
gr.update(value=outputs[1]),
gr.update(value=outputs[2]),
gr.update(value=outputs[3]),
gr.update(value=outputs[4]),
gr.update(value=1),
gr.update(value=1),
gr.update(value=1),
gr.update(value=1),
gr.update(value=1),
gr.update(value=1),
gr.update(value=1),
gr.update(value=1),
gr.update(value=1),
gr.update(value=1),
gr.update(value=1),
gr.update(value=1),
gr.update(value=1),
gr.update(value=1),
gr.update(value=1),
gr.update(value="Portrait photo"),
gr.update(value="Sketch"),
gr.update(
value="Evaluation criterion: If the caricature's contour matches the sketch's shape? 10: Best match. 1: Worst match."),
gr.update(
value="Evaluation criterion: If the caricature sufficiently matches the facial features of the portrait photo? 10: Best match. 1: Worst match."),
gr.update(
value="Evaluation criterion: Based on the above two criteria, your overall assessment of the quality of the caricature. 10: Best quality. 1: Worst quality."),
gr.update(
value="Thank you for supporting our research on AI-based caricature generation. In this questionnaire, you will be shown several portrait photos along with corresponding sketches that depict the contours of the desired caricatures. Please rate the generated caricatures according to the given evaluation criteria."),
gr.update(value=f"### Current progress: {new_current_index + 1}/{NUM_GROUPS}"),
new_random_global_index,
new_current_index
]
data_all = load_data()
height = 250
width = 250
with gr.Blocks(css=""".center-column {
display: flex;
flex-direction: column;
align-items: center;
}
.center-markdown {
font-size: 100px !important;
text-align: center;
width: fit-content;
}
""") as demo:
random_global_index = gr.State(0)
current_index = gr.State(0)
initial_conditions, initial_outputs = get_group_data(0)
text_main = gr.Markdown(
"Thank you for supporting our research on AI-based caricature generation. In this questionnaire, you will be shown several portrait photos along with corresponding sketches that depict the contours of the desired caricatures. Please rate the generated caricatures according to the given evaluation criteria.")
with gr.Row():
with gr.Column(elem_classes=["center-column"]):
text1 = gr.Markdown("Portrait photo", elem_classes=["center-markdown"])
cond1 = gr.Image(value=initial_conditions[0], label="Photo", interactive=False, height=250, width=250)
with gr.Column(elem_classes=["center-column"]):
text2 = gr.Markdown("Sketch", elem_classes=["center-markdown"])
cond2 = gr.Image(value=initial_conditions[1], label="Sketch", interactive=False, height=250, width=250)
with gr.Row():
text3 = gr.Markdown(
"Evaluation criterion: If the caricature's contour matches the sketch's shape? 10: Best match. 1: Worst match")
with gr.Row():
out1 = gr.Image(value=initial_outputs[0], interactive=False, height=height, width=width)
out2 = gr.Image(value=initial_outputs[1], interactive=False, height=height, width=width)
out3 = gr.Image(value=initial_outputs[2], interactive=False, height=height, width=width)
out4 = gr.Image(value=initial_outputs[3], interactive=False, height=height, width=width)
out5 = gr.Image(value=initial_outputs[4], interactive=False, height=height, width=width)
with gr.Row():
s1 = gr.Slider(1, 10, step=1, label="Rate")
s2 = gr.Slider(1, 10, step=1, label="Rate")
s3 = gr.Slider(1, 10, step=1, label="Rate")
s4 = gr.Slider(1, 10, step=1, label="Rate")
s5 = gr.Slider(1, 10, step=1, label="Rate")
with gr.Row():
text4 = gr.Markdown(
"Evaluation criterion: If the caricature sufficiently matches the facial features of the portrait photo? 10: Best match. 1: Worst match")
with gr.Row():
out6 = gr.Image(value=initial_outputs[0], interactive=False, height=height, width=width)
out7 = gr.Image(value=initial_outputs[1], interactive=False, height=height, width=width)
out8 = gr.Image(value=initial_outputs[2], interactive=False, height=height, width=width)
out9 = gr.Image(value=initial_outputs[3], interactive=False, height=height, width=width)
out10 = gr.Image(value=initial_outputs[4], interactive=False, height=height, width=width)
with gr.Row():
text5 = gr.Markdown(
"Evaluation criterion: Based on the above two criteria, your overall assessment of the quality of the caricature. 10: Best quality 1: Worst quality")
with gr.Row():
s6 = gr.Slider(1, 10, step=1, label="Rate")
s7 = gr.Slider(1, 10, step=1, label="Rate")
s8 = gr.Slider(1, 10, step=1, label="Rate")
s9 = gr.Slider(1, 10, step=1, label="Rate")
s10 = gr.Slider(1, 10, step=1, label="Rate")
with gr.Row():
out11 = gr.Image(value=initial_outputs[0], interactive=False, height=height, width=width)
out12 = gr.Image(value=initial_outputs[1], interactive=False, height=height, width=width)
out13 = gr.Image(value=initial_outputs[2], interactive=False, height=height, width=width)
out14 = gr.Image(value=initial_outputs[3], interactive=False, height=height, width=width)
out15 = gr.Image(value=initial_outputs[4], interactive=False, height=height, width=width)
with gr.Row():
s11 = gr.Slider(1, 10, step=1, label="Rate")
s12 = gr.Slider(1, 10, step=1, label="Rate")
s13 = gr.Slider(1, 10, step=1, label="Rate")
s14 = gr.Slider(1, 10, step=1, label="Rate")
s15 = gr.Slider(1, 10, step=1, label="Rate")
progress_label = gr.Markdown(f"### Current progress:1/{NUM_GROUPS}")
submit_btn = gr.Button("Submit")
hidden_index = gr.State(0)
original_indicies = initial_outputs
demo.load(fn=reload, inputs=[current_index],
outputs=[cond1, cond2, out1, out2, out3, out4, out5, out6, out7, out8, out9, out10,
out11, out12, out13, out14, out15, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14,
s15,
text1, text2, text3, text4, text5, text_main, progress_label, random_global_index])
submit_btn.click(
fn=submit_eachtime,
inputs=[s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, random_global_index, current_index],
outputs=[cond1, cond2, out1, out2, out3, out4, out5, out6, out7, out8, out9, out10, out11, out12, out13, out14,
out15, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15,
text1, text2, text3, text4, text5, text_main, progress_label, random_global_index, current_index]
)
if __name__ == "__main__":
demo.launch()