joeWabbit commited on
Commit
032683a
·
verified ·
1 Parent(s): 9bcecd2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +103 -38
app.py CHANGED
@@ -1,56 +1,109 @@
1
- from transformers import pipeline
2
- from PIL import Image, ImageFilter
3
  import gradio as gr
4
  import torch
5
  import numpy as np
 
 
 
 
6
 
7
- # --- Depth-Based Blur using a Pipeline ---
8
- # Use the pipeline for depth estimation with the small model.
9
- depth_pipe = pipeline(task="depth-estimation", model="depth-anything/Depth-Anything-V2-Small-hf")
10
-
11
- def compute_depth_map_pipeline(image: Image.Image, scale_factor: float) -> np.ndarray:
12
  """
13
- Computes a depth map using the Hugging Face pipeline.
14
- The returned depth is inverted (so near=0 and far=1) and scaled.
 
15
  """
16
- result = depth_pipe(image) # No [0] index; the pipeline returns a dictionary
17
- depth_map = np.array(result["depth"])
18
- # Invert depth so that near becomes 0 and far becomes 1
19
- depth_map = 1.0 - depth_map
20
- depth_map *= scale_factor
21
- return depth_map
 
 
 
22
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  def layered_blur(image: Image.Image, depth_map: np.ndarray, num_layers: int, max_blur: float) -> Image.Image:
24
  """
25
- Applies multiple levels of Gaussian blur based on depth.
26
- The image is blurred with increasing radii and then composited
27
- using a mask derived from the depth map divided into bins.
28
  """
29
  blur_radii = np.linspace(0, max_blur, num_layers)
30
- blur_versions = [image.filter(ImageFilter.GaussianBlur(r)) for r in blur_radii]
31
- upper_bound = depth_map.max()
32
- thresholds = np.linspace(0, upper_bound, num_layers + 1)
33
  final_image = blur_versions[-1]
34
  for i in range(num_layers - 1, -1, -1):
35
- mask_array = np.logical_and(depth_map >= thresholds[i],
36
- depth_map < thresholds[i + 1]).astype(np.uint8) * 255
 
 
37
  mask_image = Image.fromarray(mask_array, mode="L")
38
  final_image = Image.composite(blur_versions[i], final_image, mask_image)
39
  return final_image
40
 
41
- def process_depth_blur_pipeline(uploaded_image, max_blur_value, scale_factor, num_layers):
42
  """
43
- Processes an uploaded image using depth-based blur.
44
- The image is resized to 512x512, its depth is computed via the pipeline,
45
- and a layered blur is applied.
46
  """
47
  if not isinstance(uploaded_image, Image.Image):
48
  uploaded_image = Image.open(uploaded_image)
49
  image = uploaded_image.convert("RGB").resize((512, 512))
50
- depth_map = compute_depth_map_pipeline(image, scale_factor)
51
  final_image = layered_blur(image, depth_map, int(num_layers), max_blur_value)
52
  return final_image
53
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
  # --- Segmentation-Based Blur using BEN2 ---
55
  def load_segmentation_model():
56
  """
@@ -89,16 +142,28 @@ def process_segmentation_blur(uploaded_image, seg_blur_radius: float):
89
  with gr.Blocks() as demo:
90
  gr.Markdown("# Depth-Based vs Segmentation-Based Blur")
91
  with gr.Tabs():
92
- with gr.Tab("Depth-Based Blur (Pipeline)"):
93
- depth_img = gr.Image(type="pil", label="Upload Image")
94
- depth_max_blur = gr.Slider(1.0, 5.0, value=3.0, step=0.1, label="Maximum Blur Radius")
95
- depth_scale = gr.Slider(0.1, 1.0, value=0.5, step=0.1, label="Depth Scale Factor")
96
- depth_layers = gr.Slider(2, 20, value=8, step=1, label="Number of Layers")
97
- depth_out = gr.Image(label="Depth-Based Blurred Image")
98
- depth_button = gr.Button("Process Depth Blur")
99
- depth_button.click(process_depth_blur_pipeline,
100
- inputs=[depth_img, depth_max_blur, depth_scale, depth_layers],
101
- outputs=depth_out)
 
 
 
 
 
 
 
 
 
 
 
 
102
  with gr.Tab("Segmentation-Based Blur (BEN2)"):
103
  seg_img = gr.Image(type="pil", label="Upload Image")
104
  seg_blur = gr.Slider(5, 30, value=15, step=1, label="Segmentation Blur Radius")
 
 
 
1
  import gradio as gr
2
  import torch
3
  import numpy as np
4
+ from transformers import AutoImageProcessor, AutoModelForDepthEstimation
5
+ from PIL import Image, ImageFilter
6
+ import matplotlib.pyplot as plt
7
+ import matplotlib.cm as cm
8
 
9
+ # ---------------------------
10
+ # Depth Estimation Utilities
11
+ # ---------------------------
12
+ def compute_depth_map(image: Image.Image, scale_factor: float) -> np.ndarray:
 
13
  """
14
+ Loads the LiheYoung/depth-anything-large-hf model and computes a depth map.
15
+ The depth map is normalized, inverted (so that near=0 and far=1),
16
+ and multiplied by the given scale_factor.
17
  """
18
+ # Load model and processor from pretrained weights
19
+ image_processor = AutoImageProcessor.from_pretrained("LiheYoung/depth-anything-large-hf")
20
+ model = AutoModelForDepthEstimation.from_pretrained("LiheYoung/depth-anything-large-hf")
21
+
22
+ # Prepare image for the model
23
+ inputs = image_processor(images=image, return_tensors="pt")
24
+ with torch.no_grad():
25
+ outputs = model(**inputs)
26
+ predicted_depth = outputs.predicted_depth
27
 
28
+ # Interpolate predicted depth map to match image size
29
+ prediction = torch.nn.functional.interpolate(
30
+ predicted_depth.unsqueeze(1),
31
+ size=image.size[::-1], # PIL image size is (width, height)
32
+ mode="bicubic",
33
+ align_corners=False,
34
+ )
35
+ # Normalize for visualization
36
+ depth_min = prediction.min()
37
+ depth_max = prediction.max()
38
+ depth_vis = (prediction - depth_min) / (depth_max - depth_min + 1e-8)
39
+ depth_map = depth_vis.squeeze().cpu().numpy()
40
+ # Invert so that near=0 and far=1, then scale
41
+ depth_map_inverted = 1.0 - depth_map
42
+ depth_map_inverted *= scale_factor
43
+ return depth_map_inverted
44
+
45
+ # ---------------------------
46
+ # Depth-Based Blur Functions
47
+ # ---------------------------
48
  def layered_blur(image: Image.Image, depth_map: np.ndarray, num_layers: int, max_blur: float) -> Image.Image:
49
  """
50
+ Creates multiple blurred versions of the image (using Gaussian blur with radii from 0 to max_blur)
51
+ and composites them using masks generated from bins of the normalized depth map.
 
52
  """
53
  blur_radii = np.linspace(0, max_blur, num_layers)
54
+ blur_versions = [image.filter(ImageFilter.GaussianBlur(radius)) for radius in blur_radii]
55
+ # Use a fixed range (0 to 1) since the depth map is normalized
56
+ thresholds = np.linspace(0, 1, num_layers + 1)
57
  final_image = blur_versions[-1]
58
  for i in range(num_layers - 1, -1, -1):
59
+ mask_array = np.logical_and(
60
+ depth_map >= thresholds[i],
61
+ depth_map < thresholds[i + 1]
62
+ ).astype(np.uint8) * 255
63
  mask_image = Image.fromarray(mask_array, mode="L")
64
  final_image = Image.composite(blur_versions[i], final_image, mask_image)
65
  return final_image
66
 
67
+ def process_depth_blur(uploaded_image, max_blur_value, scale_factor, num_layers):
68
  """
69
+ Resizes the uploaded image to 512x512, computes its depth map,
70
+ and applies layered blur based on the depth.
 
71
  """
72
  if not isinstance(uploaded_image, Image.Image):
73
  uploaded_image = Image.open(uploaded_image)
74
  image = uploaded_image.convert("RGB").resize((512, 512))
75
+ depth_map = compute_depth_map(image, scale_factor)
76
  final_image = layered_blur(image, depth_map, int(num_layers), max_blur_value)
77
  return final_image
78
 
79
+ # ---------------------------
80
+ # Depth Heatmap Functions
81
+ # ---------------------------
82
+ def create_heatmap(depth_map: np.ndarray, intensity: float) -> Image.Image:
83
+ """
84
+ Applies a colormap to the normalized depth map.
85
+ The 'intensity' slider multiplies the normalized depth values (clipped to [0,1])
86
+ before applying the "inferno" colormap.
87
+ """
88
+ # Multiply depth map by intensity and clip to 0-1 range
89
+ normalized = np.clip(depth_map * intensity, 0, 1)
90
+ colormap = cm.get_cmap("inferno")
91
+ colored = colormap(normalized) # Returns an RGBA image in [0, 1]
92
+ heatmap = (colored[:, :, :3] * 255).astype(np.uint8) # drop alpha and convert to [0,255]
93
+ return Image.fromarray(heatmap)
94
+
95
+ def process_depth_heatmap(uploaded_image, intensity):
96
+ """
97
+ Resizes the uploaded image to 512x512, computes its depth map (with scale factor 1.0),
98
+ and returns a heatmap visualization.
99
+ """
100
+ if not isinstance(uploaded_image, Image.Image):
101
+ uploaded_image = Image.open(uploaded_image)
102
+ image = uploaded_image.convert("RGB").resize((512, 512))
103
+ depth_map = compute_depth_map(image, scale_factor=1.0)
104
+ heatmap_img = create_heatmap(depth_map, intensity)
105
+ return heatmap_img
106
+
107
  # --- Segmentation-Based Blur using BEN2 ---
108
  def load_segmentation_model():
109
  """
 
142
  with gr.Blocks() as demo:
143
  gr.Markdown("# Depth-Based vs Segmentation-Based Blur")
144
  with gr.Tabs():
145
+ with gr.Tab("Depth Blur"):
146
+ img_input = gr.Image(type="pil", label="Upload Image")
147
+ blur_slider = gr.Slider(1, 50, value=20, label="Maximum Blur Radius")
148
+ scale_slider = gr.Slider(0.1, 2.0, value=1.0, label="Depth Scale Factor")
149
+ layers_slider = gr.Slider(2, 10, value=5, label="Number of Layers")
150
+ blur_output = gr.Image(label="Depth Blur Result")
151
+ blur_button = gr.Button("Process Depth Blur")
152
+ blur_button.click(
153
+ process_depth_blur,
154
+ inputs=[img_input, blur_slider, scale_slider, layers_slider],
155
+ outputs=blur_output
156
+ )
157
+ with gr.Tab("Depth Heatmap"):
158
+ img_input2 = gr.Image(type="pil", label="Upload Image")
159
+ intensity_slider = gr.Slider(0.5, 5.0, value=1.0, label="Heatmap Intensity")
160
+ heatmap_output = gr.Image(label="Depth Heatmap")
161
+ heatmap_button = gr.Button("Generate Depth Heatmap")
162
+ heatmap_button.click(
163
+ process_depth_heatmap,
164
+ inputs=[img_input2, intensity_slider],
165
+ outputs=heatmap_output
166
+ )
167
  with gr.Tab("Segmentation-Based Blur (BEN2)"):
168
  seg_img = gr.Image(type="pil", label="Upload Image")
169
  seg_blur = gr.Slider(5, 30, value=15, step=1, label="Segmentation Blur Radius")