Stylemixing / app.py
uhdessai's picture
Update app.py
157aa00 verified
# import gradio as gr
# import torch
# import numpy as np
# from PIL import Image
# import os
# import legacy
# import torch_utils
# # Load the pre-trained StyleGAN model
# device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
# model_path = 'dress_model.pkl' # Place your .pkl in the same directory or update path
# # Load StyleGAN Generator
# with open(model_path, 'rb') as f:
# G = legacy.load_network_pkl(f)['G_ema'].to(device)
# def mix_styles(image1_path, image2_path, styles_to_mix):
# # Extract image names (without extensions)
# image1_name = os.path.splitext(os.path.basename(image1_path))[0]
# image2_name = os.path.splitext(os.path.basename(image2_path))[0]
# # Load latent vectors from .npz
# latent_vector_1 = np.load(os.path.join("projection_results", image1_name, "projected_w.npz"))['w']
# latent_vector_2 = np.load(os.path.join("projection_results", image2_name, "projected_w.npz"))['w']
# # Convert to torch tensors
# latent_1_tensor = torch.from_numpy(latent_vector_1).to(device)
# latent_2_tensor = torch.from_numpy(latent_vector_2).to(device)
# # Mix layers
# mixed_latent = latent_1_tensor.clone()
# mixed_latent[:, styles_to_mix] = latent_2_tensor[:, styles_to_mix]
# # Generate image
# with torch.no_grad():
# image = G.synthesis(mixed_latent, noise_mode='const')
# # Convert to image
# image = (image.permute(0, 2, 3, 1) * 127.5 + 128).clamp(0, 255).to(torch.uint8).cpu().numpy()
# mixed_image = Image.fromarray(image[0], 'RGB')
# return mixed_image
# def style_mixing_interface(image1, image2, mix_value):
# if image1 is None or image2 is None:
# return None
# selected_layers = list(range(mix_value + 1))
# return mix_styles(image1, image2, selected_layers)
# # Gradio UI
# iface = gr.Interface(
# fn=style_mixing_interface,
# inputs=[
# gr.Image(label="First Clothing Image", type="filepath"),
# gr.Image(label="Second Clothing Image", type="filepath"),
# gr.Slider(label="Style Mixing Strength (Layers 0 to N)", minimum=0, maximum=9, step=1, value=5)
# ],
# outputs=gr.Image(label="Mixed Clothing Design"),
# live=True,
# title="Style Mixing for Clothing Design",
# description="Upload two projected images and choose how many early layers to mix."
# )
# iface.launch()
# import gradio as gr
# import torch
# import numpy as np
# from PIL import Image
# import os
# import legacy
# import torch_utils
# import requests
# import io
# import warnings
# warnings.filterwarnings("ignore")
# device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
# model_path = 'dress_model.pkl'
# with open(model_path, 'rb') as f:
# G = legacy.load_network_pkl(f)['G_ema'].to(device)
# def mix_styles(image1_path, image2_path, styles_to_mix):
# image1_name = os.path.splitext(os.path.basename(image1_path))[0]
# image2_name = os.path.splitext(os.path.basename(image2_path))[0]
# latent_vector_1 = np.load(os.path.join("projection_results", image1_name, "projected_w.npz"))['w']
# latent_vector_2 = np.load(os.path.join("projection_results", image2_name, "projected_w.npz"))['w']
# latent_1_tensor = torch.from_numpy(latent_vector_1).to(device)
# latent_2_tensor = torch.from_numpy(latent_vector_2).to(device)
# mixed_latent = latent_1_tensor.clone()
# mixed_latent[:, styles_to_mix] = latent_2_tensor[:, styles_to_mix]
# with torch.no_grad():
# image = G.synthesis(mixed_latent, noise_mode='const')
# image = (image.permute(0, 2, 3, 1) * 127.5 + 128).clamp(0, 255).to(torch.uint8).cpu().numpy()
# mixed_image = Image.fromarray(image[0], 'RGB')
# return mixed_image
# def style_mixing_interface(image1, image2, mix_value):
# if image1 is None or image2 is None:
# return None, None
# selected_layers = list(range(mix_value + 1))
# mixed_img = mix_styles(image1, image2, selected_layers)
# buffer = io.BytesIO()
# mixed_img.save(buffer, format="PNG")
# buffer.seek(0)
# return mixed_img, buffer
# def send_to_backend(image_buffer, user_id):
# if not user_id:
# return "❌ user_id not found."
# try:
# files = {'file': ('generated_image.png', image_buffer, 'image/png')}
# url = f"https://5a4d-103-40-74-78.ngrok-free.app/customisation/upload/{user_id}"
# response = requests.post(url, files=files)
# if response.status_code == 201:
# return "βœ… Image uploaded and saved to database!"
# else:
# return f"❌ Upload failed: {response.status_code} - {response.text}"
# except Exception as e:
# return f"⚠️ Error: {str(e)}"
# # --- Gradio UI ---
# with gr.Blocks(title="Style Mixing for Clothing Design") as iface:
# user_id_state = gr.State()
# @iface.load(inputs=None, outputs=[user_id_state])
# def on_load(request: gr.Request):
# user_id = request.query_params.get('user_id', '')
# return user_id
# gr.Markdown("## Style Mixing for Clothing Design\nUpload two projected clothing images and mix their styles.")
# with gr.Row():
# image1_input = gr.Image(label="First Clothing Image", type="filepath")
# image2_input = gr.Image(label="Second Clothing Image", type="filepath")
# mix_slider = gr.Slider(label="Style Mixing Strength (Layers 0 to N)", minimum=0, maximum=9, step=1, value=5)
# with gr.Row():
# output_image = gr.Image(label="Mixed Clothing Design")
# save_button = gr.Button("Download & Save to Database")
# image_buffer = gr.State()
# save_status = gr.Textbox(label="Save Status", interactive=False)
# def mix_and_store(image1, image2, mix_value):
# result_image, buffer = style_mixing_interface(image1, image2, mix_value)
# return result_image, buffer
# mix_slider.change(mix_and_store, inputs=[image1_input, image2_input, mix_slider], outputs=[output_image, image_buffer])
# save_button.click(send_to_backend, inputs=[image_buffer, user_id_state], outputs=[save_status])
# iface.launch()
import gradio as gr
import torch
import numpy as np
from PIL import Image
import os
import legacy
import torch_utils
import requests
import io
import warnings
import gdown
warnings.filterwarnings("ignore")
# -------- CONFIGURATION --------
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
# Google Drive model setup
file_id = "12_fsSQgUfOCAPQaDtq2QPCLE74qTQEwt"
output_path = "dress_model.pkl"
# Download the model if it's not present
if not os.path.exists(output_path):
print("Downloading StyleGAN2 model from Google Drive...")
gdown.download(f"https://drive.google.com/uc?id={file_id}", output_path, quiet=False)
# Load the model
with open(output_path, 'rb') as f:
G = legacy.load_network_pkl(f)['G_ema'].to(device)
# Save model path for projector.py
NETWORK_PKL = output_path
# -------- ENSURE PROJECTION --------
def ensure_projection(image_path):
image_name = os.path.splitext(os.path.basename(image_path))[0]
proj_dir = os.path.join("projection_results", image_name)
proj_file = os.path.join(proj_dir, "projected_w.npz")
if not os.path.exists(proj_file):
print(f"Projection for {image_name} not found. Running projector.py...")
os.makedirs(proj_dir, exist_ok=True)
subprocess.run([
"python", "projector.py",
f"--network={NETWORK_PKL}",
f"--target={image_path}",
f"--outdir={proj_dir}"
], check=True)
return proj_file
# -------- STYLE MIXING --------
def mix_styles(image1_path, image2_path, styles_to_mix):
proj_file1 = ensure_projection(image1_path)
proj_file2 = ensure_projection(image2_path)
latent_vector_1 = np.load(proj_file1)['w']
latent_vector_2 = np.load(proj_file2)['w']
latent_1_tensor = torch.from_numpy(latent_vector_1).to(device)
latent_2_tensor = torch.from_numpy(latent_vector_2).to(device)
mixed_latent = latent_1_tensor.clone()
mixed_latent[:, styles_to_mix] = latent_2_tensor[:, styles_to_mix]
with torch.no_grad():
image = G.synthesis(mixed_latent, noise_mode='const')
image = (image.permute(0, 2, 3, 1) * 127.5 + 128).clamp(0, 255).to(torch.uint8).cpu().numpy()
mixed_image = Image.fromarray(image[0], 'RGB')
return mixed_image
# Handles style mixing + output buffer
def style_mixing_interface(image1, image2, mix_value):
if image1 is None or image2 is None:
return None, None
selected_layers = list(range(mix_value + 1))
mixed_img = mix_styles(image1, image2, selected_layers)
buffer = io.BytesIO()
mixed_img.save(buffer, format="PNG")
buffer.seek(0)
return mixed_img, buffer
# Upload to NestJS backend
def send_to_backend(image_buffer, user_id):
if not user_id:
return "❌ user_id not found."
if image_buffer is None:
return "⚠️ No image generated. Please mix styles first."
try:
# Convert BytesIO to raw bytes before sending
file_bytes = image_buffer.getvalue()
files = {'file': ('generated_image.png', file_bytes, 'image/png')}
# Update with your actual ngrok or server URL
url = f" https://68be601de1e4.ngrok-free.app/customisation/upload/{user_id}"
response = requests.post(url, files=files)
if response.status_code == 201:
return "βœ… Image uploaded and saved to database!"
else:
return f"❌ Upload failed: {response.status_code} - {response.text}"
except Exception as e:
return f"⚠️ Error: {str(e)}"
# Gradio interface
# with gr.Blocks(title="Style Mixing for Clothing Designs") as iface:
# user_id_state = gr.State()
# @iface.load(inputs=None, outputs=[user_id_state])
# def on_load(request: gr.Request):
# user_id = request.query_params.get('user_id', '')
# return user_id
# gr.Markdown("## Style Mixing for Clothing Design\nUpload two projected clothing images and mix their styles.")
# with gr.Row():
# image1_input = gr.Image(label="First Clothing Image", type="filepath")
# image2_input = gr.Image(label="Second Clothing Image", type="filepath")
# mix_slider = gr.Slider(label="Style Mixing Strength", minimum=0, maximum=9, step=1, value=5)
# with gr.Row():
# output_image = gr.Image(label="Mixed Clothing Design")
# save_button = gr.Button("Download & Save to Database")
# image_buffer = gr.State()
# save_status = gr.Textbox(label="Save Status", interactive=False)
# def mix_and_store(image1, image2, mix_value):
# result_image, buffer = style_mixing_interface(image1, image2, mix_value)
# return result_image, buffer
# mix_button = gr.Button("Mix Styles")
# mix_button.click(mix_and_store, inputs=[image1_input, image2_input, mix_slider], outputs=[output_image, image_buffer])
# save_button.click(send_to_backend, inputs=[image_buffer, user_id_state], outputs=[save_status])
# iface.launch()
import gradio as gr
with gr.Blocks(title="Style Mixing for Clothing Designs") as iface:
user_id_state = gr.State()
image_buffer = gr.State()
# Load user ID from URL
@iface.load(inputs=None, outputs=[user_id_state])
def on_load(request: gr.Request):
user_id = request.query_params.get('user_id', '')
return user_id
# Header
gr.Markdown("## 🎨 Style Mixing for Clothing Designs")
gr.Markdown("Upload two projected clothing images and blend their styles using the slider below.")
# Upload Inputs
with gr.Group():
with gr.Row():
image1_input = gr.Image(label="πŸ‘— First Clothing Image", type="filepath",height=256, width=256)
image2_input = gr.Image(label="πŸ‘— Second Clothing Image", type="filepath",height=256, width=256)
mix_slider = gr.Slider(label="πŸ§ͺ Style Mixing Intensity", minimum=0, maximum=9, step=1, value=5, info="0 = Mostly Left | 9 = Mostly Right")
# Output & Actions
with gr.Group():
with gr.Row():
output_image = gr.Image(label="🧡 Mixed Clothing Design",height=256, width=256)
with gr.Row():
mix_button = gr.Button("✨ Mix Styles")
save_button = gr.Button("πŸ’Ύ Save to Database")
save_status = gr.Textbox(label="Status", interactive=False)
# Functions
def mix_and_store(image1, image2, mix_value):
result_image, buffer = style_mixing_interface(image1, image2, mix_value)
return result_image, buffer
# Button Logic
mix_button.click(
fn=mix_and_store,
inputs=[image1_input, image2_input, mix_slider],
outputs=[output_image, image_buffer]
)
save_button.click(
fn=send_to_backend,
inputs=[image_buffer, user_id_state],
outputs=[save_status]
)
iface.launch()