|
import cv2 |
|
import numpy as np |
|
import gradio as gr |
|
from PIL import Image |
|
|
|
|
|
def segment_foreground(img): |
|
|
|
np_img = np.array(img.convert("RGB")) |
|
h, w, _ = np_img.shape |
|
|
|
mask = np.zeros((h, w), dtype=np.uint8) |
|
center = (w // 2, h // 2) |
|
radius = min(center) - 10 |
|
cv2.circle(mask, center, radius, (255), thickness=-1) |
|
return mask |
|
|
|
|
|
def gaussian_blur_background(img, sigma=15): |
|
mask = segment_foreground(img) |
|
np_img = np.array(img.convert("RGB")) |
|
|
|
blurred = cv2.GaussianBlur(np_img, (0, 0), sigma) |
|
|
|
mask_3d = np.stack([mask] * 3, axis=-1) / 255.0 |
|
|
|
combined = np_img * mask_3d + blurred * (1 - mask_3d) |
|
return Image.fromarray(combined.astype(np.uint8)) |
|
|
|
|
|
def estimate_depth(img): |
|
np_img = np.array(img.convert("RGB")) |
|
h, w, _ = np_img.shape |
|
|
|
depth = np.tile(np.linspace(0, 1, h)[:, None], (1, w)) |
|
return depth |
|
|
|
|
|
def depth_based_blur(img, max_sigma=20): |
|
depth = estimate_depth(img) |
|
np_img = np.array(img.convert("RGB")) |
|
output = np.zeros_like(np_img) |
|
|
|
|
|
depth_norm = (depth - depth.min()) / (depth.max() - depth.min() + 1e-8) |
|
|
|
|
|
for i in range(np_img.shape[0]): |
|
sigma = max_sigma * depth_norm[i, 0] |
|
row = cv2.GaussianBlur(np_img[i:i+1, :, :], (0, 0), sigma) |
|
output[i, :, :] = row |
|
return Image.fromarray(output.astype(np.uint8)) |
|
|
|
|
|
def process_image(img, effect): |
|
if effect == "Gaussian Blur Background": |
|
return gaussian_blur_background(img) |
|
elif effect == "Depth-based Lens Blur": |
|
return depth_based_blur(img) |
|
else: |
|
return img |
|
|
|
|
|
iface = gr.Interface( |
|
fn=process_image, |
|
inputs=[ |
|
gr.inputs.Image(type="pil", label="Input Image"), |
|
gr.inputs.Radio(["Gaussian Blur Background", "Depth-based Lens Blur"], label="Select Effect") |
|
], |
|
outputs=gr.outputs.Image(type="pil", label="Output Image"), |
|
title="Blur Effects Demo", |
|
description="Upload an image and choose an effect to apply either a Gaussian Blur to the background or a Depth-based Lens Blur." |
|
) |
|
|
|
if __name__ == "__main__": |
|
iface.launch() |
|
|