sjagird1 commited on
Commit
cc7361e
·
verified ·
1 Parent(s): 8da4c43

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +168 -0
app.py ADDED
@@ -0,0 +1,168 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import torch
3
+ import numpy as np
4
+ from PIL import Image
5
+ from scipy.ndimage import gaussian_filter
6
+ from transformers import pipeline
7
+
8
+ def preprocess_image(image):
9
+ """Resize and convert image to PIL format if needed."""
10
+ if isinstance(image, np.ndarray):
11
+ image = Image.fromarray(image)
12
+
13
+ # Resize to 512x512 while maintaining aspect ratio
14
+ image = image.resize((512, 512))
15
+ return image
16
+
17
+ def segment_image(image, model_name="facebook/mask2former-swin-large-cityscapes-semantic"):
18
+ """Perform semantic segmentation on the input image."""
19
+ from transformers import AutoImageProcessor, Mask2FormerForUniversalSegmentation
20
+
21
+ # Load processor and model
22
+ processor = AutoImageProcessor.from_pretrained(model_name)
23
+ model = Mask2FormerForUniversalSegmentation.from_pretrained(model_name)
24
+
25
+ # Prepare inputs
26
+ inputs = processor(images=image, return_tensors="pt")
27
+
28
+ # Run inference
29
+ with torch.no_grad():
30
+ outputs = model(**inputs)
31
+
32
+ # Post-process segmentation
33
+ semantic_map = processor.post_process_semantic_segmentation(
34
+ outputs,
35
+ target_sizes=[image.size[::-1]]
36
+ )[0]
37
+
38
+ # Convert to numpy and create binary mask
39
+ semantic_map = semantic_map.numpy()
40
+ return semantic_map
41
+
42
+ def apply_gaussian_blur(image, sigma=15):
43
+ """Apply Gaussian blur to the background."""
44
+ # Convert image to numpy array
45
+ image_array = np.array(image)
46
+
47
+ # Create segmentation mask (assuming we want to keep the foreground)
48
+ segmentation_mask = segment_image(image)
49
+
50
+ # Choose a prominent object class (e.g., person with ID 24 in Cityscapes)
51
+ foreground_mask = (segmentation_mask == 24).astype(np.uint8)
52
+
53
+ # Prepare blurred version
54
+ blurred = np.zeros_like(image_array)
55
+ for channel in range(3):
56
+ blurred[:, :, channel] = gaussian_filter(image_array[:, :, channel], sigma=sigma)
57
+
58
+ # Combine original and blurred images based on mask
59
+ mask_3d = np.stack([foreground_mask] * 3, axis=2)
60
+ result = image_array * mask_3d + blurred * (1 - mask_3d)
61
+
62
+ return Image.fromarray(result.astype(np.uint8))
63
+
64
+ def estimate_depth(image, model_name="depth-anything/Depth-Anything-V2-Small-hf"):
65
+ """Estimate depth of the image."""
66
+ depth_estimator = pipeline(
67
+ task="depth-estimation",
68
+ model=model_name,
69
+ torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32
70
+ )
71
+
72
+ depth_output = depth_estimator(image)
73
+ depth_map = np.array(depth_output["depth"])
74
+
75
+ # Normalize depth map
76
+ depth_map = (depth_map - depth_map.min()) / (depth_map.max() - depth_map.min())
77
+
78
+ return depth_map
79
+
80
+ def apply_depth_aware_blur(image, max_sigma=10, min_sigma=0):
81
+ """Apply depth-aware blur to the image."""
82
+ # Estimate depth
83
+ depth_map = estimate_depth(image)
84
+
85
+ image_array = np.array(image)
86
+ blurred = np.zeros_like(image_array, dtype=np.float32)
87
+
88
+ # Interpolate sigmas based on depth
89
+ sigmas = np.interp(depth_map, [0, 1], [min_sigma, max_sigma])
90
+
91
+ # Precompute blurred layers
92
+ blur_stack = {}
93
+ for sigma in np.unique(sigmas):
94
+ if sigma > 0:
95
+ blurred_layer = np.zeros_like(image_array, dtype=np.float32)
96
+ for channel in range(3):
97
+ blurred_layer[:, :, channel] = gaussian_filter(
98
+ image_array[:, :, channel].astype(np.float32),
99
+ sigma=sigma
100
+ )
101
+ blur_stack[sigma] = blurred_layer
102
+
103
+ # Blend based on depth
104
+ for sigma in np.unique(sigmas):
105
+ if sigma > 0:
106
+ mask = (sigmas == sigma)
107
+ mask_3d = np.stack([mask] * 3, axis=2)
108
+ blurred += mask_3d * blur_stack[sigma]
109
+ else:
110
+ mask = (sigmas == 0)
111
+ mask_3d = np.stack([mask] * 3, axis=2)
112
+ blurred += mask_3d * image_array
113
+
114
+ return Image.fromarray(blurred.astype(np.uint8))
115
+
116
+ def process_image(image, blur_type, sigma=15):
117
+ """Process image based on blur type."""
118
+ # Preprocess image
119
+ pil_image = preprocess_image(image)
120
+
121
+ # Apply appropriate blur
122
+ if blur_type == "Gaussian Background Blur":
123
+ result = apply_gaussian_blur(pil_image, sigma)
124
+ elif blur_type == "Depth-Aware Lens Blur":
125
+ result = apply_depth_aware_blur(pil_image, max_sigma=sigma)
126
+ else:
127
+ result = pil_image
128
+
129
+ return result
130
+
131
+ # Gradio Interface
132
+ def create_blur_app():
133
+ with gr.Blocks() as demo:
134
+ gr.Markdown("# Image Blur Effects")
135
+
136
+ with gr.Row():
137
+ input_image = gr.Image(label="Input Image", type="pil")
138
+ output_image = gr.Image(label="Processed Image")
139
+
140
+ with gr.Row():
141
+ blur_type = gr.Dropdown(
142
+ choices=[
143
+ "Gaussian Background Blur",
144
+ "Depth-Aware Lens Blur"
145
+ ],
146
+ label="Blur Type"
147
+ )
148
+ sigma = gr.Slider(
149
+ minimum=0,
150
+ maximum=30,
151
+ value=15,
152
+ label="Blur Intensity"
153
+ )
154
+
155
+ process_btn = gr.Button("Apply Blur Effect")
156
+
157
+ process_btn.click(
158
+ fn=process_image,
159
+ inputs=[input_image, blur_type, sigma],
160
+ outputs=output_image
161
+ )
162
+
163
+ return demo
164
+
165
+ # Launch the app
166
+ if __name__ == "__main__":
167
+ demo = create_blur_app()
168
+ demo.launch()