Jeevan-HM commited on
Commit
3fb37bd
Β·
1 Parent(s): ceabe6b

Modify lens blur

Browse files
Files changed (3) hide show
  1. .DS_Store +0 -0
  2. app.py +96 -42
  3. requirements.txt +1 -0
.DS_Store CHANGED
Binary files a/.DS_Store and b/.DS_Store differ
 
app.py CHANGED
@@ -2,12 +2,16 @@ import cv2
2
  import numpy as np
3
  import gradio as gr
4
  from PIL import Image
 
 
 
 
 
 
5
 
6
 
7
  def resize_to_512(img: Image.Image) -> Image.Image:
8
- if img.size != (512, 512):
9
- return img.resize((512, 512))
10
- return img
11
 
12
 
13
  def gaussian_blur(img: Image.Image, kernel_size: int):
@@ -17,65 +21,115 @@ def gaussian_blur(img: Image.Image, kernel_size: int):
17
  return cv2.cvtColor(blurred, cv2.COLOR_BGR2RGB)
18
 
19
 
 
 
 
 
 
 
20
  def lens_blur(img: Image.Image, max_blur_radius: int):
21
  img = resize_to_512(img)
22
- original = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR)
23
- original_rgb = cv2.cvtColor(original, cv2.COLOR_BGR2RGB)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
 
25
- # Create synthetic depth map
26
- depth_norm = np.zeros((original.shape[0], original.shape[1]), dtype=np.float32)
27
- cv2.circle(depth_norm, (original.shape[1] // 2, original.shape[0] // 2), 100, 1, -1)
28
- depth_norm = cv2.GaussianBlur(depth_norm, (21, 21), 0)
29
 
30
- blurred_image = np.zeros_like(original_rgb)
31
 
32
- for i in range(original.shape[0]):
33
- for j in range(original.shape[1]):
34
- blur_radius = int(depth_norm[i, j] * max_blur_radius)
35
- if blur_radius % 2 == 0:
36
- blur_radius += 1
37
 
38
- x_min = max(j - blur_radius, 0)
39
- x_max = min(j + blur_radius, original.shape[1])
40
- y_min = max(i - blur_radius, 0)
41
- y_max = min(i + blur_radius, original.shape[0])
42
 
43
- roi = original_rgb[y_min:y_max, x_min:x_max]
 
44
 
45
- if blur_radius > 1:
46
- blurred_roi = cv2.GaussianBlur(roi, (blur_radius, blur_radius), 0)
47
- try:
48
- blurred_image[i, j] = blurred_roi[
49
- blur_radius // 2, blur_radius // 2
50
- ]
51
- except:
52
- blurred_image[i, j] = original_rgb[i, j]
53
- else:
54
- blurred_image[i, j] = original_rgb[i, j]
55
 
56
- return blurred_image
 
 
 
57
 
58
 
59
  with gr.Blocks() as demo:
60
- gr.Markdown("## Gaussian and Lens Blur App")
 
61
  with gr.Row():
62
- image_input = gr.Image(type="pil", label="Upload an Image")
 
63
  with gr.Row():
64
- kernel_slider = gr.Slider(1, 49, value=11, step=2, label="Gaussian Kernel Size")
65
- max_blur_slider = gr.Slider(
66
- 1, 50, value=15, step=1, label="Max Lens Blur Radius"
67
  )
 
68
  with gr.Row():
69
  gaussian_output = gr.Image(label="Gaussian Blurred Image")
70
  lens_output = gr.Image(label="Depth-Based Lens Blurred Image")
71
- with gr.Row():
72
- blur_btn = gr.Button("Apply Blur")
73
 
74
- blur_btn.click(
75
- fn=gaussian_blur, inputs=[image_input, kernel_slider], outputs=gaussian_output
 
 
 
76
  )
77
- blur_btn.click(
78
- fn=lens_blur, inputs=[image_input, max_blur_slider], outputs=lens_output
 
 
 
 
 
 
 
 
 
 
 
79
  )
80
 
81
  demo.launch()
 
2
  import numpy as np
3
  import gradio as gr
4
  from PIL import Image
5
+ from scipy.ndimage import gaussian_filter
6
+ from transformers import (
7
+ AutoImageProcessor,
8
+ AutoModelForDepthEstimation,
9
+ )
10
+ import torch
11
 
12
 
13
  def resize_to_512(img: Image.Image) -> Image.Image:
14
+ return img.resize((512, 512)) if img.size != (512, 512) else img
 
 
15
 
16
 
17
  def gaussian_blur(img: Image.Image, kernel_size: int):
 
21
  return cv2.cvtColor(blurred, cv2.COLOR_BGR2RGB)
22
 
23
 
24
+ # Load model once globally
25
+ depth_model_id = "depth-anything/Depth-Anything-V2-Small-hf"
26
+ processor = AutoImageProcessor.from_pretrained(depth_model_id)
27
+ depth_model = AutoModelForDepthEstimation.from_pretrained(depth_model_id)
28
+
29
+
30
  def lens_blur(img: Image.Image, max_blur_radius: int):
31
  img = resize_to_512(img)
32
+ original = np.array(img).astype(np.float32)
33
+
34
+ # Get depth map
35
+ inputs = processor(images=img, return_tensors="pt")
36
+ with torch.no_grad():
37
+ outputs = depth_model(**inputs)
38
+ predicted_depth = outputs.predicted_depth
39
+
40
+ depth = (
41
+ torch.nn.functional.interpolate(
42
+ predicted_depth.unsqueeze(1),
43
+ size=(512, 512),
44
+ mode="bicubic",
45
+ align_corners=False,
46
+ )
47
+ .squeeze()
48
+ .cpu()
49
+ .numpy()
50
+ )
51
+
52
+ # Normalize and invert depth
53
+ depth_norm = (depth - depth.min()) / (depth.max() - depth.min())
54
+ depth_inverted = 1.0 - depth_norm
55
+
56
+ # Dynamically scale blur strength using the slider
57
+ num_levels = 6 # More levels for smoother transitions
58
+ max_sigma = (
59
+ max_blur_radius / 2.0
60
+ ) # Scale down to reasonable range (e.g. 0–25 β†’ 0–12.5 sigma)
61
+ blur_levels = np.linspace(0, max_sigma, num_levels)
62
+ blurred_images = [gaussian_filter(original, sigma=(s, s, 0)) for s in blur_levels]
63
+
64
+ # Blend based on depth
65
+ blurred_final = np.zeros_like(original, dtype=np.float32)
66
+ depth_scaled = depth_inverted * (num_levels - 1)
67
+ depth_int = np.floor(depth_scaled).astype(int)
68
+ depth_frac = depth_scaled - depth_int
69
+
70
+ for i in range(num_levels - 1):
71
+ mask = depth_int == i
72
+ alpha = depth_frac[mask]
73
+ for c in range(3):
74
+ blended = (
75
+ blurred_images[i][..., c][mask] * (1 - alpha)
76
+ + blurred_images[i + 1][..., c][mask] * alpha
77
+ )
78
+ blurred_final[..., c][mask] = blended
79
 
80
+ return np.clip(blurred_final, 0, 255).astype(np.uint8)
 
 
 
81
 
 
82
 
83
+ # Separate update functions
84
+ def update_gaussian(img, kernel_size):
85
+ return gaussian_blur(img, kernel_size)
 
 
86
 
 
 
 
 
87
 
88
+ def update_lens(img, max_blur_radius):
89
+ return lens_blur(img, max_blur_radius)
90
 
 
 
 
 
 
 
 
 
 
 
91
 
92
+ def apply_blurs(img, kernel_size, max_blur_radius):
93
+ g_blurred = gaussian_blur(img, kernel_size)
94
+ l_blurred = lens_blur(img, max_blur_radius)
95
+ return g_blurred, l_blurred
96
 
97
 
98
  with gr.Blocks() as demo:
99
+ gr.Markdown("## πŸŒ€ Apply Gaussian and Depth-Based Lens Blur")
100
+
101
  with gr.Row():
102
+ image_input = gr.Image(type="pil", label="Upload Image")
103
+
104
  with gr.Row():
105
+ kernel_slider = gr.Slider(1, 49, step=2, value=11, label="Gaussian Kernel Size")
106
+ lens_slider = gr.Slider(
107
+ 1, 50, step=1, value=15, label="Max Lens Blur Intensity"
108
  )
109
+
110
  with gr.Row():
111
  gaussian_output = gr.Image(label="Gaussian Blurred Image")
112
  lens_output = gr.Image(label="Depth-Based Lens Blurred Image")
 
 
113
 
114
+ # Trigger both when image changes
115
+ image_input.change(
116
+ fn=apply_blurs,
117
+ inputs=[image_input, kernel_slider, lens_slider],
118
+ outputs=[gaussian_output, lens_output],
119
  )
120
+
121
+ # Trigger only gaussian blur
122
+ kernel_slider.change(
123
+ fn=update_gaussian,
124
+ inputs=[image_input, kernel_slider],
125
+ outputs=gaussian_output,
126
+ )
127
+
128
+ # Trigger only lens blur
129
+ lens_slider.change(
130
+ fn=update_lens,
131
+ inputs=[image_input, lens_slider],
132
+ outputs=lens_output,
133
  )
134
 
135
  demo.launch()
requirements.txt CHANGED
@@ -2,3 +2,4 @@ gradio
2
  opencv-python
3
  numpy
4
  pillow
 
 
2
  opencv-python
3
  numpy
4
  pillow
5
+ transformers