File size: 6,044 Bytes
af7c0ce |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
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:
# Parse the input numbers
numbers = [float(n.strip()) for n in numbers_str.split(',') if n.strip()]
if not numbers:
return image, [(image, "Original Image")]
# Convert PIL Image to numpy array for OpenCV operations
img = np.array(image)
# Initialize the result list with the original image
results = [(image, "Original Image")]
current_image = image
# Apply transformations based on each number
for i, value in enumerate(numbers):
# Make a copy of the current numpy image
if i == 0:
current_img = img.copy()
else:
current_img = np.array(current_image)
# Apply different transformations based on the value
transformation_type = ""
if i % 5 == 0: # Brightness adjustment
# Scale value to reasonable brightness adjustment
brightness = max(min(value, 100), -100) # Limit between -100 and 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: # Rotation
# Scale value to reasonable rotation angle
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 adjustment
# Scale value to reasonable contrast adjustment
contrast = max(min(value / 10, 3), 0.5) # Limit between 0.5 and 3
current_img = cv2.convertScaleAbs(current_img, alpha=contrast, beta=0)
transformation_type = f"Contrast: {contrast:.1f}x"
elif i % 5 == 3: # Blur
# Scale value to reasonable blur kernel size
blur_amount = max(int(abs(value) % 20), 1)
if blur_amount % 2 == 0: # Ensure kernel size is odd
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: # Hue shift (for color images)
if current_img.shape[-1] == 3: # Only for color images
# Convert to HSV
hsv_img = cv2.cvtColor(current_img, cv2.COLOR_RGB2HSV)
# Shift hue
hue_shift = int(value) % 180
hsv_img[:, :, 0] = (hsv_img[:, :, 0] + hue_shift) % 180
# Convert back to RGB
current_img = cv2.cvtColor(hsv_img, cv2.COLOR_HSV2RGB)
transformation_type = f"Hue Shift: {hue_shift}°"
# Convert back to PIL Image and add to results
current_image = Image.fromarray(current_img)
# Add to results with a label for the gallery
results.append((current_image, f"Step {i+1}: {transformation_type}"))
# (Progress updates removed)
# Add a small delay to make the progressive changes visible
time.sleep(4)
# Yield intermediate results for real-time updates
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")]
# Create Gradio Interface
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]
)
# Launch the app
demo.launch() |