pratham0011's picture
Upload 10 files
43be43c verified
import gradio as gr
import tensorflow as tf
import numpy as np
from PIL import Image
from tensorflow.keras.applications.vgg19 import VGG19, preprocess_input
from tensorflow.keras.preprocessing.image import img_to_array
from tensorflow.keras.models import Model
# Load VGG19 model
model = VGG19(include_top=False, weights='imagenet')
model.trainable = False
# Define content and style layers
content_layer = 'block5_conv2'
content_model = Model(inputs=model.input,
outputs=model.get_layer(content_layer).output)
style_layers = ['block1_conv1', 'block3_conv1', 'block5_conv1']
style_models = [Model(inputs=model.input, outputs=model.get_layer(
layer).output) for layer in style_layers]
weight_of_layer = 1. / len(style_models)
def process_image(img):
# Convert to array and preprocess
img = img_to_array(img)
img = preprocess_input(img)
img = np.expand_dims(img, axis=0)
return img
def deprocess(img):
# Perform the inverse of the preprocessing step
img = img.copy() # Create a copy to avoid modifying the original
img[:, :, 0] += 103.939
img[:, :, 1] += 116.779
img[:, :, 2] += 123.68
# Convert BGR to RGB
img = img[:, :, ::-1]
img = np.clip(img, 0, 255).astype('uint8')
return img
# Gram matrix
def gram_matrix(A):
channels = int(A.shape[-1])
a = tf.reshape(A, [-1, channels])
n = tf.shape(a)[0]
gram = tf.matmul(a, a, transpose_a=True)
return gram / tf.cast(n, tf.float32)
# Content loss
def content_loss(content, generated):
a_C = content_model(content)
a_G = content_model(generated)
loss = tf.reduce_mean(tf.square(a_C - a_G))
return loss
# Style loss
def style_cost(style, generated):
J_style = 0
for style_model in style_models:
a_S = style_model(style)
a_G = style_model(generated)
GS = gram_matrix(a_S)
GG = gram_matrix(a_G)
current_cost = tf.reduce_mean(tf.square(GS - GG))
J_style += current_cost * weight_of_layer
return J_style
# Total Loss Function
def compute_total_loss(content, style, generated, alpha=10, beta=1000):
J_content = content_loss(content, generated)
J_style = style_cost(style, generated)
return alpha * J_content + beta * J_style
def ensure_pil_image(img):
if isinstance(img, np.ndarray):
return Image.fromarray(img.astype('uint8'))
return img
def neural_style_transfer(content_img, style_img, iterations=50, alpha=10, beta=1000):
try:
# Ensure we have PIL images
content_img_pil = ensure_pil_image(content_img)
style_img_pil = ensure_pil_image(style_img)
# Resize images to a manageable size
content_img_pil = content_img_pil.resize((300, 300), Image.LANCZOS)
style_img_pil = style_img_pil.resize((300, 300), Image.LANCZOS)
# Process images
content = process_image(content_img_pil)
style = process_image(style_img_pil)
# Initialize with content image
generated = tf.Variable(content, dtype=tf.float32)
# Optimizer
opt = tf.keras.optimizers.Adam(learning_rate=0.7)
progress_images = []
for i in range(iterations):
with tf.GradientTape() as tape:
total_loss = compute_total_loss(
content, style, generated, alpha, beta)
# Get gradients and apply
grads = tape.gradient(total_loss, generated)
opt.apply_gradients([(grads, generated)])
if i % 10 == 0 or i == iterations - 1:
# Save progress image
current_img = generated.numpy()
img_squeezed = np.squeeze(current_img, axis=0)
img_deprocessed = deprocess(img_squeezed)
progress_images.append(Image.fromarray(img_deprocessed))
print(f"Iteration {i}, Loss: {total_loss.numpy()}")
# Get final image
final_img = generated.numpy()
final_img = np.squeeze(final_img, axis=0)
final_img = deprocess(final_img)
return Image.fromarray(final_img), progress_images
except Exception as e:
print(f"Error in neural_style_transfer: {e}")
# Return a default error image
error_img = Image.new('RGB', (300, 300), color='red')
return error_img, []
def style_transfer_interface(content_img, style_img, iterations=50, content_weight=10, style_weight=1000):
# Check if images are provided
if content_img is None or style_img is None:
return None
# Perform style transfer
result_img, _ = neural_style_transfer(
content_img,
style_img,
iterations=iterations,
alpha=content_weight,
beta=style_weight
)
return result_img
# Example images
content_path = "content/images/content"
style_path = "content/styles/style"
example_content_1 = f"{content_path}1.jpg"
example_content_2 = f"{content_path}2.jpg"
example_content_3 = f"{content_path}3.jpg"
example_style_1 = f"{style_path}1.jpg"
example_style_2 = f"{style_path}2.jpg"
example_style_3 = f"{style_path}3.jpg"
examples = [
[example_content_1, example_style_1, 10, 5, 1000],
[example_content_2, example_style_2, 20, 10, 1500],
[example_content_3, example_style_3, 50, 15, 2000],
]
with gr.Blocks(title="Neural Style Transfer") as app:
gr.Markdown("# Neural Style Transfer App")
gr.Markdown(
"Upload a content image and a style image to generate a stylized result")
with gr.Row():
with gr.Column():
content_input = gr.Image(label="Content Image", type="pil")
style_input = gr.Image(label="Style Image", type="pil")
with gr.Row():
iterations_slider = gr.Slider(
minimum=10, maximum=100, value=50, step=10,
label="Iterations"
)
with gr.Row():
content_weight_slider = gr.Slider(
minimum=1, maximum=20, value=10, step=1,
label="Content Weight"
)
style_weight_slider = gr.Slider(
minimum=500, maximum=2000, value=1000, step=100,
label="Style Weight"
)
submit_btn = gr.Button("Generate Stylized Image")
with gr.Column():
output_image = gr.Image(label="Stylized Result")
gr.Examples(
examples=examples,
inputs=[content_input, style_input, iterations_slider,
content_weight_slider, style_weight_slider],
outputs=output_image,
fn=style_transfer_interface,
cache_examples=False,
)
submit_btn.click(
fn=style_transfer_interface,
inputs=[content_input, style_input, iterations_slider,
content_weight_slider, style_weight_slider],
outputs=output_image
)
# Launch the app
if __name__ == "__main__":
app.launch(share=True, debug=True)