Jeevan-HM/blur_background
0
1import cv22import numpy as np3import gradio as gr4from PIL import Image5from scipy.ndimage import gaussian_filter6from transformers import (7 AutoImageProcessor,8 AutoModelForDepthEstimation,9)10import torch11 12 13def resize_to_512(img: Image.Image) -> Image.Image:14 return img.resize((512, 512)) if img.size != (512, 512) else img15 16 17def gaussian_blur(img: Image.Image, kernel_size: int):18 img = resize_to_512(img)19 img_cv = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR)20 blurred = cv2.GaussianBlur(img_cv, (kernel_size | 1, kernel_size | 1), 0)21 return cv2.cvtColor(blurred, cv2.COLOR_BGR2RGB)22 23 24depth_model_id = "depth-anything/Depth-Anything-V2-Small-hf"25processor = AutoImageProcessor.from_pretrained(depth_model_id)26depth_model = AutoModelForDepthEstimation.from_pretrained(depth_model_id)27 28 29def lens_blur(img: Image.Image, max_blur_radius: int):30 img = resize_to_512(img)31 original = np.array(img).astype(np.float32)32 33 inputs = processor(images=img, return_tensors="pt")34 with torch.no_grad():35 outputs = depth_model(**inputs)36 predicted_depth = outputs.predicted_depth37 38 depth = (39 torch.nn.functional.interpolate(40 predicted_depth.unsqueeze(1),41 size=(512, 512),42 mode="bicubic",43 align_corners=False,44 )45 .squeeze()46 .cpu()47 .numpy()48 )49 50 depth_norm = (depth - depth.min()) / (depth.max() - depth.min())51 depth_inverted = 1.0 - depth_norm52 53 num_levels = 654 max_sigma = max_blur_radius / 2.055 blur_levels = np.linspace(0, max_sigma, num_levels)56 blurred_images = [gaussian_filter(original, sigma=(s, s, 0)) for s in blur_levels]57 58 blurred_final = np.zeros_like(original, dtype=np.float32)59 depth_scaled = depth_inverted * (num_levels - 1)60 depth_int = np.floor(depth_scaled).astype(int)61 depth_frac = depth_scaled - depth_int62 63 for i in range(num_levels - 1):64 mask = depth_int == i65 alpha = depth_frac[mask]66 for c in range(3):67 blended = (68 blurred_images[i][..., c][mask] * (1 - alpha)69 + blurred_images[i + 1][..., c][mask] * alpha70 )71 blurred_final[..., c][mask] = blended72 73 return np.clip(blurred_final, 0, 255).astype(np.uint8)74 75 76def synthetic_lens_blur(img: Image.Image, max_blur_radius: int):77 img = resize_to_512(img)78 original = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR)79 original_rgb = cv2.cvtColor(original, cv2.COLOR_BGR2RGB)80 81 depth_norm = np.zeros((original.shape[0], original.shape[1]), dtype=np.float32)82 cv2.circle(depth_norm, (original.shape[1] // 2, original.shape[0] // 2), 100, 1, -1)83 depth_norm = cv2.GaussianBlur(depth_norm, (21, 21), 0)84 85 blurred_image = np.zeros_like(original_rgb)86 87 for i in range(original.shape[0]):88 for j in range(original.shape[1]):89 blur_radius = int(depth_norm[i, j] * max_blur_radius)90 if blur_radius % 2 == 0:91 blur_radius += 192 93 x_min = max(j - blur_radius, 0)94 x_max = min(j + blur_radius, original.shape[1])95 y_min = max(i - blur_radius, 0)96 y_max = min(i + blur_radius, original.shape[0])97 98 roi = original_rgb[y_min:y_max, x_min:x_max]99 100 if blur_radius > 1:101 blurred_roi = cv2.GaussianBlur(roi, (blur_radius, blur_radius), 0)102 try:103 blurred_image[i, j] = blurred_roi[104 blur_radius // 2, blur_radius // 2105 ]106 except:107 blurred_image[i, j] = original_rgb[i, j]108 else:109 blurred_image[i, j] = original_rgb[i, j]110 111 return blurred_image112 113 114def apply_all_blurs(img, g_kernel, lens_radius, synthetic_radius):115 g = gaussian_blur(img, g_kernel)116 l = lens_blur(img, lens_radius)117 s = synthetic_lens_blur(img, synthetic_radius)118 return g, l, s119 120 121def update_gaussian(img, kernel_size):122 return gaussian_blur(img, kernel_size)123 124 125def update_lens(img, radius):126 return lens_blur(img, radius)127 128 129def update_synthetic(img, radius):130 return synthetic_lens_blur(img, radius)131 132 133with gr.Blocks() as demo:134 gr.Markdown(135 "## ๐ Blur Effects Comparison: Gaussian, Depth-Based, Synthetic (Depth Based Blur works with bottles)"136 )137 138 with gr.Row():139 image_input = gr.Image(type="pil", label="Upload Image")140 141 with gr.Row():142 g_slider = gr.Slider(1, 49, step=2, value=11, label="Gaussian Kernel Size")143 lens_slider = gr.Slider(144 1,145 50,146 step=1,147 value=15,148 label="Depth-Based Blur Intensity (Works with bottles)",149 )150 synth_slider = gr.Slider(1, 50, step=1, value=25, label="Synthetic Blur Radius")151 152 with gr.Row():153 g_output = gr.Image(label="Gaussian Blurred Image")154 l_output = gr.Image(label="Depth-Based Lens Blurred Image")155 s_output = gr.Image(label="Synthetic Depth Lens Blurred Image")156 157 # Initial image upload updates all three158 image_input.change(159 fn=apply_all_blurs,160 inputs=[image_input, g_slider, lens_slider, synth_slider],161 outputs=[g_output, l_output, s_output],162 )163 164 # Individual updates for each slider165 g_slider.change(166 fn=update_gaussian, inputs=[image_input, g_slider], outputs=g_output167 )168 lens_slider.change(169 fn=update_lens, inputs=[image_input, lens_slider], outputs=l_output170 )171 synth_slider.change(172 fn=update_synthetic, inputs=[image_input, synth_slider], outputs=s_output173 )174 175demo.launch()176 