pavank007 commited on
Commit
1840cfa
·
verified ·
1 Parent(s): bc24544

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +0 -243
app.py CHANGED
@@ -16,242 +16,6 @@ seg_model = AutoModelForSemanticSegmentation.from_pretrained("nvidia/segformer-b
16
  depth_processor = DPTImageProcessor.from_pretrained("Intel/dpt-large")
17
  depth_model = DPTForDepthEstimation.from_pretrained("Intel/dpt-large")
18
 
19
- def apply_gaussian_blur(image, mask, sigma=15):
20
- """Apply Gaussian blur to the background of an image based on a mask."""
21
- # Convert mask to binary (0 and 255)
22
- if mask.max() <= 1.0:
23
- binary_mask = (mask * 255).astype(np.uint8)
24
- else:
25
- binary_mask = mask.astype(np.uint8)
26
-
27
- # Create a blurred version of the entire image
28
- blurred = cv2.GaussianBlur(image, (0, 0), sigma)
29
-
30
- # Resize mask to match image dimensions if needed
31
- if binary_mask.shape[:2] != image.shape[:2]:
32
- binary_mask = cv2.resize(binary_mask, (image.shape[1], image.shape[0]))
33
-
34
- # Create a 3-channel mask if the input mask is single-channel
35
- if len(binary_mask.shape) == 2:
36
- mask_3ch = np.stack([binary_mask, binary_mask, binary_mask], axis=2)
37
- else:
38
- mask_3ch = binary_mask
39
-
40
- # Normalize mask to range [0, 1]
41
- mask_3ch = mask_3ch / 255.0
42
-
43
- # Combine original image (foreground) with blurred image (background) using the mask
44
- result = image * mask_3ch + blurred * (1 - mask_3ch)
45
-
46
- return result.astype(np.uint8)
47
-
48
- def apply_depth_blur(image, depth_map, max_sigma=25):
49
- """Apply variable Gaussian blur based on depth map."""
50
- # Normalize depth map to range [0, 1]
51
- if depth_map.max() > 1.0:
52
- depth_norm = depth_map / depth_map.max()
53
- else:
54
- depth_norm = depth_map
55
-
56
- # Resize depth map to match image dimensions if needed
57
- if depth_norm.shape[:2] != image.shape[:2]:
58
- depth_norm = cv2.resize(depth_norm, (image.shape[1], image.shape[0]))
59
-
60
- # Create output image
61
- result = np.zeros_like(image)
62
-
63
- # Apply different blur levels based on depth
64
- for sigma in range(1, int(max_sigma) + 1, 2):
65
- # Create a mask for pixels at this depth level
66
- lower_bound = (sigma - 1) / max_sigma
67
- upper_bound = (sigma + 1) / max_sigma
68
- mask = np.logical_and(depth_norm >= lower_bound, depth_norm <= upper_bound).astype(np.float32)
69
-
70
- # Skip if no pixels at this depth
71
- if not np.any(mask):
72
- continue
73
-
74
- # Blur the image with current sigma
75
- blurred = cv2.GaussianBlur(image, (0, 0), sigma)
76
-
77
- # Create a 3-channel mask if the input mask is single-channel
78
- if len(mask.shape) == 2:
79
- mask_3ch = np.stack([mask, mask, mask], axis=2)
80
- else:
81
- mask_3ch = mask
82
-
83
- # Add the blurred pixels at this depth to the result
84
- result += (blurred * mask_3ch).astype(np.uint8)
85
-
86
- # Fill in any missing pixels (where sum of all masks < 1)
87
- total_mask = np.zeros_like(depth_norm)
88
- for sigma in range(1, int(max_sigma) + 1, 2):
89
- lower_bound = (sigma - 1) / max_sigma
90
- upper_bound = (sigma + 1) / max_sigma
91
- mask = np.logical_and(depth_norm >= lower_bound, depth_norm <= upper_bound).astype(np.float32)
92
- total_mask += mask
93
-
94
- missing_mask = (total_mask < 0.5).astype(np.float32)
95
- if np.any(missing_mask):
96
- missing_mask_3ch = np.stack([missing_mask, missing_mask, missing_mask], axis=2)
97
- result += (image * missing_mask_3ch).astype(np.uint8)
98
-
99
- return result
100
-
101
- def get_segmentation_mask(image_pil):
102
- """Get segmentation mask for person/foreground from an image."""
103
- # Resize the image to the size expected by the segmentation model
104
- width, height = image_pil.size
105
- image_pil_resized = image_pil.resize((512, 512))
106
-
107
- # Process the image with the segmentation model
108
- inputs = seg_processor(images=image_pil_resized, return_tensors="pt")
109
- with torch.no_grad():
110
- outputs = seg_model(**inputs)
111
-
112
- # Get the predicted segmentation mask
113
- logits = outputs.logits
114
- upsampled_logits = torch.nn.functional.interpolate(
115
- logits,
116
- size=(512, 512),
117
- mode="bilinear",
118
- align_corners=False,
119
- )
120
-
121
- # Get the predicted segmentation mask
122
- predicted_mask = upsampled_logits.argmax(dim=1)[0]
123
-
124
- # Convert the mask to a numpy array
125
- mask_np = predicted_mask.cpu().numpy()
126
-
127
- # Create a foreground mask - considering classes that are likely to be foreground
128
- # The ADE20K dataset has 150 classes, so we need to choose which ones to consider as foreground
129
- # Common foreground classes: person (12), animal classes, and objects like furniture
130
- # This is a simplified approach - you may need to adjust based on your needs
131
- foreground_classes = [12, 13, 14, 15, 16, 17, 18, 19, 20] # Person and some objects
132
- foreground_mask = np.zeros_like(mask_np)
133
- for cls in foreground_classes:
134
- foreground_mask[mask_np == cls] = 1
135
-
136
- # Resize back to original image size
137
- foreground_mask = cv2.resize(foreground_mask, (width, height))
138
-
139
- return foreground_mask
140
-
141
- def get_depth_map(image_pil):
142
- """Get depth map from an image."""
143
- # Process the image with the depth estimation model
144
- inputs = depth_processor(images=image_pil, return_tensors="pt")
145
- with torch.no_grad():
146
- outputs = depth_model(**inputs)
147
- predicted_depth = outputs.predicted_depth
148
-
149
- # Interpolate to original size
150
- prediction = torch.nn.functional.interpolate(
151
- predicted_depth.unsqueeze(1),
152
- size=image_pil.size[::-1],
153
- mode="bicubic",
154
- align_corners=False,
155
- )
156
-
157
- # Convert to numpy array
158
- depth_map = prediction.squeeze().cpu().numpy()
159
-
160
- # Normalize depth map
161
- depth_map = (depth_map - depth_map.min()) / (depth_map.max() - depth_map.min())
162
-
163
- return depth_map
164
-
165
- def process_image(input_image, blur_sigma=15, depth_blur_sigma=25):
166
- """Main function to process the input image."""
167
- try:
168
- # Convert to PIL Image if needed
169
- if isinstance(input_image, np.ndarray):
170
- pil_image = Image.fromarray(input_image)
171
- else:
172
- pil_image = input_image
173
- input_image = np.array(pil_image)
174
-
175
- # Get segmentation mask
176
- seg_mask = get_segmentation_mask(pil_image)
177
-
178
- # Get depth map
179
- depth_map = get_depth_map(pil_image)
180
-
181
- # Apply gaussian blur to background
182
- gaussian_result = apply_gaussian_blur(input_image, seg_mask, sigma=blur_sigma)
183
-
184
- # Apply depth-based blur
185
- depth_result = apply_depth_blur(input_image, depth_map, max_sigma=depth_blur_sigma)
186
-
187
- # Display depth map as an image
188
- depth_visualization = (depth_map * 255).astype(np.uint8)
189
- depth_visualization = cv2.applyColorMap(depth_visualization, cv2.COLORMAP_INFERNO)
190
-
191
- # Display segmentation mask
192
- seg_visualization = (seg_mask * 255).astype(np.uint8)
193
-
194
- return [
195
- input_image,
196
- seg_visualization,
197
- gaussian_result,
198
- depth_visualization,
199
- depth_result
200
- ]
201
- except Exception as e:
202
- print(f"Error processing image: {e}")
203
- return [None, None, None, None, None]
204
-
205
- # Create Gradio interface
206
- with gr.Blocks(title="Image Blur Effects with Segmentation and Depth Estimation") as demo:
207
- gr.Markdown("# Image Blur Effects App")
208
- gr.Markdown("This app demonstrates two types of blur effects: background blur using segmentation and depth-based lens blur.")
209
-
210
- with gr.Row():
211
- with gr.Column():
212
- input_image = gr.Image(label="Upload an image", type="pil")
213
- blur_sigma = gr.Slider(minimum=1, maximum=50, value=15, step=1, label="Background Blur Intensity")
214
- depth_blur_sigma = gr.Slider(minimum=1, maximum=50, value=25, step=1, label="Depth Blur Max Intensity")
215
- process_btn = gr.Button("Process Image")
216
-
217
- with gr.Column():
218
- with gr.Tab("Original Image"):
219
- output_original = gr.Image(label="Original Image")
220
- with gr.Tab("Segmentation Mask"):
221
- output_segmentation = gr.Image(label="Segmentation Mask")
222
- with gr.Tab("Background Blur"):
223
- output_gaussian = gr.Image(label="Background Blur Result")
224
- with gr.Tab("Depth Map"):
225
- output_depth = gr.Image(label="Depth Map")
226
- with gr.Tab("Depth-based Lens Blur"):
227
- output_depth_blur = gr.Image(label="Depth-based Lens Blur Result")
228
-
229
- process_btn.click(
230
- fn=process_image,
231
- inputs=[input_image, blur_sigma, depth_blur_sigma],
232
- outputs=[output_original, output_segmentation, output_gaussian, output_depth, output_depth_blur]
233
- )
234
-
235
- gr.Markdown("""
236
- ## How it works
237
- import gradio as gr
238
- import torch
239
- import numpy as np
240
- import cv2
241
- from PIL import Image
242
- from transformers import AutoImageProcessor, AutoModelForSemanticSegmentation
243
- from transformers import DPTImageProcessor, DPTForDepthEstimation
244
- import warnings
245
- warnings.filterwarnings("ignore")
246
-
247
- # Load segmentation model - using SegFormer which is compatible with AutoModelForSemanticSegmentation
248
- seg_processor = AutoImageProcessor.from_pretrained("nvidia/segformer-b0-finetuned-ade-512-512")
249
- seg_model = AutoModelForSemanticSegmentation.from_pretrained("nvidia/segformer-b0-finetuned-ade-512-512")
250
-
251
- # Load depth estimation model
252
- depth_processor = DPTImageProcessor.from_pretrained("Intel/dpt-large")
253
- depth_model = DPTForDepthEstimation.from_pretrained("Intel/dpt-large")
254
-
255
  def safe_resize(image, target_size, interpolation=cv2.INTER_LINEAR):
256
  """Safely resize an image with validation checks."""
257
  if image is None:
@@ -535,11 +299,4 @@ with gr.Blocks(title="Image Blur Effects with Segmentation and Depth Estimation"
535
  Try uploading a photo of a person against a background to see the effects!
536
  """)
537
 
538
- demo.launch()
539
- 1. **Background Blur**: Uses a segmentation model to identify foreground objects and blurs only the background
540
- 2. **Depth-based Lens Blur**: Uses a depth estimation model to apply variable blur based on estimated distance
541
-
542
- Try uploading a photo of a person or object against a background to see the effects!
543
- """)
544
-
545
  demo.launch()
 
16
  depth_processor = DPTImageProcessor.from_pretrained("Intel/dpt-large")
17
  depth_model = DPTForDepthEstimation.from_pretrained("Intel/dpt-large")
18
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  def safe_resize(image, target_size, interpolation=cv2.INTER_LINEAR):
20
  """Safely resize an image with validation checks."""
21
  if image is None:
 
299
  Try uploading a photo of a person against a background to see the effects!
300
  """)
301
 
 
 
 
 
 
 
 
302
  demo.launch()