Spaces:
Sleeping
Sleeping
File size: 3,996 Bytes
da08054 949b21d da08054 949b21d da08054 9a38f9d da08054 a2d6b95 da08054 3d0e8ab |
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 |
import gradio as gr
from PIL import Image, ImageFilter
import numpy as np
import torch
import cv2
from transformers import AutoImageProcessor, AutoModelForDepthEstimation
# Load depth estimation model
image_processor = AutoImageProcessor.from_pretrained("depth-anything/Depth-Anything-V2-Small-hf")
model = AutoModelForDepthEstimation.from_pretrained("depth-anything/Depth-Anything-V2-Small-hf")
def apply_gaussian_blur(image, mask):
"""Applies Gaussian blur to the background based on a user-drawn mask."""
if mask is None:
return image # If no mask is provided, return the original image
# Ensure mask is grayscale and resized to match image dimensions
mask_pil = Image.fromarray(mask).convert("L").resize(image.size)
mask_array = np.array(mask_pil)
# Create a blurred background
blurred_background = image.filter(ImageFilter.GaussianBlur(radius=15))
# Convert images to NumPy arrays
img_array = np.array(image)
blurred_array = np.array(blurred_background)
# Create a boolean mask (foreground = True, background = False)
foreground_mask = mask_array > 0
foreground_mask_3d = np.stack([foreground_mask] * 3, axis=-1)
# Blend the original image with the blurred background
final_image_array = np.where(foreground_mask_3d, img_array, blurred_array)
final_image = Image.fromarray(final_image_array.astype(np.uint8))
return final_image
def apply_lens_blur(image):
"""Applies depth-based lens blur using a pre-trained model."""
# Resize image to 512x512 for processing
resized_image = image.resize((512, 512))
image_np = np.array(resized_image)
# Prepare image for the model
inputs = image_processor(images=resized_image, return_tensors="pt")
with torch.no_grad():
outputs = model(**inputs)
predicted_depth = outputs.predicted_depth
# Interpolate depth map to match the image size
prediction = torch.nn.functional.interpolate(
predicted_depth.unsqueeze(1),
size=resized_image.size[::-1],
mode="bicubic",
align_corners=False,
).squeeze()
# Convert prediction to a NumPy array
depth_map = prediction.cpu().numpy()
# Normalize the depth map
depth_norm = (depth_map - np.min(depth_map)) / (np.max(depth_map) - np.min(depth_map))
num_blur_levels = 5
blurred_layers = []
for i in range(num_blur_levels):
sigma = i * 0.5
if sigma == 0:
blurred = image_np
else:
blurred = cv2.GaussianBlur(image_np, (15, 15), sigmaX=sigma, sigmaY=sigma, borderType=cv2.BORDER_REPLICATE)
blurred_layers.append(blurred)
depth_indices = ((1 - depth_norm) * (num_blur_levels - 1)).astype(np.uint8)
final_blurred_image = np.zeros_like(image_np)
for y in range(image_np.shape[0]):
for x in range(image_np.shape[1]):
depth_index = depth_indices[y, x]
final_blurred_image[y, x] = blurred_layers[depth_index][y, x]
# Convert the final blurred image back to a PIL Image
final_blurred_pil_image = Image.fromarray(final_blurred_image)
return final_blurred_pil_image
def process_image(image, mask, blur_type):
"""Processes the image based on the selected blur type."""
if blur_type == "Gaussian Blur":
return apply_gaussian_blur(image, mask)
elif blur_type == "Lens Blur":
return apply_lens_blur(image)
else:
return image
interface = gr.Interface(
fn=process_image,
inputs=[
gr.Image(type="pil", label="Upload an Image"),
gr.Sketchpad(height=256, width=256, label="Draw Mask (Only for Gaussian Blur)"),
gr.Radio(["Gaussian Blur", "Lens Blur"], label="Choose Blur Effect")
],
outputs=gr.Image(type="pil"),
title="Gaussian & Lens Blur Effects",
description="Upload an image and select either Gaussian blur (with mask) or depth-based lens blur."
)
if __name__ == "__main__":
interface.launch(share=True)
|