gchallar commited on
Commit
f59b093
·
verified ·
1 Parent(s): f632032

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +69 -107
app.py CHANGED
@@ -1,34 +1,65 @@
1
  import gradio as gr
 
2
  from PIL import Image, ImageFilter
3
  import numpy as np
4
  import torch
5
- import cv2
6
- from transformers import AutoImageProcessor, AutoModelForDepthEstimation, OneFormerProcessor, OneFormerForUniversalSegmentation
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
 
8
- # Load depth estimation model
9
- image_processor = AutoImageProcessor.from_pretrained("depth-anything/Depth-Anything-V2-Small-hf")
10
- depth_model = AutoModelForDepthEstimation.from_pretrained("depth-anything/Depth-Anything-V2-Small-hf")
11
 
12
- # Load OneFormer processor and model
13
- processor = OneFormerProcessor.from_pretrained("shi-labs/oneformer_coco_swin_large")
14
- segmentation_model = OneFormerForUniversalSegmentation.from_pretrained("shi-labs/oneformer_coco_swin_large")
 
 
 
 
 
 
 
15
 
16
- def apply_gaussian_blur(image, foreground_label='person'):
17
- """Applies Gaussian blur to the background based on a segmentation mask for the foreground."""
18
-
19
  # Prepare input for semantic segmentation
20
  inputs = processor(images=image, task_inputs=["semantic"], return_tensors="pt")
21
 
22
  # Semantic segmentation
23
  with torch.no_grad():
24
- outputs = segmentation_model(**inputs)
25
 
26
  # Processing semantic segmentation output
27
  predicted_semantic_map = processor.post_process_semantic_segmentation(outputs, target_sizes=[image.size[::-1]])[0]
28
  segmentation_mask = predicted_semantic_map.cpu().numpy()
29
 
30
- # Get the mapping of class IDs to labels from the processor
31
- id2label = segmentation_model.config.id2label
 
 
 
32
  foreground_class_id = None
33
  for id, label in id2label.items():
34
  if label == foreground_label:
@@ -36,108 +67,39 @@ def apply_gaussian_blur(image, foreground_label='person'):
36
  break
37
 
38
  if foreground_class_id is None:
39
- print(f"Error: Could not find the label '{foreground_label}' in the model's class mapping.")
40
- return image # Return original image if foreground label is not found
41
 
42
- # Create a black background mask and set the pixels corresponding to the foreground object to white
43
  output_mask_array = np.zeros(segmentation_mask.shape, dtype=np.uint8)
44
- output_mask_array[segmentation_mask == foreground_class_id] = 255
45
-
46
- # Convert the output mask to a PIL Image (Grayscale)
47
- mask_pil = Image.fromarray(output_mask_array, mode='L')
48
-
49
- # Resize the mask to match the image size
50
- mask_pil = mask_pil.resize(image.size)
51
- output_mask_array = np.array(mask_pil)
52
-
53
- # Create a blurred version of the input image
54
- blurred_background = image.filter(ImageFilter.GaussianBlur(radius=15))
55
 
56
- # Convert images to NumPy arrays
57
- img_array = np.array(image)
58
- blurred_array = np.array(blurred_background)
59
-
60
- # Create a boolean mask (foreground = True, background = False)
61
- foreground_mask = output_mask_array > 0
62
- foreground_mask_3d = np.stack([foreground_mask] * 3, axis=-1)
63
-
64
- # Blend the original image with the blurred background
65
- final_image_array = np.where(foreground_mask_3d, img_array, blurred_array)
66
- final_image = Image.fromarray(final_image_array.astype(np.uint8))
67
-
68
- return final_image
69
-
70
- def apply_lens_blur(image):
71
- """Applies depth-based lens blur using a pre-trained model."""
72
-
73
- # Resize image to 512x512 for processing
74
- resized_image = image.resize((512, 512))
75
- image_np = np.array(resized_image)
76
 
77
- # Prepare image for the model
78
- inputs = image_processor(images=resized_image, return_tensors="pt")
 
79
 
80
- with torch.no_grad():
81
- outputs = depth_model(**inputs)
82
- predicted_depth = outputs.predicted_depth
83
-
84
- # Interpolate to the original size
85
- prediction = torch.nn.functional.interpolate(
86
- predicted_depth.unsqueeze(1),
87
- size=resized_image.size[::-1],
88
- mode="bicubic",
89
- align_corners=False,
90
- ).squeeze()
91
-
92
- # Convert prediction to a NumPy array
93
- depth_map = prediction.cpu().numpy()
94
-
95
- # Normalize the depth map to the range 0-1
96
- depth_norm = (depth_map - np.min(depth_map)) / (np.max(depth_map) - np.min(depth_map))
97
-
98
- num_blur_levels = 5
99
- blurred_layers = []
100
-
101
- for i in range(num_blur_levels):
102
- sigma = i * 0.5
103
- if sigma == 0:
104
- blurred = image_np
105
- else:
106
- blurred = cv2.GaussianBlur(image_np, (15, 15), sigmaX=sigma, sigmaY=sigma, borderType=cv2.BORDER_REPLICATE)
107
- blurred_layers.append(blurred)
108
-
109
- depth_indices = ((1 - depth_norm) * (num_blur_levels - 1)).astype(np.uint8)
110
-
111
- final_blurred_image = np.zeros_like(image_np)
112
-
113
- for y in range(image_np.shape[0]):
114
- for x in range(image_np.shape[1]):
115
- depth_index = depth_indices[y, x]
116
- final_blurred_image[y, x] = blurred_layers[depth_index][y, x]
117
-
118
- # Convert the final blurred image back to a PIL Image
119
- final_blurred_pil_image = Image.fromarray(final_blurred_image)
120
-
121
- return final_blurred_pil_image
122
-
123
- def process_image(image, blur_type, foreground_label='person'):
124
- """Processes the image based on the selected blur type."""
125
- if blur_type == "Gaussian Blur":
126
- return apply_gaussian_blur(image, foreground_label=foreground_label)
127
  else:
128
- return apply_lens_blur(image)
 
 
129
 
130
- interface = gr.Interface(
131
- fn=process_image,
132
  inputs=[
133
- gr.Image(type="pil", label="Upload an Image"),
134
- gr.Radio(["Gaussian Blur", "Lens Blur"], label="Choose Blur Effect"),
135
- gr.Textbox(label="Foreground Label (for Gaussian Blur)", default="person")
 
136
  ],
137
- outputs=[gr.Image(type="pil"), gr.Image(type="pil")],
138
- title="Gaussian & Lens Blur Effects",
139
- description="Upload an image and select either Gaussian blur (with foreground segmentation) or depth-based lens blur."
140
  )
141
 
142
  if __name__ == "__main__":
143
- interface.launch()
 
1
  import gradio as gr
2
+ from transformers import OneFormerProcessor, OneFormerForUniversalSegmentation
3
  from PIL import Image, ImageFilter
4
  import numpy as np
5
  import torch
6
+ from scipy.ndimage import gaussian_filter
7
+
8
+ # Load the OneFormer processor and model globally (to avoid reloading for each request)
9
+ processor = None
10
+ model = None
11
+ try:
12
+ processor = OneFormerProcessor.from_pretrained("shi-labs/oneformer_coco_swin_large")
13
+ model = OneFormerForUniversalSegmentation.from_pretrained("shi-labs/oneformer_coco_swin_large")
14
+ except Exception as e:
15
+ print(f"Error loading OneFormer model: {e}")
16
+
17
+ def apply_gaussian_blur(image, mask, radius):
18
+ """Applies Gaussian blur to the background of the image."""
19
+ blurred_background = image.filter(ImageFilter.GaussianBlur(radius=radius))
20
+ img_array = np.array(image)
21
+ blurred_array = np.array(blurred_background)
22
+ foreground_mask = mask > 0
23
+ foreground_mask_3d = np.stack([foreground_mask] * 3, axis=-1)
24
+ final_image_array = np.where(foreground_mask_3d, img_array, blurred_array)
25
+ return Image.fromarray(final_image_array.astype(np.uint8))
26
+
27
+ def apply_lens_blur(image, mask, strength):
28
+ """Placeholder for Lens Blur function. Will be implemented later."""
29
+ # Convert PIL Image to NumPy array
30
+ img_array = np.array(image)
31
+ mask_array = np.array(mask) / 255.0 # Normalize mask to 0-1
32
 
33
+ # Apply a simple blur based on the mask (this is a very basic placeholder)
34
+ blurred_image = gaussian_filter(img_array, sigma=strength * mask_array[:, :, np.newaxis])
 
35
 
36
+ return Image.fromarray(blurred_image.astype(np.uint8))
37
+
38
+ def segment_and_blur(input_image, blur_type, gaussian_radius=15, lens_strength=5):
39
+ """Segments the input image and applies the selected blur."""
40
+ if processor is None or model is None:
41
+ return "Error: OneFormer model not loaded."
42
+
43
+ image = input_image.convert("RGB")
44
+ # Rotate the image (assuming this is still needed)
45
+ image = image.rotate(-90, expand=True)
46
 
 
 
 
47
  # Prepare input for semantic segmentation
48
  inputs = processor(images=image, task_inputs=["semantic"], return_tensors="pt")
49
 
50
  # Semantic segmentation
51
  with torch.no_grad():
52
+ outputs = model(**inputs)
53
 
54
  # Processing semantic segmentation output
55
  predicted_semantic_map = processor.post_process_semantic_segmentation(outputs, target_sizes=[image.size[::-1]])[0]
56
  segmentation_mask = predicted_semantic_map.cpu().numpy()
57
 
58
+ # Get the mapping of class IDs to labels
59
+ id2label = model.config.id2label
60
+
61
+ # Set foreground label to person
62
+ foreground_label = 'person'
63
  foreground_class_id = None
64
  for id, label in id2label.items():
65
  if label == foreground_label:
 
67
  break
68
 
69
  if foreground_class_id is None:
70
+ return f"Error: Could not find the label '{foreground_label}' in the model's class mapping."
 
71
 
72
+ # Black background mask
73
  output_mask_array = np.zeros(segmentation_mask.shape, dtype=np.uint8)
 
 
 
 
 
 
 
 
 
 
 
74
 
75
+ # Set the pixels corresponding to the foreground object to white (255)
76
+ output_mask_array[segmentation_mask == foreground_class_id] = 255
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
 
78
+ # Convert the NumPy array to a PIL Image and resize to match input
79
+ mask_pil = Image.fromarray(output_mask_array, mode='L').resize(image.size)
80
+ mask_array = np.array(mask_pil)
81
 
82
+ if blur_type == "Gaussian":
83
+ blurred_image = apply_gaussian_blur(image, mask_array, gaussian_radius)
84
+ elif blur_type == "Lens":
85
+ blurred_image = apply_lens_blur(image, mask_array, lens_strength)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
  else:
87
+ return "Error: Invalid blur type selected."
88
+
89
+ return blurred_image
90
 
91
+ iface = gr.Interface(
92
+ fn=segment_and_blur,
93
  inputs=[
94
+ gr.Image(label="Input Image"),
95
+ gr.Radio(["Gaussian", "Lens"], label="Blur Type", value="Gaussian"),
96
+ gr.Slider(0, 30, step=1, default=15, label="Gaussian Blur Radius"),
97
+ gr.Slider(0, 10, step=1, default=5, label="Lens Blur Strength"),
98
  ],
99
+ outputs=gr.Image(label="Output Image"),
100
+ title="Image Background Blur App",
101
+ description="Upload an image, select a blur type (Gaussian or Lens), and adjust the blur parameters to blur the background while keeping the person in focus."
102
  )
103
 
104
  if __name__ == "__main__":
105
+ iface.launch()