Vision / app.py
sjagird1's picture
Create app.py
cc7361e verified
raw
history blame
5.46 kB
import gradio as gr
import torch
import numpy as np
from PIL import Image
from scipy.ndimage import gaussian_filter
from transformers import pipeline
def preprocess_image(image):
"""Resize and convert image to PIL format if needed."""
if isinstance(image, np.ndarray):
image = Image.fromarray(image)
# Resize to 512x512 while maintaining aspect ratio
image = image.resize((512, 512))
return image
def segment_image(image, model_name="facebook/mask2former-swin-large-cityscapes-semantic"):
"""Perform semantic segmentation on the input image."""
from transformers import AutoImageProcessor, Mask2FormerForUniversalSegmentation
# Load processor and model
processor = AutoImageProcessor.from_pretrained(model_name)
model = Mask2FormerForUniversalSegmentation.from_pretrained(model_name)
# Prepare inputs
inputs = processor(images=image, return_tensors="pt")
# Run inference
with torch.no_grad():
outputs = model(**inputs)
# Post-process segmentation
semantic_map = processor.post_process_semantic_segmentation(
outputs,
target_sizes=[image.size[::-1]]
)[0]
# Convert to numpy and create binary mask
semantic_map = semantic_map.numpy()
return semantic_map
def apply_gaussian_blur(image, sigma=15):
"""Apply Gaussian blur to the background."""
# Convert image to numpy array
image_array = np.array(image)
# Create segmentation mask (assuming we want to keep the foreground)
segmentation_mask = segment_image(image)
# Choose a prominent object class (e.g., person with ID 24 in Cityscapes)
foreground_mask = (segmentation_mask == 24).astype(np.uint8)
# Prepare blurred version
blurred = np.zeros_like(image_array)
for channel in range(3):
blurred[:, :, channel] = gaussian_filter(image_array[:, :, channel], sigma=sigma)
# Combine original and blurred images based on mask
mask_3d = np.stack([foreground_mask] * 3, axis=2)
result = image_array * mask_3d + blurred * (1 - mask_3d)
return Image.fromarray(result.astype(np.uint8))
def estimate_depth(image, model_name="depth-anything/Depth-Anything-V2-Small-hf"):
"""Estimate depth of the image."""
depth_estimator = pipeline(
task="depth-estimation",
model=model_name,
torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32
)
depth_output = depth_estimator(image)
depth_map = np.array(depth_output["depth"])
# Normalize depth map
depth_map = (depth_map - depth_map.min()) / (depth_map.max() - depth_map.min())
return depth_map
def apply_depth_aware_blur(image, max_sigma=10, min_sigma=0):
"""Apply depth-aware blur to the image."""
# Estimate depth
depth_map = estimate_depth(image)
image_array = np.array(image)
blurred = np.zeros_like(image_array, dtype=np.float32)
# Interpolate sigmas based on depth
sigmas = np.interp(depth_map, [0, 1], [min_sigma, max_sigma])
# Precompute blurred layers
blur_stack = {}
for sigma in np.unique(sigmas):
if sigma > 0:
blurred_layer = np.zeros_like(image_array, dtype=np.float32)
for channel in range(3):
blurred_layer[:, :, channel] = gaussian_filter(
image_array[:, :, channel].astype(np.float32),
sigma=sigma
)
blur_stack[sigma] = blurred_layer
# Blend based on depth
for sigma in np.unique(sigmas):
if sigma > 0:
mask = (sigmas == sigma)
mask_3d = np.stack([mask] * 3, axis=2)
blurred += mask_3d * blur_stack[sigma]
else:
mask = (sigmas == 0)
mask_3d = np.stack([mask] * 3, axis=2)
blurred += mask_3d * image_array
return Image.fromarray(blurred.astype(np.uint8))
def process_image(image, blur_type, sigma=15):
"""Process image based on blur type."""
# Preprocess image
pil_image = preprocess_image(image)
# Apply appropriate blur
if blur_type == "Gaussian Background Blur":
result = apply_gaussian_blur(pil_image, sigma)
elif blur_type == "Depth-Aware Lens Blur":
result = apply_depth_aware_blur(pil_image, max_sigma=sigma)
else:
result = pil_image
return result
# Gradio Interface
def create_blur_app():
with gr.Blocks() as demo:
gr.Markdown("# Image Blur Effects")
with gr.Row():
input_image = gr.Image(label="Input Image", type="pil")
output_image = gr.Image(label="Processed Image")
with gr.Row():
blur_type = gr.Dropdown(
choices=[
"Gaussian Background Blur",
"Depth-Aware Lens Blur"
],
label="Blur Type"
)
sigma = gr.Slider(
minimum=0,
maximum=30,
value=15,
label="Blur Intensity"
)
process_btn = gr.Button("Apply Blur Effect")
process_btn.click(
fn=process_image,
inputs=[input_image, blur_type, sigma],
outputs=output_image
)
return demo
# Launch the app
if __name__ == "__main__":
demo = create_blur_app()
demo.launch()