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()