Spaces:
Running
on
Zero
Running
on
Zero
import os | |
import gradio as gr | |
import numpy as np | |
from PIL import Image | |
import tempfile | |
import sys | |
import subprocess | |
from pathlib import Path | |
from typing import Optional | |
import re | |
import spaces | |
# NOTE: This script assumes it is located in the project root directory. | |
PYTHON_EXECUTABLE = sys.executable # Or specify a path like "/path/to/your/python" | |
# Construct paths relative to this app's location in the root. | |
APP_DIR = os.path.dirname(os.path.abspath(__file__)) | |
MAIN_SCRIPT_PATH = os.path.join(APP_DIR, "src", "main.py") | |
EXAMPLES_PATH = os.path.join(APP_DIR, "examples") | |
# --- Gradio Interface --- | |
def run_main_script( | |
src_cond_image_np: np.ndarray, | |
tgt_cond_image_np: np.ndarray, | |
original_mv_image_np: np.ndarray, | |
t_steps: int, | |
n_max: int, | |
src_gs: float, | |
tar_gs: float, | |
seed: int, | |
progress=gr.Progress(), | |
): | |
""" | |
Wrapper function for Gradio to prepare files and run the main.py script. | |
""" | |
# Ensure consistent types for filename generation and command-line args. | |
tar_gs = float(tar_gs) | |
n_max = int(n_max) | |
t_steps = int(t_steps) | |
src_gs = float(src_gs) | |
seed = int(seed) | |
if ( | |
src_cond_image_np is None | |
or tgt_cond_image_np is None | |
or original_mv_image_np is None | |
): | |
raise gr.Error("Please provide all three input images.") | |
if not os.path.exists(MAIN_SCRIPT_PATH): | |
raise gr.Error( | |
f"Main script not found at '{MAIN_SCRIPT_PATH}'. Please update the MAIN_SCRIPT_PATH variable in the app." | |
) | |
progress(0, desc="Preparing experiment...") | |
with tempfile.TemporaryDirectory() as exp_dir: | |
# Save uploaded images to the required filenames | |
src_cond_img = Image.fromarray(src_cond_image_np).convert("RGB") | |
tgt_cond_img = Image.fromarray(tgt_cond_image_np).convert("RGB") | |
original_mv_img = Image.fromarray(original_mv_image_np).convert("RGB") | |
src_cond_img.save(os.path.join(exp_dir, "src.png")) | |
tgt_cond_img.save(os.path.join(exp_dir, "edited.png")) | |
original_mv_img.save(os.path.join(exp_dir, "src_mv.png")) | |
# Construct the command to run main.py | |
cmd = [ | |
PYTHON_EXECUTABLE, | |
"-u", # Force unbuffered stdout | |
MAIN_SCRIPT_PATH, | |
"--exp_dir", | |
exp_dir, | |
"--T_steps", | |
str(t_steps), | |
"--n_max", | |
str(n_max), | |
"--src_guidance_scale", | |
str(src_gs), | |
"--tar_guidance_scale", | |
str(tar_gs), | |
"--seed", | |
str(seed), | |
] | |
print(f"🚀 Running command: {' '.join(cmd)}") | |
progress(0.05, desc="Executing main script...") | |
# Execute the script as a subprocess and stream the output. | |
process = subprocess.Popen( | |
cmd, | |
stdout=subprocess.PIPE, | |
stderr=subprocess.STDOUT, # Merge stderr with stdout | |
text=True, | |
bufsize=1, | |
universal_newlines=True, | |
) | |
# Regex to find the main tqdm progress in the format "current/total [time<remaining, speed]" | |
tqdm_regex = re.compile(r"(\d+)/(\d+)\s*\[.*<.*,.*s/it\]") | |
# Print stdout in real-time and update progress bar | |
if process.stdout: | |
for line in iter(process.stdout.readline, ""): | |
print(line, end="") | |
match = tqdm_regex.search(line) | |
if match: | |
current_step = int(match.group(1)) | |
total_steps = int(match.group(2)) | |
# This condition ensures we only track the main, multi-step progress bar | |
if total_steps > 1: | |
percent = current_step / total_steps | |
# Update progress bar with a clean description | |
progress(percent, desc=f"Denoising...") | |
# Wait for the process to finish and get the return code | |
process.wait() | |
# Check for errors after the process has completed | |
if process.returncode != 0: | |
print(f"❌ Script failed with exit code: {process.returncode}") | |
raise gr.Error(f"Script execution failed. Check console for details.") | |
print("\n✅ Script executed successfully.") | |
# Find the output file | |
output_dir = os.path.join(exp_dir, "output") | |
output_filename = f"result_tgs_{tar_gs}_nmax_{n_max}.png" | |
save_path = os.path.join(output_dir, output_filename) | |
progress(0.98, desc="Loading result...") | |
if not os.path.exists(save_path): | |
print(f"❌ Output file not found at expected path: {save_path}") | |
raise gr.Error( | |
"Output file was not created by the script. Check console logs for errors." | |
) | |
result_img = Image.open(save_path) | |
progress(1, desc="Done.") | |
return result_img | |
def clear_inputs(): | |
"""Resets all input fields to their default state and makes them interactive.""" | |
return { | |
original_mv_image: None, | |
src_cond_image: None, | |
tgt_cond_image: None, | |
t_steps: gr.Slider(value=50, interactive=True), | |
n_max: gr.Slider(value=31, interactive=True), | |
src_gs: gr.Slider(value=3.5, interactive=True), | |
tar_gs: gr.Slider(value=5.0, interactive=True), | |
seed: gr.Slider(value=18, interactive=True), | |
output_image: None, | |
} | |
# --- Markdown Content for UI --- | |
ABOUT_TEXT = """ | |
<div style="text-align: center; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;"> | |
<h1 style="font-weight: 800; font-size: 2.5em; margin-bottom: 0.2em;">EditP23: 3D Editing via Propagation of Image Prompts to Multi-View</h1> | |
<div style="margin-bottom: 1.5em; display: flex; justify-content: center; align-items: center; gap: 12px; flex-wrap: wrap;"> | |
<a href="https://editp23.github.io/" target="_blank" class="link-button" style="background-color: #1d6aef;">▶️ Project Page</a> | |
<a href="https://arxiv.org/abs/2506.20652" target="_blank" class="link-button" style="background-color: #b31b1b;">📄 arXiv</a> | |
<a href="https://github.com/editp23/editp23" target="_blank" class="link-button" style="background-color: #24292e;">💻 GitHub</a> | |
</div> | |
<p style="font-size: 1.1em; max-width: 800px; margin: auto; line-height: 1.6;"> | |
This is the official Gradio demo for <strong>EditP23</strong>, a method for fast, mask-free 3D editing that propagates 2D image edits to multi-view representations in a 3D-consistent manner. The edit is guided by an image pair, allowing users to leverage any preferred 2D editing tool, from manual painting to generative pipelines. | |
</p> | |
</div> | |
""" | |
HOW_TO_USE_TEXT = """ | |
<div id="how-to-use-container"> | |
<h2 id="understanding-inputs">Understanding the Inputs</h2> | |
<p><strong>EditP23</strong> requires three specific images to perform an edit. This demo automates the process, but understanding each component is key.</p> | |
<ol> | |
<li><strong>Original Multi-View Image (`src_mv.png`)</strong>: This is a 2x3 grid of six different views of the original, unedited object. The model uses this as the base to apply the edit consistently across all angles.</li> | |
<li><strong>Source Condition (`src.png`)</strong>: This is a single, frontal view of the original object. It acts as the "before" image for the edit.</li> | |
<li><strong>Target Condition (`edited.png`)</strong>: This is the "after" image. It's the same view as <code>src.png</code>, but with your desired 2D modification applied. The difference between this image and <code>src.png</code> is what guides the 3D edit.</li> | |
</ol> | |
<hr> | |
<h2 id="prepare-images">How to Prepare Your Own Images</h2> | |
<p>You can generate the required input images using the helper scripts provided in our <a href="https://github.com/editp23/editp23" target="_blank">GitHub repository</a>.</p> | |
<h4><strong>Step 1: Generate <code>src.png</code> and <code>src_mv.png</code></strong></h4> | |
<p>You have two options for creating the initial views of your object.</p> | |
<ul> | |
<li><strong>Method A: From a Single Image</strong><br>If you have a single image of an object, you can generate the multi-view grid using our <code>img2mv.py</code> script. | |
<pre><code>python scripts/img2mv.py --input_image "path/to/your_image.png" --output_dir "path/to/output/"</code></pre> | |
</li> | |
<li><strong>Method B: From a 3D Mesh (<code>.glb</code>, <code>.obj</code>)</strong><br>If you have a 3D model, you can render the required views using our Blender script. | |
<pre><code>python scripts/render_mesh.py --mesh_path "path/to/your_model.glb" --output_dir "path/to/output/"</code></pre> | |
</li> | |
</ul> | |
<h4><strong>Step 2: Create <code>edited.png</code></strong></h4> | |
<p>Use any 2D image editor to modify your <code>src.png</code>. This is where your creativity comes in! For quick edits, we recommend these online tools:</p> | |
<ul> | |
<li><a href="https://huggingface.co/spaces/fallenshock/FlowEdit" target="_blank">FlowEdit</a>: Excellent for global, structural edits.</li> | |
<li><a href="https://huggingface.co/spaces/black-forest-labs/FLUX.1-Fill-dev" target="_blank">Flux-Inpainting</a>: Great for local modifications and inpainting.</li> | |
</ul> | |
<hr> | |
<h2 id="understanding-params">Understanding the Parameters</h2> | |
<ul> | |
<li><strong><code>n_max</code></strong>: Controls how many denoising steps are influenced by your edit. Higher values are needed for more significant geometric changes.</li> | |
<li><strong><code>tar_guidance_scale</code></strong>: Determines the strength of your edit. Increase this for more dramatic changes, but be aware that very high values can sometimes introduce artifacts.</li> | |
<li><strong><code>src_guidance_scale</code></strong>: Controls how strongly the model adheres to the original object's identity. This can usually be left at its default value.</li> | |
</ul> | |
<hr> | |
<h2 id="reconstruct-model">Reconstructing a 3D Model</h2> | |
<p>After this demo generates an edited multi-view image, you can use the <code>scripts/recon.py</code> script from our repository to convert it back into a 3D model (<code>.obj</code> file).</p> | |
<pre><code>python scripts/recon.py path/to/instant-mesh-large.yaml --input_file "path/to/edited_mv.png" --output_dir "path/to/output/"</code></pre> | |
</div> | |
""" | |
# --- Gradio UI Layout --- | |
# Create a custom theme to match the website's color | |
theme = gr.themes.Base( | |
primary_hue=gr.themes.colors.blue, | |
secondary_hue=gr.themes.colors.blue, | |
font=[gr.themes.GoogleFont("Inter"), "ui-sans-serif", "system-ui", "sans-serif"], | |
).set( | |
button_primary_background_fill="*primary_500", | |
button_primary_background_fill_hover="*primary_600", | |
) | |
# Custom CSS for better layout and fixing UI quirks | |
CUSTOM_CSS = """ | |
.gradio-container { max-width: 95% !important; } | |
.label-wrap { padding-top: 6px !import ant; } /* Fix label overlap */ | |
.help-text { color: #9CA3AF; font-size: 0.9rem; margin-top: 4px; margin-bottom: 12px; } | |
.link-button { text-decoration: none; color: white; padding: 8px 16px; border-radius: 8px; font-weight: bold; transition: background-color 0.2s ease; } | |
.link-button:hover { background-color: #4a5568 !important; } | |
#action-buttons { margin-top: 1rem; } | |
/* --- CSS Rules for the Examples Table --- */ | |
/* 1. CRITICAL FIX: Target the image's wrapper to prevent clipping. */ | |
#example-table td > div { | |
overflow: visible !important; /* This is the key to stop cropping. */ | |
display: flex; | |
justify-content: center; | |
align-items: center; | |
} | |
/* 2. General cell styling for alignment and spacing */ | |
#example-table td { | |
vertical-align: middle !important; | |
padding: 8px !important; | |
} | |
/* 3. Force parameter columns (4-7) to have the same width */ | |
#example-table th:nth-child(n+4):nth-child(-n+7), | |
#example-table td:nth-child(n+4):nth-child(-n+7) { | |
width: 85px !important; | |
max-width: 85px !important; | |
text-align: center; | |
word-break: break-word; | |
} | |
/* 4. Enlarge multi-view image (Col 1) with a 3:2 height:width ratio */ | |
#example-table td:nth-child(1) img { | |
height: 180px !important; | |
width: 120px !important; /* 180px / 120px = 3:2 ratio */ | |
object-fit: contain !important; /* Ensures the whole image is visible */ | |
} | |
/* 5. Enlarge condition images (Col 2 & 3) */ | |
#example-table td:nth-child(2) img, | |
#example-table td:nth-child(3) img { | |
height: 150px !important; | |
width: 150px !important; | |
object-fit: contain !important; | |
} | |
""" | |
with gr.Blocks(theme=theme, css=CUSTOM_CSS) as demo: | |
gr.Markdown(ABOUT_TEXT) | |
with gr.Tabs() as tabs: | |
with gr.TabItem("Interactive Demo", id=0): | |
with gr.Row(variant="panel", equal_height=False): | |
# Column 1: Inputs | |
with gr.Column(scale=1): | |
gr.Markdown("### 1. Input Images") | |
gr.Markdown( | |
'See the "How to Use" tab for details on generating the **Multi-View Image** and creating your own **Edited Condition**.', | |
elem_classes="help-text", | |
) | |
original_mv_image = gr.Image( | |
type="numpy", | |
label="Original Multi-View Image (src_mv.png)", | |
height=675, | |
width=450, | |
) | |
with gr.Row(): | |
src_cond_image = gr.Image( | |
type="numpy", | |
label="Source Condition (src.png)", | |
height=350, | |
width=350, | |
) | |
tgt_cond_image = gr.Image( | |
type="numpy", | |
label="Target Condition (edited.png)", | |
height=350, | |
width=350, | |
) | |
# Column 2: Parameters & Action | |
with gr.Column(scale=1, min_width=300): | |
gr.Markdown("### 2. Parameters") | |
with gr.Accordion("Advanced Parameters", open=True): | |
t_steps = gr.Slider( | |
minimum=1, | |
maximum=100, | |
value=50, | |
step=1, | |
label="T_steps", | |
info="Total number of denoising steps.", | |
) | |
n_max = gr.Slider( | |
minimum=1, | |
maximum=50, | |
value=31, | |
step=1, | |
label="n_max", | |
info="Number of scheduler steps for edit-aware guidance. Increase for more significant edits.", | |
) | |
src_gs = gr.Slider( | |
minimum=1.0, | |
maximum=10.0, | |
value=3.5, | |
step=0.1, | |
label="Source CFG", | |
info="Guidance scale for the source condition. Can typically remain constant.", | |
) | |
tar_gs = gr.Slider( | |
minimum=1.0, | |
maximum=30.0, | |
value=5.0, | |
step=0.1, | |
label="Target CFG", | |
info="Guidance scale for the target condition. Increase for more significant edits.", | |
) | |
seed = gr.Slider( | |
minimum=0, | |
maximum=10000, | |
value=18, | |
step=1, | |
label="Seed", | |
info="Random seed for reproducibility.", | |
) | |
with gr.Row(elem_id="action-buttons"): | |
clear_button = gr.Button("Clear", variant="secondary", scale=1) | |
run_button = gr.Button("Generate", variant="primary", scale=2) | |
# Column 3: Output | |
with gr.Column(scale=2, min_width=350): | |
gr.Markdown("### 3. Output Image") | |
output_image = gr.Image( | |
type="pil", | |
label="Edited Result", | |
height=450, | |
width=450, | |
interactive=False, | |
) | |
gr.Markdown( | |
'After generating, you can use the `recon.py` script to create a 3D model. See the "How to Use" tab for the full command.', | |
elem_classes="help-text", | |
) | |
# --- Examples Section --- | |
if os.path.exists(EXAMPLES_PATH): | |
gr.Markdown("---") | |
gr.Markdown("### Click an Example to Load") | |
example_inputs = [ | |
original_mv_image, | |
src_cond_image, | |
tgt_cond_image, | |
t_steps, | |
n_max, | |
src_gs, | |
tar_gs, | |
] | |
example_data = [ | |
[ | |
os.path.join(EXAMPLES_PATH, "bike_vintage", "src_mv.png"), | |
os.path.join(EXAMPLES_PATH, "bike_vintage", "src.png"), | |
os.path.join(EXAMPLES_PATH, "bike_vintage", "edited.png"), | |
50, | |
31, | |
3.5, | |
5.0, | |
18, | |
], | |
[ | |
os.path.join(EXAMPLES_PATH, "robot_sunglasses", "src_mv.png"), | |
os.path.join(EXAMPLES_PATH, "robot_sunglasses", "src.png"), | |
os.path.join(EXAMPLES_PATH, "robot_sunglasses", "edited.png"), | |
50, | |
31, | |
3.5, | |
5.0, | |
18, | |
], | |
[ | |
os.path.join(EXAMPLES_PATH, "stormtrooper_donut", "src_mv.png"), | |
os.path.join(EXAMPLES_PATH, "stormtrooper_donut", "src.png"), | |
os.path.join(EXAMPLES_PATH, "stormtrooper_donut", "edited.png"), | |
50, | |
42, | |
3.5, | |
12.0, | |
18, | |
], | |
[ | |
os.path.join(EXAMPLES_PATH, "figure_zombie", "src_mv.png"), | |
os.path.join(EXAMPLES_PATH, "figure_zombie", "src.png"), | |
os.path.join(EXAMPLES_PATH, "figure_zombie", "edited.png"), | |
50, | |
31, | |
3.5, | |
5.0, | |
18, | |
], | |
[ | |
os.path.join(EXAMPLES_PATH, "deer_pixar", "src_mv.png"), | |
os.path.join(EXAMPLES_PATH, "deer_pixar", "src.png"), | |
os.path.join(EXAMPLES_PATH, "deer_pixar", "edited.png"), | |
50, | |
31, | |
3.5, | |
5.0, | |
18, | |
], | |
[ | |
os.path.join(EXAMPLES_PATH, "german-shep_plush", "src_mv.png"), | |
os.path.join(EXAMPLES_PATH, "german-shep_plush", "src.png"), | |
os.path.join(EXAMPLES_PATH, "german-shep_plush", "edited.png"), | |
50, | |
41, | |
3.5, | |
6.0, | |
18, | |
], | |
[ | |
os.path.join(EXAMPLES_PATH, "deer_wings", "src_mv.png"), | |
os.path.join(EXAMPLES_PATH, "deer_wings", "src.png"), | |
os.path.join(EXAMPLES_PATH, "deer_wings", "edited.png"), | |
50, | |
39, | |
3.5, | |
21.0, | |
18, | |
], | |
[ | |
os.path.join(EXAMPLES_PATH, "lego-car_spoiler", "src_mv.png"), | |
os.path.join(EXAMPLES_PATH, "lego-car_spoiler", "src.png"), | |
os.path.join(EXAMPLES_PATH, "lego-car_spoiler", "edited.png"), | |
50, | |
42, | |
3.5, | |
12.0, | |
18, | |
], | |
[ | |
os.path.join(EXAMPLES_PATH, "batman_jetpack", "src_mv.png"), | |
os.path.join(EXAMPLES_PATH, "batman_jetpack", "src.png"), | |
os.path.join(EXAMPLES_PATH, "batman_jetpack", "edited.png"), | |
50, | |
31, | |
3.5, | |
5.0, | |
18, | |
], | |
[ | |
os.path.join(EXAMPLES_PATH, "bike_sport", "src_mv.png"), | |
os.path.join(EXAMPLES_PATH, "bike_sport", "src.png"), | |
os.path.join(EXAMPLES_PATH, "bike_sport", "edited.png"), | |
50, | |
31, | |
3.5, | |
5.0, | |
18, | |
], | |
[ | |
os.path.join(EXAMPLES_PATH, "red-dragon_tail", "src_mv.png"), | |
os.path.join(EXAMPLES_PATH, "red-dragon_tail", "src.png"), | |
os.path.join(EXAMPLES_PATH, "red-dragon_tail", "edited.png"), | |
50, | |
41, | |
3.5, | |
6.0, | |
18, | |
], | |
[ | |
os.path.join(EXAMPLES_PATH, "cake_oreo", "src_mv.png"), | |
os.path.join(EXAMPLES_PATH, "cake_oreo", "src.png"), | |
os.path.join(EXAMPLES_PATH, "cake_oreo", "edited.png"), | |
50, | |
31, | |
3.5, | |
5.0, | |
18, | |
], | |
[ | |
os.path.join(EXAMPLES_PATH, "bike_harley", "src_mv.png"), | |
os.path.join(EXAMPLES_PATH, "bike_harley", "src.png"), | |
os.path.join(EXAMPLES_PATH, "bike_harley", "edited.png"), | |
50, | |
31, | |
3.5, | |
5.0, | |
18, | |
], | |
[ | |
os.path.join(EXAMPLES_PATH, "bike_modern", "src_mv.png"), | |
os.path.join(EXAMPLES_PATH, "bike_modern", "src.png"), | |
os.path.join(EXAMPLES_PATH, "bike_modern", "edited.png"), | |
50, | |
31, | |
3.5, | |
5.0, | |
18, | |
], | |
[ | |
os.path.join(EXAMPLES_PATH, "bmw_speedy", "src_mv.png"), | |
os.path.join(EXAMPLES_PATH, "bmw_speedy", "src.png"), | |
os.path.join(EXAMPLES_PATH, "bmw_speedy", "edited.png"), | |
50, | |
31, | |
3.5, | |
5.0, | |
18, | |
], | |
[ | |
os.path.join(EXAMPLES_PATH, "batman_backpack", "src_mv.png"), | |
os.path.join(EXAMPLES_PATH, "batman_backpack", "src.png"), | |
os.path.join(EXAMPLES_PATH, "batman_backpack", "edited.png"), | |
50, | |
31, | |
3.5, | |
5.0, | |
18, | |
], | |
[ | |
os.path.join(EXAMPLES_PATH, "figure_backpack", "src_mv.png"), | |
os.path.join(EXAMPLES_PATH, "figure_backpack", "src.png"), | |
os.path.join(EXAMPLES_PATH, "figure_backpack", "edited.png"), | |
50, | |
31, | |
3.5, | |
5.0, | |
18, | |
], | |
[ | |
os.path.join(EXAMPLES_PATH, "car_cartoon", "src_mv.png"), | |
os.path.join(EXAMPLES_PATH, "car_cartoon", "src.png"), | |
os.path.join(EXAMPLES_PATH, "car_cartoon", "edited.png"), | |
50, | |
31, | |
3.5, | |
5.0, | |
18, | |
], | |
[ | |
os.path.join(EXAMPLES_PATH, "car_engine", "src_mv.png"), | |
os.path.join(EXAMPLES_PATH, "car_engine", "src.png"), | |
os.path.join(EXAMPLES_PATH, "car_engine", "edited.png"), | |
50, | |
31, | |
3.5, | |
5.0, | |
18, | |
], | |
[ | |
os.path.join(EXAMPLES_PATH, "car_steampunk", "src_mv.png"), | |
os.path.join(EXAMPLES_PATH, "car_steampunk", "src.png"), | |
os.path.join(EXAMPLES_PATH, "car_steampunk", "edited.png"), | |
50, | |
41, | |
3.5, | |
6.0, | |
18, | |
], | |
[ | |
os.path.join(EXAMPLES_PATH, "green-dragon_skirt", "src_mv.png"), | |
os.path.join(EXAMPLES_PATH, "green-dragon_skirt", "src.png"), | |
os.path.join(EXAMPLES_PATH, "green-dragon_skirt", "edited.png"), | |
50, | |
41, | |
3.5, | |
6.0, | |
18, | |
], | |
[ | |
os.path.join(EXAMPLES_PATH, "gazebo_pagoda", "src_mv.png"), | |
os.path.join(EXAMPLES_PATH, "gazebo_pagoda", "src.png"), | |
os.path.join(EXAMPLES_PATH, "gazebo_pagoda", "edited.png"), | |
50, | |
41, | |
3.5, | |
6.0, | |
18, | |
], | |
[ | |
os.path.join(EXAMPLES_PATH, "oasis_magical", "src_mv.png"), | |
os.path.join(EXAMPLES_PATH, "oasis_magical", "src.png"), | |
os.path.join(EXAMPLES_PATH, "oasis_magical", "edited.png"), | |
50, | |
39, | |
3.5, | |
5.0, | |
18, | |
], | |
[ | |
os.path.join(EXAMPLES_PATH, "cabin_alpine", "src_mv.png"), | |
os.path.join(EXAMPLES_PATH, "cabin_alpine", "src.png"), | |
os.path.join(EXAMPLES_PATH, "cabin_alpine", "edited.png"), | |
50, | |
42, | |
3.5, | |
12.0, | |
18, | |
], | |
[ | |
os.path.join(EXAMPLES_PATH, "cabin_gothic", "src_mv.png"), | |
os.path.join(EXAMPLES_PATH, "cabin_gothic", "src.png"), | |
os.path.join(EXAMPLES_PATH, "cabin_gothic", "edited.png"), | |
50, | |
42, | |
3.5, | |
12.0, | |
18, | |
], | |
[ | |
os.path.join(EXAMPLES_PATH, "fox_tuxedo", "src_mv.png"), | |
os.path.join(EXAMPLES_PATH, "fox_tuxedo", "src.png"), | |
os.path.join(EXAMPLES_PATH, "fox_tuxedo", "edited.png"), | |
50, | |
31, | |
3.5, | |
5.0, | |
18, | |
], | |
[ | |
os.path.join(EXAMPLES_PATH, "cabin_haunted", "src_mv.png"), | |
os.path.join(EXAMPLES_PATH, "cabin_haunted", "src.png"), | |
os.path.join(EXAMPLES_PATH, "cabin_haunted", "edited.png"), | |
50, | |
42, | |
3.5, | |
12.0, | |
18, | |
], | |
[ | |
os.path.join(EXAMPLES_PATH, "fox_eyes", "src_mv.png"), | |
os.path.join(EXAMPLES_PATH, "fox_eyes", "src.png"), | |
os.path.join(EXAMPLES_PATH, "fox_eyes", "edited.png"), | |
50, | |
31, | |
3.5, | |
5.0, | |
18, | |
], | |
[ | |
os.path.join(EXAMPLES_PATH, "gazebo_disney", "src_mv.png"), | |
os.path.join(EXAMPLES_PATH, "gazebo_disney", "src.png"), | |
os.path.join(EXAMPLES_PATH, "gazebo_disney", "edited.png"), | |
50, | |
31, | |
3.5, | |
5.0, | |
18, | |
], | |
[ | |
os.path.join(EXAMPLES_PATH, "desk_wizard", "src_mv.png"), | |
os.path.join(EXAMPLES_PATH, "desk_wizard", "src.png"), | |
os.path.join(EXAMPLES_PATH, "desk_wizard", "edited.png"), | |
50, | |
42, | |
3.5, | |
12.0, | |
18, | |
], | |
[ | |
os.path.join(EXAMPLES_PATH, "gazebo_light", "src_mv.png"), | |
os.path.join(EXAMPLES_PATH, "gazebo_light", "src.png"), | |
os.path.join(EXAMPLES_PATH, "gazebo_light", "edited.png"), | |
50, | |
31, | |
3.5, | |
5.0, | |
18, | |
], | |
[ | |
os.path.join(EXAMPLES_PATH, "gazebo_roof", "src_mv.png"), | |
os.path.join(EXAMPLES_PATH, "gazebo_roof", "src.png"), | |
os.path.join(EXAMPLES_PATH, "gazebo_roof", "edited.png"), | |
50, | |
39, | |
3.5, | |
5.0, | |
18, | |
], | |
[ | |
os.path.join(EXAMPLES_PATH, "grogu_earphones", "src_mv.png"), | |
os.path.join(EXAMPLES_PATH, "grogu_earphones", "src.png"), | |
os.path.join(EXAMPLES_PATH, "grogu_earphones", "edited.png"), | |
50, | |
41, | |
3.5, | |
6.0, | |
18, | |
], | |
[ | |
os.path.join(EXAMPLES_PATH, "gazebo_rust", "src_mv.png"), | |
os.path.join(EXAMPLES_PATH, "gazebo_rust", "src.png"), | |
os.path.join(EXAMPLES_PATH, "gazebo_rust", "edited.png"), | |
50, | |
39, | |
3.5, | |
5.0, | |
18, | |
], | |
[ | |
os.path.join(EXAMPLES_PATH, "german-shep_pixar", "src_mv.png"), | |
os.path.join(EXAMPLES_PATH, "german-shep_pixar", "src.png"), | |
os.path.join(EXAMPLES_PATH, "german-shep_pixar", "edited.png"), | |
50, | |
39, | |
3.5, | |
5.0, | |
18, | |
], | |
[ | |
os.path.join(EXAMPLES_PATH, "grogu_kimono", "src_mv.png"), | |
os.path.join(EXAMPLES_PATH, "grogu_kimono", "src.png"), | |
os.path.join(EXAMPLES_PATH, "grogu_kimono", "edited.png"), | |
50, | |
39, | |
3.5, | |
21.0, | |
18, | |
], | |
[ | |
os.path.join(EXAMPLES_PATH, "ship_fantasy", "src_mv.png"), | |
os.path.join(EXAMPLES_PATH, "ship_fantasy", "src.png"), | |
os.path.join(EXAMPLES_PATH, "ship_fantasy", "edited.png"), | |
50, | |
31, | |
3.5, | |
5.0, | |
18, | |
], | |
[ | |
os.path.join(EXAMPLES_PATH, "grogu_lego-fig", "src_mv.png"), | |
os.path.join(EXAMPLES_PATH, "grogu_lego-fig", "src.png"), | |
os.path.join(EXAMPLES_PATH, "grogu_lego-fig", "edited.png"), | |
50, | |
39, | |
3.5, | |
21.0, | |
18, | |
], | |
[ | |
os.path.join(EXAMPLES_PATH, "lego-car_spoiler", "src_mv.png"), | |
os.path.join(EXAMPLES_PATH, "lego-car_spoiler", "src.png"), | |
os.path.join(EXAMPLES_PATH, "lego-car_spoiler", "edited.png"), | |
50, | |
39, | |
3.5, | |
5.0, | |
18, | |
], | |
[ | |
os.path.join(EXAMPLES_PATH, "nurse_sporty", "src_mv.png"), | |
os.path.join(EXAMPLES_PATH, "nurse_sporty", "src.png"), | |
os.path.join(EXAMPLES_PATH, "nurse_sporty", "edited.png"), | |
50, | |
31, | |
3.5, | |
5.0, | |
18, | |
], | |
[ | |
os.path.join(EXAMPLES_PATH, "r2d2_golden", "src_mv.png"), | |
os.path.join(EXAMPLES_PATH, "r2d2_golden", "src.png"), | |
os.path.join(EXAMPLES_PATH, "r2d2_golden", "edited.png"), | |
50, | |
31, | |
3.5, | |
5.0, | |
18, | |
], | |
[ | |
os.path.join(EXAMPLES_PATH, "grogu_the-force", "src_mv.png"), | |
os.path.join(EXAMPLES_PATH, "grogu_the-force", "src.png"), | |
os.path.join(EXAMPLES_PATH, "grogu_the-force", "edited.png"), | |
50, | |
39, | |
3.5, | |
21.0, | |
18, | |
], | |
[ | |
os.path.join(EXAMPLES_PATH, "spiderbot_chrome", "src_mv.png"), | |
os.path.join(EXAMPLES_PATH, "spiderbot_chrome", "src.png"), | |
os.path.join(EXAMPLES_PATH, "spiderbot_chrome", "edited.png"), | |
50, | |
31, | |
3.5, | |
5.0, | |
18, | |
], | |
[ | |
os.path.join( | |
EXAMPLES_PATH, "spiderbot_steampunk", "src_mv.png" | |
), | |
os.path.join(EXAMPLES_PATH, "spiderbot_steampunk", "src.png"), | |
os.path.join( | |
EXAMPLES_PATH, "spiderbot_steampunk", "edited.png" | |
), | |
50, | |
31, | |
3.5, | |
5.0, | |
18, | |
], | |
[ | |
os.path.join(EXAMPLES_PATH, "superman_crossed", "src_mv.png"), | |
os.path.join(EXAMPLES_PATH, "superman_crossed", "src.png"), | |
os.path.join(EXAMPLES_PATH, "superman_crossed", "edited.png"), | |
50, | |
39, | |
3.5, | |
5.0, | |
18, | |
], | |
] | |
gr.Examples( | |
examples=example_data, | |
inputs=example_inputs, | |
label="Example Edits", | |
examples_per_page=10, | |
elem_id="example-table" | |
) | |
with gr.TabItem("How to Use", id=1): | |
gr.Markdown(HOW_TO_USE_TEXT) | |
# Define button actions | |
run_button.click( | |
fn=run_main_script, | |
inputs=[ | |
src_cond_image, | |
tgt_cond_image, | |
original_mv_image, | |
t_steps, | |
n_max, | |
src_gs, | |
tar_gs, | |
seed, | |
], | |
outputs=output_image, | |
) | |
clear_button.click( | |
fn=clear_inputs, | |
inputs=[], | |
outputs=[ | |
original_mv_image, | |
src_cond_image, | |
tgt_cond_image, | |
t_steps, | |
n_max, | |
src_gs, | |
tar_gs, | |
seed, | |
output_image, | |
], | |
) | |
if __name__ == "__main__": | |
demo.launch(share=True) | |