|
import gradio as gr |
|
import numpy as np |
|
import cv2 |
|
import time |
|
from PIL import Image |
|
import io |
|
|
|
def apply_transformations(image, numbers_str): |
|
""" |
|
Apply a series of transformations to an image based on a list of numbers. |
|
Shows the progressive changes as each transformation is applied. |
|
Returns both the current image and the full gallery of transformations. |
|
""" |
|
try: |
|
|
|
numbers = [float(n.strip()) for n in numbers_str.split(',') if n.strip()] |
|
if not numbers: |
|
return image, [(image, "Original Image")] |
|
|
|
|
|
img = np.array(image) |
|
|
|
|
|
results = [(image, "Original Image")] |
|
current_image = image |
|
|
|
|
|
for i, value in enumerate(numbers): |
|
|
|
if i == 0: |
|
current_img = img.copy() |
|
else: |
|
current_img = np.array(current_image) |
|
|
|
|
|
transformation_type = "" |
|
if i % 5 == 0: |
|
|
|
brightness = max(min(value, 100), -100) |
|
current_img = cv2.addWeighted(current_img, 1, np.zeros_like(current_img), 0, brightness) |
|
transformation_type = f"Brightness: {brightness:.1f}" |
|
|
|
elif i % 5 == 1: |
|
|
|
angle = value % 360 |
|
h, w = current_img.shape[:2] |
|
center = (w // 2, h // 2) |
|
rotation_matrix = cv2.getRotationMatrix2D(center, angle, 1.0) |
|
current_img = cv2.warpAffine(current_img, rotation_matrix, (w, h)) |
|
transformation_type = f"Rotation: {angle:.1f}°" |
|
|
|
elif i % 5 == 2: |
|
|
|
contrast = max(min(value / 10, 3), 0.5) |
|
current_img = cv2.convertScaleAbs(current_img, alpha=contrast, beta=0) |
|
transformation_type = f"Contrast: {contrast:.1f}x" |
|
|
|
elif i % 5 == 3: |
|
|
|
blur_amount = max(int(abs(value) % 20), 1) |
|
if blur_amount % 2 == 0: |
|
blur_amount += 1 |
|
current_img = cv2.GaussianBlur(current_img, (blur_amount, blur_amount), 0) |
|
transformation_type = f"Blur: {blur_amount}px" |
|
|
|
elif i % 5 == 4: |
|
if current_img.shape[-1] == 3: |
|
|
|
hsv_img = cv2.cvtColor(current_img, cv2.COLOR_RGB2HSV) |
|
|
|
hue_shift = int(value) % 180 |
|
hsv_img[:, :, 0] = (hsv_img[:, :, 0] + hue_shift) % 180 |
|
|
|
current_img = cv2.cvtColor(hsv_img, cv2.COLOR_HSV2RGB) |
|
transformation_type = f"Hue Shift: {hue_shift}°" |
|
|
|
|
|
current_image = Image.fromarray(current_img) |
|
|
|
|
|
results.append((current_image, f"Step {i+1}: {transformation_type}")) |
|
|
|
|
|
|
|
|
|
time.sleep(4) |
|
|
|
|
|
if i < len(numbers) - 1: |
|
yield current_image, results |
|
|
|
return current_image, results |
|
|
|
except Exception as e: |
|
error_msg = f"Error: {str(e)}" |
|
return image, [(image, "Error")] |
|
|
|
|
|
with gr.Blocks() as demo: |
|
gr.Markdown("# Image Transformation Demo") |
|
gr.Markdown("Upload an image and provide a comma-separated list of numbers. The demo will apply a series of transformations to the image based on these numbers.") |
|
|
|
with gr.Row(): |
|
with gr.Column(scale=1): |
|
input_image = gr.Image(label="Input Image", type="pil") |
|
numbers_input = gr.Textbox(label="Transformation Values (comma-separated numbers)", |
|
placeholder="e.g., 50, -30, 1.5, 5, 90, 20", |
|
value="30, 45, 1.5, 3, 60, -20, 90, 1.8, 7, 120") |
|
transform_btn = gr.Button("Apply Transformations") |
|
|
|
explanation = gr.Markdown(""" |
|
## How the transformations work: |
|
|
|
The numbers you input will be used to apply these transformations in sequence: |
|
1. First number: Brightness adjustment (-100 to 100) |
|
2. Second number: Rotation (degrees) |
|
3. Third number: Contrast adjustment (0.5 to 3) |
|
4. Fourth number: Blur (kernel size) |
|
5. Fifth number: Hue shift (color images only) |
|
|
|
And the pattern repeats for longer lists of numbers. |
|
""") |
|
|
|
with gr.Column(scale=2): |
|
with gr.Row(): |
|
current_image = gr.Image(label="Current Transformation", type="pil") |
|
with gr.Row(): |
|
gallery = gr.Gallery(label="Transformation History", show_label=True, columns=4, rows=2, height="auto") |
|
|
|
transform_btn.click( |
|
fn=apply_transformations, |
|
inputs=[input_image, numbers_input], |
|
outputs=[current_image, gallery] |
|
) |
|
|
|
|
|
demo.launch() |