|
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 |
|
|
|
PYTHON_EXECUTABLE = sys.executable |
|
|
|
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") |
|
|
|
|
|
|
|
@spaces.GPU |
|
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. |
|
""" |
|
|
|
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: |
|
|
|
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")) |
|
|
|
|
|
cmd = [ |
|
PYTHON_EXECUTABLE, |
|
"-u", |
|
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...") |
|
|
|
|
|
process = subprocess.Popen( |
|
cmd, |
|
stdout=subprocess.PIPE, |
|
stderr=subprocess.STDOUT, |
|
text=True, |
|
bufsize=1, |
|
universal_newlines=True, |
|
) |
|
|
|
|
|
tqdm_regex = re.compile(r"(\d+)/(\d+)\s*\[.*<.*,.*s/it\]") |
|
|
|
|
|
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)) |
|
|
|
if total_steps > 1: |
|
percent = current_step / total_steps |
|
|
|
progress(percent, desc=f"Denoising...") |
|
|
|
|
|
process.wait() |
|
|
|
|
|
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.") |
|
|
|
|
|
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, |
|
} |
|
|
|
|
|
|
|
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> |
|
""" |
|
|
|
|
|
|
|
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 = """ |
|
.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): |
|
|
|
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, |
|
) |
|
|
|
|
|
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) |
|
|
|
|
|
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", |
|
) |
|
|
|
|
|
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) |
|
|
|
|
|
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) |
|
|