Akileshshankar's picture
Initial commit
ace6398
import gradio as gr
import gradio as gr
import numpy as np
import torch
import cv2
from PIL import Image
from transformers import (
AutoImageProcessor,
SegformerForSemanticSegmentation,
DPTImageProcessor,
DPTForDepthEstimation
)
# Load models
seg_processor = AutoImageProcessor.from_pretrained("nvidia/segformer-b0-finetuned-ade-512-512")
seg_model = SegformerForSemanticSegmentation.from_pretrained("nvidia/segformer-b0-finetuned-ade-512-512")
depth_processor = DPTImageProcessor.from_pretrained("Intel/dpt-hybrid-midas")
depth_model = DPTForDepthEstimation.from_pretrained("Intel/dpt-hybrid-midas")
# Segmentation + Gaussian Blur
def segmentation_blur(image):
inputs = seg_processor(images=image, return_tensors="pt")
with torch.no_grad():
outputs = seg_model(**inputs)
pred = outputs.logits.argmax(dim=1)[0].cpu().numpy()
mask = (pred == 12).astype(np.uint8) * 255 # Person class
mask_resized = cv2.resize(mask, image.size, interpolation=cv2.INTER_NEAREST)
image_np = np.array(image)
mask_3ch = np.stack([mask_resized] * 3, axis=-1) // 255
blurred = cv2.GaussianBlur(image_np, (0, 0), sigmaX=15)
combined = np.where(mask_3ch == 1, image_np, blurred)
return Image.fromarray(combined)
# Depth-based Variable Blur
def apply_depth_based_blur(image_np, depth_map_norm, max_blur=25):
h, w = depth_map_norm.shape
blurred_image = np.zeros_like(image_np)
image_np = image_np.astype(np.float32)
for i in range(1, max_blur+1, 2):
mask = ((depth_map_norm >= (i / max_blur)) & (depth_map_norm < ((i + 2) / max_blur))).astype(np.uint8)
if np.sum(mask) == 0:
continue
blurred = cv2.GaussianBlur(image_np, (i, i), 0)
mask_3ch = np.stack([mask]*3, axis=-1)
blurred_image = np.where(mask_3ch == 1, blurred, blurred_image)
sharpest_mask = (depth_map_norm < 0.1).astype(np.uint8)
sharpest_mask_3ch = np.stack([sharpest_mask]*3, axis=-1)
final_image = np.where(sharpest_mask_3ch == 1, image_np, blurred_image)
return final_image.astype(np.uint8)
def depth_blur(image):
inputs = depth_processor(images=image, return_tensors="pt")
with torch.no_grad():
outputs = depth_model(**inputs)
depth_map = outputs.predicted_depth[0].cpu().numpy()
depth_map = cv2.resize(depth_map, image.size)
norm_depth = (depth_map - depth_map.min()) / (depth_map.max() - depth_map.min())
image_np = np.array(image)
blurred_image = apply_depth_based_blur(image_np, norm_depth)
return Image.fromarray(blurred_image)
# Gradio interface
def process(image, mode):
if mode == "Segmentation Blur":
return segmentation_blur(image)
else:
return depth_blur(image)
demo = gr.Interface(
fn=process,
inputs=[
gr.Image(type="pil", label="Upload Image"),
gr.Radio(["Segmentation Blur", "Depth Blur"], value="Segmentation Blur", label="Blur Mode")
],
outputs=gr.Image(label="Output"),
title="Image Blur Effects (Segmentation & Depth)",
description="Upload an image and apply either Zoom-style background blur or DSLR-style depth blur."
)
demo.launch()