nsathya5 commited on
Commit
a9e0802
·
verified ·
1 Parent(s): b6e18e3

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +63 -40
app.py CHANGED
@@ -41,7 +41,11 @@ def segment_image(image):
41
 
42
  # Original dimensions
43
  original_size = image.size
44
- model_image = image.resize((512, 512))
 
 
 
 
45
 
46
  # Process image with model
47
  inputs = seg_processor(images=model_image, return_tensors="pt")
@@ -64,29 +68,30 @@ def segment_image(image):
64
  if cls_mask.sum() > binary_mask.sum():
65
  binary_mask = cls_mask
66
 
67
- # Improve mask with morphological operations
68
- mask_small = Image.fromarray((binary_mask * 255).astype(np.uint8))
69
- mask_cv = np.array(mask_small)
 
70
  kernel = np.ones((5, 5), np.uint8)
71
  mask_cv = cv2.morphologyEx(mask_cv, cv2.MORPH_CLOSE, kernel)
72
  mask_cv = cv2.morphologyEx(mask_cv, cv2.MORPH_OPEN, kernel)
73
 
74
- # Apply Gaussian blur to smooth the edges
75
- mask_cv = cv2.GaussianBlur(mask_cv, (9, 9), 0)
76
  _, mask_cv = cv2.threshold(mask_cv, 128, 255, cv2.THRESH_BINARY)
77
 
78
- # Resize back to original image size
79
- mask_small = Image.fromarray(mask_cv)
80
- mask_image = mask_small.resize(original_size, Image.BICUBIC)
81
 
82
- # Create binary mask
83
- mask_array = np.array(mask_image) > 0
84
 
85
- # Create colored mask for visualization
86
- mask_rgb = np.zeros((mask_array.shape[0], mask_array.shape[1], 3), dtype=np.uint8)
87
- mask_rgb[:,:,0] = mask_array * 255 # Red channel for visualization
88
 
89
- return mask_array, mask_rgb
90
 
91
  # Function to apply Gaussian blur to background
92
  def apply_background_blur(image, mask, sigma=15):
@@ -106,9 +111,8 @@ def apply_background_blur(image, mask, sigma=15):
106
  binary_mask = mask > 0
107
 
108
  # Apply Gaussian blur to the entire image
109
- blurred = np.zeros_like(image_array)
110
- for c in range(3):
111
- blurred[:, :, c] = gaussian_filter(image_array[:, :, c], sigma=sigma)
112
 
113
  # Combine original foreground with blurred background
114
  result = np.copy(blurred)
@@ -128,7 +132,9 @@ def apply_depth_based_blur(image, mask=None, max_sigma=15):
128
 
129
  # Original dimensions
130
  original_size = image.size
131
- model_size = (512, 512)
 
 
132
  model_image = image.resize(model_size, Image.LANCZOS)
133
 
134
  # Process image for depth estimation
@@ -143,43 +149,56 @@ def apply_depth_based_blur(image, mask=None, max_sigma=15):
143
  depth = predicted_depth.squeeze().cpu().numpy()
144
  depth_map = (depth - depth.min()) / (depth.max() - depth.min())
145
 
146
- # Resize depth map to match image size
147
- depth_pil = Image.fromarray(depth_map)
148
- depth_map_resized = np.array(depth_pil.resize(model_size, Image.LANCZOS))
149
 
150
  # Invert depth map (closer objects should be less blurred)
151
- inverted_depth_map = 1.0 - depth_map_resized
152
 
153
  # If mask is provided, ensure foreground is not blurred at all
154
  if mask is not None:
155
  # Resize mask to match model size
156
- mask_pil = Image.fromarray((mask * 255).astype(np.uint8))
157
  mask_resized = np.array(mask_pil.resize(model_size, Image.LANCZOS)) > 128
158
  # Set depth map to 0 (no blur) for foreground pixels
159
  inverted_depth_map = inverted_depth_map * (1 - mask_resized)
160
 
161
- # Apply variable blur based on depth
162
- original_array = np.array(model_image)
163
- result_array = np.zeros_like(original_array)
164
 
165
- # Apply blur with different intensities based on depth
166
- for channel in range(3):
167
- # Maximum blur
168
- max_blurred = gaussian_filter(original_array[:, :, channel], sigma=max_sigma)
169
- # Apply blur based on depth value
170
- result_array[:, :, channel] = (1 - inverted_depth_map) * original_array[:, :, channel] + \
171
- inverted_depth_map * max_blurred
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
172
 
173
- # Resize back to original image size
174
- depth_blur = Image.fromarray(result_array.astype(np.uint8))
175
- depth_blur_image = depth_blur.resize(original_size, Image.LANCZOS)
176
 
177
  # Create colored depth map for visualization
178
  depth_map_colored = plt.cm.viridis(depth_map)[:, :, :3]
179
  depth_map_viz = Image.fromarray((depth_map_colored * 255).astype(np.uint8))
180
- depth_map_image = depth_map_viz.resize(original_size, Image.LANCZOS)
181
 
182
- return np.array(depth_map_image), np.array(depth_blur_image)
183
 
184
  # Main processing function
185
  def process_image(input_image, blur_type="Gaussian Blur", blur_intensity=15):
@@ -207,7 +226,11 @@ def process_image(input_image, blur_type="Gaussian Blur", blur_intensity=15):
207
  if blur_type == "Gaussian Blur":
208
  # Apply regular Gaussian blur
209
  result = apply_background_blur(pil_img, mask_array, sigma=blur_intensity)
210
- depth_viz = np.zeros_like(img) # Placeholder for depth map
 
 
 
 
211
 
212
  else: # "Depth-based Lens Blur"
213
  # Apply depth-based blur
 
41
 
42
  # Original dimensions
43
  original_size = image.size
44
+
45
+ # Use higher resolution for better results while staying within model limits
46
+ # Most models work well with 640x640
47
+ model_size = (640, 640)
48
+ model_image = image.resize(model_size, Image.LANCZOS)
49
 
50
  # Process image with model
51
  inputs = seg_processor(images=model_image, return_tensors="pt")
 
68
  if cls_mask.sum() > binary_mask.sum():
69
  binary_mask = cls_mask
70
 
71
+ # Convert to uint8 for OpenCV processing
72
+ mask_cv = (binary_mask * 255).astype(np.uint8)
73
+
74
+ # Apply morphological operations to clean up the mask
75
  kernel = np.ones((5, 5), np.uint8)
76
  mask_cv = cv2.morphologyEx(mask_cv, cv2.MORPH_CLOSE, kernel)
77
  mask_cv = cv2.morphologyEx(mask_cv, cv2.MORPH_OPEN, kernel)
78
 
79
+ # Apply Gaussian blur to smooth the edges - less aggressive
80
+ mask_cv = cv2.GaussianBlur(mask_cv, (7, 7), 0)
81
  _, mask_cv = cv2.threshold(mask_cv, 128, 255, cv2.THRESH_BINARY)
82
 
83
+ # Resize back to original image size using bicubic interpolation for smoother results
84
+ mask_pil = Image.fromarray(mask_cv)
85
+ mask_resized = mask_pil.resize(original_size, Image.LANCZOS)
86
 
87
+ # Convert back to numpy
88
+ mask_array = np.array(mask_resized) > 128
89
 
90
+ # Create visualization of mask (red on black background)
91
+ mask_viz = np.zeros((mask_array.shape[0], mask_array.shape[1], 3), dtype=np.uint8)
92
+ mask_viz[:,:,0] = mask_array * 255 # Red channel
93
 
94
+ return mask_array, mask_viz
95
 
96
  # Function to apply Gaussian blur to background
97
  def apply_background_blur(image, mask, sigma=15):
 
111
  binary_mask = mask > 0
112
 
113
  # Apply Gaussian blur to the entire image
114
+ # Use OpenCV for better performance on larger images
115
+ blurred = cv2.GaussianBlur(image_array, (0, 0), sigma)
 
116
 
117
  # Combine original foreground with blurred background
118
  result = np.copy(blurred)
 
132
 
133
  # Original dimensions
134
  original_size = image.size
135
+
136
+ # Higher resolution for depth estimation
137
+ model_size = (640, 640)
138
  model_image = image.resize(model_size, Image.LANCZOS)
139
 
140
  # Process image for depth estimation
 
149
  depth = predicted_depth.squeeze().cpu().numpy()
150
  depth_map = (depth - depth.min()) / (depth.max() - depth.min())
151
 
152
+ # Create high-res depth map
153
+ depth_map_highres = cv2.resize(depth_map, (model_size[0], model_size[1]), interpolation=cv2.INTER_CUBIC)
 
154
 
155
  # Invert depth map (closer objects should be less blurred)
156
+ inverted_depth_map = 1.0 - depth_map_highres
157
 
158
  # If mask is provided, ensure foreground is not blurred at all
159
  if mask is not None:
160
  # Resize mask to match model size
161
+ mask_pil = Image.fromarray((mask.astype(np.uint8) * 255))
162
  mask_resized = np.array(mask_pil.resize(model_size, Image.LANCZOS)) > 128
163
  # Set depth map to 0 (no blur) for foreground pixels
164
  inverted_depth_map = inverted_depth_map * (1 - mask_resized)
165
 
166
+ # Convert to numpy array for processing
167
+ img_array = np.array(model_image)
 
168
 
169
+ # Create a progressive blur effect with multiple levels
170
+ result = np.copy(img_array)
171
+
172
+ # Apply multiple blur levels for smoother transitions
173
+ num_levels = 8
174
+ for i in range(num_levels):
175
+ # Calculate blur sigma for this level
176
+ level_sigma = max_sigma * (i + 1) / num_levels
177
+
178
+ # Create a blurred version of the image at this sigma level
179
+ level_blurred = cv2.GaussianBlur(img_array, (0, 0), level_sigma)
180
+
181
+ # Calculate where to apply this blur level
182
+ depth_min = i / num_levels
183
+ depth_max = (i + 1) / num_levels
184
+
185
+ # Create a mask for this depth range
186
+ level_mask = (inverted_depth_map >= depth_min) & (inverted_depth_map < depth_max)
187
+
188
+ # Apply this blur level
189
+ for c in range(3):
190
+ result[:,:,c] = np.where(level_mask, level_blurred[:,:,c], result[:,:,c])
191
 
192
+ # Convert result back to PIL and resize to original dimensions
193
+ result_pil = Image.fromarray(result.astype(np.uint8))
194
+ result_resized = result_pil.resize(original_size, Image.LANCZOS)
195
 
196
  # Create colored depth map for visualization
197
  depth_map_colored = plt.cm.viridis(depth_map)[:, :, :3]
198
  depth_map_viz = Image.fromarray((depth_map_colored * 255).astype(np.uint8))
199
+ depth_map_viz_resized = depth_map_viz.resize(original_size, Image.LANCZOS)
200
 
201
+ return np.array(depth_map_viz_resized), np.array(result_resized)
202
 
203
  # Main processing function
204
  def process_image(input_image, blur_type="Gaussian Blur", blur_intensity=15):
 
226
  if blur_type == "Gaussian Blur":
227
  # Apply regular Gaussian blur
228
  result = apply_background_blur(pil_img, mask_array, sigma=blur_intensity)
229
+ # Create placeholder for depth map (black image)
230
+ depth_viz = np.zeros_like(img)
231
+ # Add text saying "Depth map not used for Gaussian blur"
232
+ font = cv2.FONT_HERSHEY_SIMPLEX
233
+ cv2.putText(depth_viz, "Depth map not used", (50, 50), font, 1, (255, 255, 255), 2)
234
 
235
  else: # "Depth-based Lens Blur"
236
  # Apply depth-based blur