Update app.py
Browse files
app.py
CHANGED
@@ -38,8 +38,9 @@ depth_pipeline = pipeline("depth-estimation", model="depth-anything/Depth-Anythi
|
|
38 |
|
39 |
def segment_and_blur_background(input_image: Image.Image, blur_radius: int = 15, threshold: float = 0.5) -> Image.Image:
|
40 |
"""
|
41 |
-
|
42 |
-
|
|
|
43 |
"""
|
44 |
# Ensure the image is in RGB and get its original dimensions
|
45 |
image = input_image.convert("RGB")
|
@@ -53,7 +54,7 @@ def segment_and_blur_background(input_image: Image.Image, blur_radius: int = 15,
|
|
53 |
preds = segmentation_model(input_tensor)[-1].sigmoid().cpu()
|
54 |
pred = preds[0].squeeze()
|
55 |
|
56 |
-
# Create a binary mask using the threshold
|
57 |
binary_mask = (pred > threshold).float()
|
58 |
mask_pil = transforms.ToPILImage()(binary_mask).convert("L")
|
59 |
# Convert grayscale mask to pure binary (0 or 255)
|
@@ -63,15 +64,15 @@ def segment_and_blur_background(input_image: Image.Image, blur_radius: int = 15,
|
|
63 |
|
64 |
# Apply Gaussian blur to the entire image for background
|
65 |
blurred_image = image.filter(ImageFilter.GaussianBlur(blur_radius))
|
66 |
-
# Composite the original image (foreground) with the blurred
|
67 |
final_image = Image.composite(image, blurred_image, mask_pil)
|
68 |
return final_image
|
69 |
|
70 |
|
71 |
def depth_based_lens_blur(input_image: Image.Image, max_blur: float = 2, num_bands: int = 40, invert_depth: bool = False) -> Image.Image:
|
72 |
"""
|
73 |
-
Applies a depth-based blur effect using a depth map
|
74 |
-
The
|
75 |
"""
|
76 |
# Resize the input image to 512x512 for the depth estimation model
|
77 |
image_resized = input_image.resize((512, 512))
|
@@ -91,7 +92,7 @@ def depth_based_lens_blur(input_image: Image.Image, max_blur: float = 2, num_ban
|
|
91 |
orig_rgba = image_resized.convert("RGBA")
|
92 |
final_image = orig_rgba.copy()
|
93 |
|
94 |
-
# Divide the normalized depth range into bands
|
95 |
band_edges = np.linspace(0, 1, num_bands + 1)
|
96 |
for i in range(num_bands):
|
97 |
band_min = band_edges[i]
|
@@ -114,16 +115,20 @@ def depth_based_lens_blur(input_image: Image.Image, max_blur: float = 2, num_ban
|
|
114 |
return final_image.convert("RGB")
|
115 |
|
116 |
|
117 |
-
def process_image(input_image: Image.Image, effect: str) -> Image.Image:
|
118 |
"""
|
119 |
Dispatch function to apply the selected effect:
|
120 |
-
|
121 |
-
|
|
|
|
|
122 |
"""
|
123 |
if effect == "Gaussian Blur Background":
|
124 |
-
|
|
|
125 |
elif effect == "Depth-based Lens Blur":
|
126 |
-
|
|
|
127 |
else:
|
128 |
return input_image
|
129 |
|
@@ -136,13 +141,15 @@ iface = gr.Interface(
|
|
136 |
fn=process_image,
|
137 |
inputs=[
|
138 |
gr.Image(type="pil", label="Input Image"),
|
139 |
-
gr.Radio(choices=["Gaussian Blur Background", "Depth-based Lens Blur"], label="Select Effect")
|
|
|
|
|
140 |
],
|
141 |
outputs=gr.Image(type="pil", label="Output Image"),
|
142 |
-
title="Blur Effects Demo",
|
143 |
description=(
|
144 |
-
"Upload an image and choose an effect
|
145 |
-
"
|
146 |
)
|
147 |
)
|
148 |
|
|
|
38 |
|
39 |
def segment_and_blur_background(input_image: Image.Image, blur_radius: int = 15, threshold: float = 0.5) -> Image.Image:
|
40 |
"""
|
41 |
+
Uses the RMBG-2.0 segmentation model to create a binary mask,
|
42 |
+
then composites a Gaussian-blurred background with the sharp foreground.
|
43 |
+
The segmentation threshold is adjustable.
|
44 |
"""
|
45 |
# Ensure the image is in RGB and get its original dimensions
|
46 |
image = input_image.convert("RGB")
|
|
|
54 |
preds = segmentation_model(input_tensor)[-1].sigmoid().cpu()
|
55 |
pred = preds[0].squeeze()
|
56 |
|
57 |
+
# Create a binary mask using the adjustable threshold
|
58 |
binary_mask = (pred > threshold).float()
|
59 |
mask_pil = transforms.ToPILImage()(binary_mask).convert("L")
|
60 |
# Convert grayscale mask to pure binary (0 or 255)
|
|
|
64 |
|
65 |
# Apply Gaussian blur to the entire image for background
|
66 |
blurred_image = image.filter(ImageFilter.GaussianBlur(blur_radius))
|
67 |
+
# Composite the original image (foreground) with the blurred background using the mask
|
68 |
final_image = Image.composite(image, blurred_image, mask_pil)
|
69 |
return final_image
|
70 |
|
71 |
|
72 |
def depth_based_lens_blur(input_image: Image.Image, max_blur: float = 2, num_bands: int = 40, invert_depth: bool = False) -> Image.Image:
|
73 |
"""
|
74 |
+
Applies a depth-based blur effect using a depth map from Depth-Anything.
|
75 |
+
The max_blur parameter (controlled by a slider) sets the highest blur intensity.
|
76 |
"""
|
77 |
# Resize the input image to 512x512 for the depth estimation model
|
78 |
image_resized = input_image.resize((512, 512))
|
|
|
92 |
orig_rgba = image_resized.convert("RGBA")
|
93 |
final_image = orig_rgba.copy()
|
94 |
|
95 |
+
# Divide the normalized depth range into bands and apply variable blur
|
96 |
band_edges = np.linspace(0, 1, num_bands + 1)
|
97 |
for i in range(num_bands):
|
98 |
band_min = band_edges[i]
|
|
|
115 |
return final_image.convert("RGB")
|
116 |
|
117 |
|
118 |
+
def process_image(input_image: Image.Image, effect: str, threshold: float, blur_intensity: float) -> Image.Image:
|
119 |
"""
|
120 |
Dispatch function to apply the selected effect:
|
121 |
+
- "Gaussian Blur Background": uses segmentation with an adjustable threshold and blur radius.
|
122 |
+
- "Depth-based Lens Blur": applies depth-based blur with an adjustable maximum blur.
|
123 |
+
The threshold slider is used only for the segmentation effect.
|
124 |
+
The blur_intensity slider controls the blur strength in both effects.
|
125 |
"""
|
126 |
if effect == "Gaussian Blur Background":
|
127 |
+
# For segmentation, use the threshold and blur_intensity (as blur_radius)
|
128 |
+
return segment_and_blur_background(input_image, blur_radius=int(blur_intensity), threshold=threshold)
|
129 |
elif effect == "Depth-based Lens Blur":
|
130 |
+
# For depth-based blur, use the blur_intensity as the max blur value.
|
131 |
+
return depth_based_lens_blur(input_image, max_blur=blur_intensity)
|
132 |
else:
|
133 |
return input_image
|
134 |
|
|
|
141 |
fn=process_image,
|
142 |
inputs=[
|
143 |
gr.Image(type="pil", label="Input Image"),
|
144 |
+
gr.Radio(choices=["Gaussian Blur Background", "Depth-based Lens Blur"], label="Select Effect"),
|
145 |
+
gr.Slider(0.0, 1.0, value=0.5, label="Segmentation Threshold (for Gaussian Blur)"),
|
146 |
+
gr.Slider(0, 30, value=15, step=1, label="Blur Intensity (for both effects)")
|
147 |
],
|
148 |
outputs=gr.Image(type="pil", label="Output Image"),
|
149 |
+
title="Interactive Blur Effects Demo",
|
150 |
description=(
|
151 |
+
"Upload an image and choose an effect. For 'Gaussian Blur Background', adjust the segmentation threshold and blur intensity. "
|
152 |
+
"For 'Depth-based Lens Blur', the blur intensity slider sets the maximum blur based on depth."
|
153 |
)
|
154 |
)
|
155 |
|