sjagird1 commited on
Commit
20980dc
·
verified ·
1 Parent(s): 395c275

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +171 -0
app.py ADDED
@@ -0,0 +1,171 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import torch
3
+ import numpy as np
4
+ from PIL import Image
5
+ import torchvision.transforms as transforms
6
+ from transformers import pipeline
7
+ from scipy.ndimage import gaussian_filter
8
+
9
+ def preprocess_image(image, target_size=(512, 512)):
10
+ """Preprocess the input image"""
11
+ if isinstance(image, str):
12
+ image = Image.open(image)
13
+ elif isinstance(image, np.ndarray):
14
+ image = Image.fromarray(image)
15
+
16
+ # Calculate aspect ratio preserving resize
17
+ aspect_ratio = image.size[0] / image.size[1]
18
+ if aspect_ratio > 1:
19
+ new_width = int(target_size[0] * aspect_ratio)
20
+ new_height = target_size[1]
21
+ else:
22
+ new_width = target_size[0]
23
+ new_height = int(target_size[1] / aspect_ratio)
24
+
25
+ preprocess = transforms.Compose([
26
+ transforms.Resize((new_height, new_width)),
27
+ transforms.CenterCrop(target_size),
28
+ ])
29
+
30
+ return preprocess(image)
31
+
32
+ def estimate_depth(image, pipe):
33
+ """Estimate depth using the Depth-Anything model"""
34
+ depth_output = pipe(image)
35
+ depth_map = depth_output["depth"]
36
+ depth_map = np.array(depth_map) / 16.67
37
+ return depth_map
38
+
39
+ def apply_depth_aware_blur(image, depth_map, max_sigma, min_sigma):
40
+ """Apply variable Gaussian blur based on depth values"""
41
+ image_array = np.array(image)
42
+ blurred = np.zeros_like(image_array, dtype=np.float32)
43
+
44
+ # Calculate sigma for each depth value
45
+ sigmas = np.interp(depth_map, [depth_map.min(), depth_map.max()], [min_sigma, max_sigma])
46
+ unique_sigmas = np.unique(sigmas)
47
+ blur_stack = {}
48
+
49
+ # Create blurred versions for each unique sigma
50
+ for sigma in unique_sigmas:
51
+ if sigma > 0:
52
+ blurred_image = np.zeros_like(image_array, dtype=np.float32)
53
+ for channel in range(3):
54
+ blurred_image[:, :, channel] = gaussian_filter(
55
+ image_array[:, :, channel].astype(np.float32),
56
+ sigma=sigma
57
+ )
58
+ blur_stack[sigma] = blurred_image
59
+
60
+ # Combine blurred versions
61
+ for sigma in unique_sigmas:
62
+ if sigma > 0:
63
+ mask = (sigmas == sigma)
64
+ mask_3d = np.stack([mask] * 3, axis=2)
65
+ blurred += mask_3d * blur_stack[sigma]
66
+ else:
67
+ mask = (sigmas == 0)
68
+ mask_3d = np.stack([mask] * 3, axis=2)
69
+ blurred += mask_3d * image_array
70
+
71
+ return Image.fromarray(blurred.astype(np.uint8))
72
+
73
+ def apply_gaussian_blur(image, sigma):
74
+ """Apply uniform Gaussian blur"""
75
+ image_array = np.array(image)
76
+ blurred = np.zeros_like(image_array)
77
+
78
+ for channel in range(3):
79
+ blurred[:, :, channel] = gaussian_filter(
80
+ image_array[:, :, channel],
81
+ sigma=sigma
82
+ )
83
+
84
+ return Image.fromarray(blurred.astype(np.uint8))
85
+
86
+ # Initialize depth estimation pipeline
87
+ pipe = pipeline(
88
+ task="depth-estimation",
89
+ model="depth-anything/Depth-Anything-V2-Small-hf",
90
+ torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32,
91
+ device=0 if torch.cuda.is_available() else -1
92
+ )
93
+
94
+ def process_image(image, blur_type, gaussian_sigma, lens_min_sigma, lens_max_sigma):
95
+ """Main processing function for Gradio interface"""
96
+ processed_image = preprocess_image(image)
97
+
98
+ if blur_type == "Gaussian Blur":
99
+ result = apply_gaussian_blur(processed_image, gaussian_sigma)
100
+ else: # Lens Blur
101
+ depth_map = estimate_depth(processed_image, pipe)
102
+ result = apply_depth_aware_blur(processed_image, depth_map, lens_max_sigma, lens_min_sigma)
103
+
104
+ return result
105
+
106
+ # Create Gradio interface
107
+ with gr.Blocks() as demo:
108
+ gr.Markdown("# Image Blur Effects Demo")
109
+ gr.Markdown("Apply Gaussian or Lens (Depth-aware) blur to your images")
110
+
111
+ with gr.Row():
112
+ with gr.Column():
113
+ input_image = gr.Image(label="Input Image", type="numpy")
114
+ blur_type = gr.Radio(
115
+ choices=["Gaussian Blur", "Lens Blur"],
116
+ label="Blur Effect",
117
+ value="Gaussian Blur"
118
+ )
119
+
120
+ with gr.Column(visible=True) as gaussian_controls:
121
+ gaussian_sigma = gr.Slider(
122
+ minimum=0, maximum=20, value=5,
123
+ label="Gaussian Blur Sigma",
124
+ step=0.5
125
+ )
126
+
127
+ with gr.Column() as lens_controls:
128
+ lens_min_sigma = gr.Slider(
129
+ minimum=0, maximum=10, value=0,
130
+ label="Minimum Blur (Near)",
131
+ step=0.5
132
+ )
133
+ lens_max_sigma = gr.Slider(
134
+ minimum=0, maximum=20, value=10,
135
+ label="Maximum Blur (Far)",
136
+ step=0.5
137
+ )
138
+
139
+ process_btn = gr.Button("Apply Blur")
140
+
141
+ with gr.Column():
142
+ output_image = gr.Image(label="Output Image")
143
+
144
+ # Handle visibility of controls based on blur type selection
145
+ def update_controls(blur_type):
146
+ return {
147
+ gaussian_controls: blur_type == "Gaussian Blur",
148
+ lens_controls: blur_type == "Lens Blur"
149
+ }
150
+
151
+ blur_type.change(
152
+ fn=update_controls,
153
+ inputs=[blur_type],
154
+ outputs=[gaussian_controls, lens_controls]
155
+ )
156
+
157
+ # Process image when button is clicked
158
+ process_btn.click(
159
+ fn=process_image,
160
+ inputs=[
161
+ input_image,
162
+ blur_type,
163
+ gaussian_sigma,
164
+ lens_min_sigma,
165
+ lens_max_sigma
166
+ ],
167
+ outputs=output_image
168
+ )
169
+
170
+ # Launch the demo
171
+ demo.launch()