Spaces:
Runtime error
Runtime error
| ##!/usr/bin/python3 | |
| # -*- coding: utf-8 -*- | |
| # @Time : 2024-07-31 | |
| # @Author : Junjie He | |
| import gradio as gr | |
| from src.process import ( | |
| text_to_single_id_generation_process, | |
| text_to_multi_id_generation_process, | |
| image_to_single_id_generation_process, | |
| ) | |
| def text_to_single_id_generation_block(): | |
| gr.Markdown("## Text-to-Single-ID Generation") | |
| gr.HTML(text_to_single_id_description) | |
| gr.HTML(text_to_single_id_tips) | |
| with gr.Row(): | |
| with gr.Column(scale=1, min_width=100): | |
| prompt = gr.Textbox(value="", label='Prompt', lines=2) | |
| negative_prompt = gr.Textbox(value="nsfw", label='Negative Prompt') | |
| image_resolution = gr.Dropdown(choices=["768x512", "512x512", "512x768"], value="512x512", | |
| label="Image Resolution (HxW)") | |
| run_button = gr.Button(value="Run") | |
| with gr.Accordion("Advanced Options", open=True): | |
| seed = gr.Slider(label="Seed (-1 indicates random)", minimum=-1, maximum=2147483647, step=1, value=-1) | |
| faceid_scale = gr.Slider(label="Face ID Scale", minimum=0.0, maximum=1.0, step=0.01, value=0.7) | |
| face_structure_scale = gr.Slider(label="Face Structure Scale", minimum=0.0, maximum=1.0, | |
| step=0.01, value=0.1) | |
| style_scale = gr.Slider(label="style_scale", minimum=0.0, maximum=1.0, step=0.01, value=0.7) | |
| use_sr = gr.Checkbox(label="RealESRGAN 2x", value=True) | |
| with gr.Column(scale=3, min_width=100): | |
| with gr.Row(equal_height=False): | |
| pil_faceid = gr.Image(type="pil", label="ID Image") | |
| with gr.Accordion("ID Supplements", open=True): | |
| with gr.Row(): | |
| pil_supp_faceids = gr.File(file_count="multiple", file_types=["image"], | |
| type="filepath", label="Additional ID Images") | |
| with gr.Row(): | |
| with gr.Column(scale=1, min_width=100): | |
| pil_mix_faceid_1 = gr.Image(type="pil", label="Mix ID 1") | |
| mix_scale_1 = gr.Slider(label="Mix Scale 1", minimum=0.0, maximum=1.0, step=0.01, value=0.0) | |
| with gr.Column(scale=1, min_width=100): | |
| pil_mix_faceid_2 = gr.Image(type="pil", label="Mix ID 2") | |
| mix_scale_2 = gr.Slider(label="Mix Scale 2", minimum=0.0, maximum=1.0, step=0.01, value=0.0) | |
| pil_style = gr.Image(type="pil", label="Style") | |
| with gr.Row(): | |
| example_output = gr.Image(type="pil", label="(Example Output)", visible=False) | |
| result_gallery = gr.Gallery(label='Output', show_label=True, elem_id="gallery", columns=4, preview=True, | |
| format="png") | |
| with gr.Row(): | |
| examples = [ | |
| [ | |
| "A man with short black hair, was paired with a blue denim jacket with yellow details.", | |
| "assets/examples/1-newton.jpg", | |
| "assets/No-Image-Placeholder.png", | |
| "assets/examples/1-output-1.png", | |
| ], | |
| [ | |
| "A little boy with short black hair, was paired with a blue denim jacket with yellow details.", | |
| "assets/examples/1-newton.jpg", | |
| "assets/No-Image-Placeholder.png", | |
| "assets/examples/1-output-4.png", | |
| ], | |
| [ | |
| "A man with short black hair, was paired with a blue denim jacket with yellow details.", | |
| "assets/examples/1-newton.jpg", | |
| "assets/examples/1-style-1.jpg", | |
| "assets/examples/1-output-2.png", | |
| ], | |
| [ | |
| "A man with short black hair, was paired with a blue denim jacket with yellow details.", | |
| "assets/examples/1-newton.jpg", | |
| "assets/examples/1-style-2.jpg", | |
| "assets/examples/1-output-5.png", | |
| ], | |
| ] | |
| gr.Examples( | |
| label="Examples", | |
| examples=examples, | |
| inputs=[prompt, pil_faceid, pil_style, example_output], | |
| ) | |
| with gr.Row(): | |
| examples = [ | |
| [ | |
| "A woman, vector art, flat illustration, pastel color", | |
| "assets/examples/1-alibaba-sucai-1.jpg", | |
| 0.5, | |
| 0.0, | |
| "assets/examples/1-output-6.png", | |
| ], | |
| [ | |
| "A woman, comic book style, pastel color", | |
| "assets/examples/1-alibaba-sucai-2.jpg", | |
| 0.5, | |
| 0.0, | |
| "assets/examples/1-output-7.png", | |
| ], | |
| ] | |
| gr.Examples( | |
| label="Advanced Examples", | |
| examples=examples, | |
| inputs=[prompt, pil_faceid, faceid_scale, face_structure_scale, example_output], | |
| ) | |
| ips = [ | |
| pil_faceid, pil_supp_faceids, | |
| pil_mix_faceid_1, mix_scale_1, | |
| pil_mix_faceid_2, mix_scale_2, | |
| faceid_scale, face_structure_scale, | |
| prompt, negative_prompt, | |
| pil_style, style_scale, | |
| seed, image_resolution, use_sr, | |
| ] | |
| run_button.click(fn=text_to_single_id_generation_process, inputs=ips, outputs=[result_gallery]) | |
| def text_to_multi_id_generation_block(): | |
| gr.Markdown("## Text-to-Multi-ID Generation") | |
| gr.HTML(text_to_multi_id_description) | |
| gr.HTML(text_to_multi_id_tips) | |
| with gr.Row(): | |
| with gr.Column(scale=1, min_width=100): | |
| prompt = gr.Textbox(value="", label='Prompt', lines=2) | |
| negative_prompt = gr.Textbox(value="nsfw", label='Negative Prompt') | |
| image_resolution = gr.Dropdown(choices=["768x512", "512x512", "512x768"], value="512x512", | |
| label="Image Resolution (HxW)") | |
| run_button = gr.Button(value="Run") | |
| with gr.Accordion("Advanced Options", open=True): | |
| seed = gr.Slider(label="Seed (-1 indicates random)", minimum=-1, maximum=2147483647, step=1, value=-1) | |
| faceid_scale = gr.Slider(label="Face ID Scale", minimum=0.0, maximum=1.0, step=0.01, value=0.7) | |
| face_structure_scale = gr.Slider(label="Face Structure Scale", minimum=0.0, maximum=1.0, | |
| step=0.01, value=0.3) | |
| style_scale = gr.Slider(label="style_scale", minimum=0.0, maximum=1.0, step=0.01, value=0.7) | |
| use_sr = gr.Checkbox(label="RealESRGAN 2x", value=True) | |
| with gr.Column(scale=3, min_width=100): | |
| with gr.Row(equal_height=False): | |
| with gr.Column(scale=1, min_width=100): | |
| pil_faceid_1st = gr.Image(type="pil", label="First ID") | |
| with gr.Accordion("First ID Supplements", open=False): | |
| with gr.Row(): | |
| pil_supp_faceids_1st = gr.File(file_count="multiple", file_types=["image"], | |
| type="filepath", label="Additional ID Images") | |
| with gr.Row(): | |
| with gr.Column(scale=1, min_width=100): | |
| pil_mix_faceid_1_1st = gr.Image(type="pil", label="Mix ID 1") | |
| mix_scale_1_1st = gr.Slider(label="Mix Scale 1", minimum=0.0, maximum=1.0, step=0.01, | |
| value=0.0) | |
| with gr.Column(scale=1, min_width=100): | |
| pil_mix_faceid_2_1st = gr.Image(type="pil", label="Mix ID 2") | |
| mix_scale_2_1st = gr.Slider(label="Mix Scale 2", minimum=0.0, maximum=1.0, step=0.01, | |
| value=0.0) | |
| with gr.Column(scale=1, min_width=100): | |
| pil_faceid_2nd = gr.Image(type="pil", label="Second ID") | |
| with gr.Accordion("Second ID Supplements", open=False): | |
| with gr.Row(): | |
| pil_supp_faceids_2nd = gr.File(file_count="multiple", file_types=["image"], | |
| type="filepath", label="Additional ID Images") | |
| with gr.Row(): | |
| with gr.Column(scale=1, min_width=100): | |
| pil_mix_faceid_1_2nd = gr.Image(type="pil", label="Mix ID 1") | |
| mix_scale_1_2nd = gr.Slider(label="Mix Scale 1", minimum=0.0, maximum=1.0, step=0.01, | |
| value=0.0) | |
| with gr.Column(scale=1, min_width=100): | |
| pil_mix_faceid_2_2nd = gr.Image(type="pil", label="Mix ID 2") | |
| mix_scale_2_2nd = gr.Slider(label="Mix Scale 2", minimum=0.0, maximum=1.0, step=0.01, | |
| value=0.0) | |
| with gr.Column(scale=1, min_width=100): | |
| pil_style = gr.Image(type="pil", label="Style") | |
| with gr.Row(): | |
| example_output = gr.Image(type="pil", label="(Example Output)", visible=False) | |
| result_gallery = gr.Gallery(label='Output', show_label=True, elem_id="gallery", columns=4, preview=True, | |
| format="png") | |
| with gr.Row(): | |
| examples = [ | |
| [ | |
| "Two beautiful women are drinking coffee.", | |
| "assets/examples/1-alibaba-sucai-2.jpg", | |
| "assets/examples/2-alibaba-sucai-1.jpg", | |
| "assets/No-Image-Placeholder.png", | |
| "assets/examples/2-output-5.png", | |
| ], | |
| [ | |
| "The two women are captured in laughter and joy, their faces brimming with sincere happiness against the backdrop of a peaceful beach at sunset. The painting, depicted in soft style, captures the warmth and tranquility of the moment.", | |
| "assets/examples/2-stylegan2-ffhq-0100.png", | |
| "assets/examples/2-stylegan2-ffhq-0293.png", | |
| "assets/No-Image-Placeholder.png", | |
| "assets/examples/2-output-1.png", | |
| ], | |
| [ | |
| "The two female models are drinking coffee. The background was off-white.", | |
| "assets/examples/2-stylegan2-ffhq-0100.png", | |
| "assets/examples/2-stylegan2-ffhq-0293.png", | |
| "assets/examples/2-style-1.jpg", | |
| "assets/examples/2-output-2.png", | |
| ], | |
| ] | |
| gr.Examples( | |
| label="Advanced Examples", | |
| examples=examples, | |
| inputs=[prompt, pil_faceid_1st, pil_faceid_2nd, pil_style, example_output], | |
| ) | |
| with gr.Row(): | |
| examples = [ | |
| [ | |
| "Two men in an American poster.", | |
| "assets/examples/Trump-1.jpg", | |
| ["assets/examples/Trump-2.jpg", "assets/examples/Trump-3.jpg", "assets/examples/Trump-4.jpg"], | |
| "assets/examples/Biden-1.jpg", | |
| ["assets/examples/Biden-2.jpg", "assets/examples/Biden-3.jpg", "assets/examples/Biden-4.jpg"], | |
| "assets/examples/2-output-4.png", | |
| ], | |
| [ | |
| "Two men engaged in a vigorous handshake, both wearing expressions of enthusiasm and determination, set against a backdrop of a bustling business district. The image is crafted in a sleek and modern digital art style, conveying the dynamic and competitive nature of their interaction.", | |
| "assets/examples/Trump-1.jpg", | |
| ["assets/examples/Trump-2.jpg", "assets/examples/Trump-3.jpg", "assets/examples/Trump-4.jpg"], | |
| "assets/examples/Biden-1.jpg", | |
| ["assets/examples/Biden-2.jpg", "assets/examples/Biden-3.jpg", "assets/examples/Biden-4.jpg"], | |
| "assets/examples/2-output-3.png", | |
| ], | |
| ] | |
| gr.Examples( | |
| label="Examples (Multiple References)", | |
| examples=examples, | |
| inputs=[prompt, pil_faceid_1st, pil_supp_faceids_1st, pil_faceid_2nd, pil_supp_faceids_2nd, example_output], | |
| ) | |
| ips = [ | |
| pil_faceid_1st, pil_supp_faceids_1st, | |
| pil_mix_faceid_1_1st, mix_scale_1_1st, | |
| pil_mix_faceid_2_1st, mix_scale_2_1st, | |
| pil_faceid_2nd, pil_supp_faceids_2nd, | |
| pil_mix_faceid_1_2nd, mix_scale_1_2nd, | |
| pil_mix_faceid_2_2nd, mix_scale_2_2nd, | |
| faceid_scale, face_structure_scale, | |
| prompt, negative_prompt, | |
| pil_style, style_scale, | |
| seed, image_resolution, use_sr, | |
| ] | |
| run_button.click(fn=text_to_multi_id_generation_process, inputs=ips, outputs=[result_gallery]) | |
| def image_to_single_id_generation_block(): | |
| gr.Markdown("## Image-to-Single-ID Generation") | |
| gr.HTML(image_to_single_id_description) | |
| gr.HTML(image_to_single_id_tips) | |
| with gr.Row(): | |
| with gr.Column(scale=1, min_width=100): | |
| image_resolution = gr.Dropdown(choices=["768x512", "512x512", "512x768"], value="512x512", | |
| label="Image Resolution (HxW)") | |
| run_button = gr.Button(value="Run") | |
| with gr.Accordion("Advanced Options", open=True): | |
| seed = gr.Slider(label="Seed (-1 indicates random)", minimum=-1, maximum=2147483647, step=1, value=-1) | |
| style_scale = gr.Slider(label="Reference Scale", minimum=0.0, maximum=1.0, step=0.01, value=0.7) | |
| faceid_scale = gr.Slider(label="Face ID Scale", minimum=0.0, maximum=1.0, step=0.01, value=0.7) | |
| face_structure_scale = gr.Slider(label="Face Structure Scale", minimum=0.0, maximum=1.0, step=0.01, | |
| value=0.3) | |
| use_sr = gr.Checkbox(label="RealESRGAN 2x", value=True) | |
| with gr.Column(scale=3, min_width=100): | |
| with gr.Row(equal_height=False): | |
| pil_style = gr.Image(type="pil", label="Portrait Reference") | |
| pil_faceid = gr.Image(type="pil", label="ID Image") | |
| with gr.Accordion("ID Supplements", open=True): | |
| with gr.Row(): | |
| pil_supp_faceids = gr.File(file_count="multiple", file_types=["image"], | |
| type="filepath", label="Additional ID Images") | |
| with gr.Row(): | |
| with gr.Column(scale=1, min_width=100): | |
| pil_mix_faceid_1 = gr.Image(type="pil", label="Mix ID 1") | |
| mix_scale_1 = gr.Slider(label="Mix Scale 1", minimum=0.0, maximum=1.0, step=0.01, value=0.0) | |
| with gr.Column(scale=1, min_width=100): | |
| pil_mix_faceid_2 = gr.Image(type="pil", label="Mix ID 2") | |
| mix_scale_2 = gr.Slider(label="Mix Scale 2", minimum=0.0, maximum=1.0, step=0.01, value=0.0) | |
| with gr.Row(): | |
| with gr.Column(scale=3, min_width=100): | |
| example_output = gr.Image(type="pil", label="(Example Output)", visible=False) | |
| result_gallery = gr.Gallery(label='Output', show_label=True, elem_id="gallery", columns=4, | |
| preview=True, format="png") | |
| with gr.Row(): | |
| examples = [ | |
| [ | |
| "assets/examples/3-style-1.png", | |
| "assets/examples/3-stylegan2-ffhq-0293.png", | |
| 0.7, | |
| 0.3, | |
| "assets/examples/3-output-1.png", | |
| ], | |
| [ | |
| "assets/examples/3-style-1.png", | |
| "assets/examples/3-stylegan2-ffhq-0293.png", | |
| 0.6, | |
| 0.0, | |
| "assets/examples/3-output-2.png", | |
| ], | |
| [ | |
| "assets/examples/3-style-2.jpg", | |
| "assets/examples/3-stylegan2-ffhq-0381.png", | |
| 0.7, | |
| 0.3, | |
| "assets/examples/3-output-3.png", | |
| ], | |
| [ | |
| "assets/examples/3-style-3.jpg", | |
| "assets/examples/3-stylegan2-ffhq-0381.png", | |
| 0.6, | |
| 0.0, | |
| "assets/examples/3-output-4.png", | |
| ], | |
| ] | |
| gr.Examples( | |
| label="Examples", | |
| examples=examples, | |
| inputs=[pil_style, pil_faceid, faceid_scale, face_structure_scale, example_output], | |
| ) | |
| ips = [ | |
| pil_faceid, pil_supp_faceids, | |
| pil_mix_faceid_1, mix_scale_1, | |
| pil_mix_faceid_2, mix_scale_2, | |
| faceid_scale, face_structure_scale, | |
| pil_style, style_scale, | |
| seed, image_resolution, use_sr, | |
| ] | |
| run_button.click(fn=image_to_single_id_generation_process, inputs=ips, outputs=[result_gallery]) | |
| if __name__ == "__main__": | |
| title = r""" | |
| <div style="text-align: center;"> | |
| <h1> UniPortrait: A Unified Framework for Identity-Preserving Single- and Multi-Human Image Personalization </h1> | |
| <div style="display: flex; justify-content: center; align-items: center; text-align: center;"> | |
| <a href="https://arxiv.org/pdf/2408.05939"><img src="https://img.shields.io/badge/arXiv-2408.05939-red"></a> | |
| | |
| <a href='https://aigcdesigngroup.github.io/UniPortrait-Page/'><img src='https://img.shields.io/badge/Project_Page-UniPortrait-green' alt='Project Page'></a> | |
| | |
| <a href="https://github.com/junjiehe96/UniPortrait"><img src="https://img.shields.io/badge/Github-Code-blue"></a> | |
| </div> | |
| </br> | |
| </div> | |
| """ | |
| title_description = r""" | |
| This is the <b>official π€ Gradio demo</b> for <a href='https://arxiv.org/pdf/2408.05939' target='_blank'><b>UniPortrait: A Unified Framework for Identity-Preserving Single- and Multi-Human Image Personalization</b></a>.<br> | |
| The demo provides three capabilities: text-to-single-ID personalization, text-to-multi-ID personalization, and image-to-single-ID personalization. All of these are based on the <b>Stable Diffusion v1-5</b> model. Feel free to give them a try! π | |
| """ | |
| text_to_single_id_description = r"""πππQuick start:<br> | |
| 1. Enter a text prompt (Chinese or English), Upload an image with a face, and Click the <b>Run</b> button.<br> | |
| 2. (Optional) You can also upload an image as the style reference for the results. π€<br> | |
| """ | |
| text_to_single_id_tips = r"""π‘π‘π‘Tips:<br> | |
| 1. Try to avoid creating too small faces, as this may lead to some artifacts. (Currently, the short side length of the generated image is limited to 512)<br> | |
| 2. It's a good idea to upload multiple reference photos of your face to improve the prompt and ID consistency. Additional references can be uploaded in the "ID supplements".<br> | |
| 3. The appropriate values of "Face ID Scale" and "Face Structure Scale" are important for balancing the ID and text alignment. We recommend using "Face ID Scale" (0.5~0.7) and "Face Structure Scale" (0.0~0.4).<br> | |
| """ | |
| text_to_multi_id_description = r"""πππQuick start:<br> | |
| 1. Enter a text prompt (Chinese or English), Upload an image with a face in "First ID" and "Second ID" blocks respectively, and Click the <b>Run</b> button.<br> | |
| 2. (Optional) You can also upload an image as the style reference for the results. π€<br> | |
| """ | |
| text_to_multi_id_tips = r"""π‘π‘π‘Tips:<br> | |
| 1. Try to avoid creating too small faces, as this may lead to some artifacts. (Currently, the short side length of the generated image is limited to 512)<br> | |
| 2. It's a good idea to upload multiple reference photos of your face to improve the prompt and ID consistency. Additional references can be uploaded in the "ID supplements".<br> | |
| 3. The appropriate values of "Face ID Scale" and "Face Structure Scale" are important for balancing the ID and text alignment. We recommend using "Face ID Scale" (0.3~0.7) and "Face Structure Scale" (0.0~0.4).<br> | |
| """ | |
| image_to_single_id_description = r"""πππQuick start: Upload an image as the portrait reference (can be any style), Upload a face image, and Click the <b>Run</b> button. π€<br>""" | |
| image_to_single_id_tips = r"""π‘π‘π‘Tips:<br> | |
| 1. Try to avoid creating too small faces, as this may lead to some artifacts. (Currently, the short side length of the generated image is limited to 512)<br> | |
| 2. It's a good idea to upload multiple reference photos of your face to improve ID consistency. Additional references can be uploaded in the "ID supplements".<br> | |
| 3. The appropriate values of "Face ID Scale" and "Face Structure Scale" are important for balancing the portrait reference and ID alignment. We recommend using "Face ID Scale" (0.5~0.7) and "Face Structure Scale" (0.0~0.4).<br> | |
| """ | |
| citation = r""" | |
| --- | |
| π **Citation** | |
| <br> | |
| If our work is helpful for your research or applications, please cite us via: | |
| ```bibtex | |
| @article{he2024uniportrait, | |
| title={UniPortrait: A Unified Framework for Identity-Preserving Single-and Multi-Human Image Personalization}, | |
| author={He, Junjie and Geng, Yifeng and Bo, Liefeng}, | |
| journal={arXiv preprint arXiv:2408.05939}, | |
| year={2024} | |
| } | |
| ``` | |
| π§ **Contact** | |
| <br> | |
| If you have any questions, please feel free to open an issue or directly reach us out at <b>[email protected]</b>. | |
| """ | |
| block = gr.Blocks(title="UniPortrait").queue() | |
| with block: | |
| gr.HTML(title) | |
| gr.HTML(title_description) | |
| with gr.TabItem("Text-to-Single-ID"): | |
| text_to_single_id_generation_block() | |
| with gr.TabItem("Text-to-Multi-ID"): | |
| text_to_multi_id_generation_block() | |
| with gr.TabItem("Image-to-Single-ID (Stylization)"): | |
| image_to_single_id_generation_block() | |
| gr.Markdown(citation) | |
| block.launch(share=True, max_threads=10) | |
| # block.launch(server_name='0.0.0.0', share=False, server_port=9999, allowed_paths=["/"]) | |
| # block.launch(server_name='127.0.0.1', share=False, server_port=9999, allowed_paths=["/"]) | |