sjagird1 commited on
Commit
467cdf6
·
verified ·
1 Parent(s): c092fae

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +43 -89
app.py CHANGED
@@ -17,17 +17,8 @@ def preprocess_image(image):
17
  def segment_image(image, model_name="yolov8n-seg"):
18
  """
19
  Perform instance segmentation on the input image using YOLO segmentation model.
20
-
21
- Args:
22
- image (PIL.Image): Input image
23
- model_name (str): Name of the YOLO segmentation model
24
-
25
- Returns:
26
- numpy.ndarray: Segmentation mask with instance segmentation
27
  """
28
  from ultralytics import YOLO
29
- import numpy as np
30
- import torch
31
 
32
  # Load the YOLO segmentation model
33
  model = YOLO(model_name)
@@ -35,76 +26,38 @@ def segment_image(image, model_name="yolov8n-seg"):
35
  # Run inference
36
  results = model(image)
37
 
38
- # Create a blank mask
39
- mask = np.zeros(image.size[::-1], dtype=np.uint8)
40
 
41
  # Process each detected object
42
  for result in results:
43
- # Get masks for all detected objects
44
- masks = result.masks
45
-
46
- if masks is not None:
47
- # Convert masks to numpy and add to the overall mask
48
- for single_mask in masks:
49
  # Convert mask to numpy and resize if needed
50
  mask_array = single_mask.data.cpu().numpy().squeeze()
51
  mask_array = (mask_array > 0.5).astype(np.uint8)
52
 
53
- # If mask size doesn't match image, resize
54
  if mask_array.shape != mask.shape:
55
- from PIL import Image
56
  mask_array = np.array(
57
  Image.fromarray(mask_array).resize(
58
- image.size[::-1],
59
  Image.NEAREST
60
  )
61
  )
62
 
63
- # Add this mask to the overall mask
64
  mask = np.maximum(mask, mask_array)
65
 
66
  return mask
67
 
68
- def process_image(image, blur_type, sigma=15):
69
- """Process image based on blur type."""
70
- # Preprocess image
71
- pil_image = preprocess_image(image)
72
-
73
- # Apply appropriate blur
74
- if blur_type == "Gaussian Background Blur":
75
- # Get segmentation mask
76
- segmentation_mask = segment_image(pil_image)
77
-
78
- # Convert to 3-channel mask
79
- mask_3d = np.stack([segmentation_mask] * 3, axis=2)
80
-
81
- # Apply Gaussian blur
82
- image_array = np.array(pil_image)
83
- blurred = np.zeros_like(image_array)
84
- for channel in range(3):
85
- blurred[:, :, channel] = gaussian_filter(image_array[:, :, channel], sigma=sigma)
86
-
87
- # Combine original and blurred images
88
- result = image_array * mask_3d + blurred * (1 - mask_3d)
89
- result = Image.fromarray(result.astype(np.uint8))
90
-
91
- elif blur_type == "Depth-Aware Lens Blur":
92
- result = apply_depth_aware_blur(pil_image, max_sigma=sigma)
93
- else:
94
- result = pil_image
95
-
96
- return result
97
-
98
  def apply_gaussian_blur(image, sigma=15):
99
  """Apply Gaussian blur to the background."""
100
  # Convert image to numpy array
101
  image_array = np.array(image)
102
 
103
- # Create segmentation mask (assuming we want to keep the foreground)
104
- segmentation_mask = segment_image(image)
105
-
106
- # Choose a prominent object class (e.g., person with ID 24 in Cityscapes)
107
- foreground_mask = (segmentation_mask == 24).astype(np.uint8)
108
 
109
  # Prepare blurred version
110
  blurred = np.zeros_like(image_array)
@@ -128,48 +81,49 @@ def estimate_depth(image, model_name="depth-anything/Depth-Anything-V2-Small-hf"
128
  depth_output = depth_estimator(image)
129
  depth_map = np.array(depth_output["depth"])
130
 
131
- # Normalize depth map
132
  depth_map = (depth_map - depth_map.min()) / (depth_map.max() - depth_map.min())
133
 
134
  return depth_map
135
 
136
  def apply_depth_aware_blur(image, max_sigma=10, min_sigma=0):
137
- """Apply depth-aware blur to the image (REVERSED version)."""
138
- # Estimate depth
139
  depth_map = estimate_depth(image)
140
 
141
  image_array = np.array(image)
142
- blurred = np.zeros_like(image_array, dtype=np.float32)
143
-
144
- # REVERSED: Now we use depth_map directly (no inversion) so farther objects get more blur
145
- sigmas = np.interp(depth_map, [0, 1], [min_sigma, max_sigma])
146
-
147
- # Precompute blurred layers
148
- blur_stack = {}
149
- for sigma in np.unique(sigmas):
150
- if sigma > 0:
151
- blurred_layer = np.zeros_like(image_array, dtype=np.float32)
152
- for channel in range(3):
153
- blurred_layer[:, :, channel] = gaussian_filter(
154
- image_array[:, :, channel].astype(np.float32),
155
- sigma=sigma
156
- )
157
- blur_stack[sigma] = blurred_layer
158
-
159
- # Blend based on depth
160
- for sigma in np.unique(sigmas):
161
- if sigma > 0:
162
- mask = (sigmas == sigma)
163
- mask_3d = np.stack([mask] * 3, axis=2)
164
- blurred += mask_3d * blur_stack[sigma]
165
- else:
166
- mask = (sigmas == 0)
167
- mask_3d = np.stack([mask] * 3, axis=2)
168
- blurred += mask_3d * image_array
169
-
170
- return Image.fromarray(blurred.astype(np.uint8))
171
-
172
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
173
 
174
  # Gradio Interface
175
  def create_blur_app():
 
17
  def segment_image(image, model_name="yolov8n-seg"):
18
  """
19
  Perform instance segmentation on the input image using YOLO segmentation model.
 
 
 
 
 
 
 
20
  """
21
  from ultralytics import YOLO
 
 
22
 
23
  # Load the YOLO segmentation model
24
  model = YOLO(model_name)
 
26
  # Run inference
27
  results = model(image)
28
 
29
+ # Create a blank mask (1 for foreground, 0 for background)
30
+ mask = np.zeros((image.size[1], image.size[0]), dtype=np.uint8)
31
 
32
  # Process each detected object
33
  for result in results:
34
+ if result.masks is not None:
35
+ for single_mask in result.masks:
 
 
 
 
36
  # Convert mask to numpy and resize if needed
37
  mask_array = single_mask.data.cpu().numpy().squeeze()
38
  mask_array = (mask_array > 0.5).astype(np.uint8)
39
 
40
+ # Resize if needed
41
  if mask_array.shape != mask.shape:
 
42
  mask_array = np.array(
43
  Image.fromarray(mask_array).resize(
44
+ (image.size[0], image.size[1]),
45
  Image.NEAREST
46
  )
47
  )
48
 
49
+ # Add this mask to the overall mask (OR operation)
50
  mask = np.maximum(mask, mask_array)
51
 
52
  return mask
53
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
  def apply_gaussian_blur(image, sigma=15):
55
  """Apply Gaussian blur to the background."""
56
  # Convert image to numpy array
57
  image_array = np.array(image)
58
 
59
+ # Get segmentation mask (1 for foreground, 0 for background)
60
+ foreground_mask = segment_image(image)
 
 
 
61
 
62
  # Prepare blurred version
63
  blurred = np.zeros_like(image_array)
 
81
  depth_output = depth_estimator(image)
82
  depth_map = np.array(depth_output["depth"])
83
 
84
+ # Normalize depth map (0-1 where 1 is farthest)
85
  depth_map = (depth_map - depth_map.min()) / (depth_map.max() - depth_map.min())
86
 
87
  return depth_map
88
 
89
  def apply_depth_aware_blur(image, max_sigma=10, min_sigma=0):
90
+ """Apply depth-aware blur with farther objects more blurred."""
91
+ # Estimate depth (1 = farthest)
92
  depth_map = estimate_depth(image)
93
 
94
  image_array = np.array(image)
95
+
96
+ # Create single blurred version at max sigma for efficiency
97
+ max_blurred = np.zeros_like(image_array, dtype=np.float32)
98
+ for channel in range(3):
99
+ max_blurred[:, :, channel] = gaussian_filter(
100
+ image_array[:, :, channel].astype(np.float32),
101
+ sigma=max_sigma
102
+ )
103
+
104
+ # Create 3-channel depth map for blending
105
+ depth_3d = np.stack([depth_map] * 3, axis=2)
106
+
107
+ # Blend between original (near) and blurred (far) based on depth
108
+ # Higher depth values (farther) get more blur
109
+ result = image_array * (1 - depth_3d) + max_blurred * depth_3d
110
+
111
+ return Image.fromarray(result.astype(np.uint8))
 
 
 
 
 
 
 
 
 
 
 
 
 
112
 
113
+ def process_image(image, blur_type, sigma=15):
114
+ """Process image based on blur type."""
115
+ # Preprocess image
116
+ pil_image = preprocess_image(image)
117
+
118
+ # Apply appropriate blur
119
+ if blur_type == "Gaussian Background Blur":
120
+ result = apply_gaussian_blur(pil_image, sigma)
121
+ elif blur_type == "Depth-Aware Lens Blur":
122
+ result = apply_depth_aware_blur(pil_image, max_sigma=sigma)
123
+ else:
124
+ result = pil_image
125
+
126
+ return result
127
 
128
  # Gradio Interface
129
  def create_blur_app():