apexmin commited on
Commit
2d4c3af
·
1 Parent(s): f6840f9

Init Space

Browse files
Files changed (4) hide show
  1. .gitattributes +1 -0
  2. app.py +133 -0
  3. assets/sample.jpg +3 -0
  4. requirements.txt +7 -0
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ assets/*.jpg filter=lfs diff=lfs merge=lfs -text
app.py ADDED
@@ -0,0 +1,133 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import torch
3
+ import numpy as np
4
+ import cv2
5
+ from PIL import Image
6
+ import matplotlib.pyplot as plt
7
+ from transformers import AutoImageProcessor, AutoModelForDepthEstimation
8
+ from io import BytesIO
9
+
10
+ # Load models
11
+ image_processor = AutoImageProcessor.from_pretrained("depth-anything/Depth-Anything-V2-Small-hf")
12
+ model = AutoModelForDepthEstimation.from_pretrained("depth-anything/Depth-Anything-V2-Small-hf")
13
+
14
+ def process_image(image, total_degrade_steps=15):
15
+ # Convert to PIL if needed
16
+ if not isinstance(image, Image.Image):
17
+ image = Image.fromarray(image)
18
+
19
+ # Standardize size to 512x512
20
+ image = image.resize((512, 512), Image.LANCZOS)
21
+ # Prepare image for the model
22
+ inputs = image_processor(images=image.convert('RGB'), return_tensors="pt")
23
+
24
+ with torch.no_grad():
25
+ outputs = model(**inputs)
26
+ predicted_depth = outputs.predicted_depth
27
+
28
+ # Interpolate to original size
29
+ prediction = torch.nn.functional.interpolate(
30
+ predicted_depth.unsqueeze(1),
31
+ size=image.size[::-1],
32
+ mode="bicubic",
33
+ align_corners=False,
34
+ )
35
+ print(f'total_degrade_steps {total_degrade_steps}')
36
+ # Normalize depth map to [0, 1]
37
+ normalized_depth = (prediction - prediction.min()) / (prediction.max() - prediction.min())
38
+ normalized_depth = normalized_depth.squeeze().detach().cpu().numpy()
39
+
40
+ # Convert original image to numpy array
41
+ image_np = np.array(image)
42
+
43
+ # Create a visualization of the depth map
44
+ depth_visualization = (normalized_depth * 255).astype(np.uint8)
45
+ depth_image = Image.fromarray(depth_visualization)
46
+
47
+ # Create a copy of the original image to store the result
48
+ result = np.copy(image_np)
49
+
50
+ # Apply variable blur based on depth
51
+ for i in range(total_degrade_steps):
52
+ sigma = i * 2 + 1
53
+ print(f'sigma: {sigma}')
54
+
55
+ interval = 0.9 / total_degrade_steps
56
+ closer = 0.9 - (i * interval)
57
+ further = 0.9 - ((i + 1) * interval)
58
+
59
+ mask = (normalized_depth > further) & (normalized_depth <= closer)
60
+ print(f'closer: {closer}, further: {further}')
61
+
62
+ if np.any(mask):
63
+ try: # Apply Gaussian blur with current kernel size
64
+ blurred = cv2.GaussianBlur(image_np, (sigma, sigma), 0)
65
+
66
+ # # Copy blurred pixels to the result where mask is True
67
+ # mask_3d = np.stack([mask, mask, mask], axis=2) if len(image_np.shape) == 3 else mask
68
+ # result = np.where(mask_3d, blurred, result)
69
+
70
+ mask_3d = np.stack([mask, mask, mask], axis=2)
71
+ result[mask_3d] = blurred[mask_3d]
72
+ except Exception as e:
73
+ print(f"Error applying blur with kernel size {sigma}: {e}")
74
+ continue
75
+
76
+ # Convert result back to PIL Image
77
+ result_image = Image.fromarray(result.astype(np.uint8))
78
+ print(f'result_image size {result_image.size}')
79
+
80
+ # # Create side-by-side comparison
81
+ # combined_width = image.width * 2
82
+ # combined_height = image.height
83
+
84
+ # combined_image = Image.new('RGB', (combined_width, combined_height))
85
+ # combined_image.paste(image, (0, 0))
86
+ # combined_image.paste(result_image, (image.width, 0))
87
+
88
+
89
+ return image, result_image
90
+
91
+ # Create Gradio interface
92
+ with gr.Blocks(title="Depth-Based Blur Effect") as demo:
93
+ gr.Markdown("# Depth-Based Blur Effect")
94
+ gr.Markdown("This app applies variable Gaussian blur to images based on depth estimation. Objects farther from the camera appear more blurred, while closer objects remain sharper.")
95
+
96
+ with gr.Row():
97
+ with gr.Column():
98
+ input_image = gr.Image(type="pil", label="Upload Image")
99
+ total_steps = gr.Slider(minimum=5, maximum=20, value=15, step=1, label="Total Blur Levels")
100
+ # show_depth = gr.Checkbox(value=True, label="Show Depth Map")
101
+ submit_btn = gr.Button("Apply Depth-Based Blur")
102
+
103
+ with gr.Column():
104
+ depth_map = gr.Image(type="pil", label="Depth Map") # Added format="png"
105
+ output_image = gr.Image(type="numpy", label="Result (Original | Blurred)")
106
+
107
+ submit_btn.click(
108
+ process_image,
109
+ inputs=[input_image, total_steps],
110
+ outputs=[depth_map, output_image]
111
+ )
112
+
113
+ gr.Examples(
114
+ examples=[
115
+ ["assets/sample.jpg"],
116
+ ],
117
+ inputs=input_image
118
+ )
119
+
120
+ gr.Markdown("""
121
+ ## How it works
122
+
123
+ 1. The app uses the Depth-Anything-V2-Small model to estimate depth in the image
124
+ 2. Depth values are normalized to a range of 0-1
125
+ 3. A variable Gaussian blur is applied based on depth values
126
+ 4. Objects farther from the camera (higher depth values) receive stronger blur
127
+ 5. Objects closer to the camera (lower depth values) remain sharper
128
+
129
+ This creates a realistic depth-of-field effect similar to what's seen in photography.
130
+ """)
131
+
132
+ # Launch the app
133
+ demo.launch()
assets/sample.jpg ADDED

Git LFS Details

  • SHA256: 4cfede9cd5bb71f1c69aa7dffd9c9e7412c14b248a9c8efc2ce4146b98a7b26a
  • Pointer size: 132 Bytes
  • Size of remote file: 3.32 MB
requirements.txt ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ gradio
2
+ torch
3
+ numpy
4
+ opencv-python
5
+ Pillow
6
+ matplotlib
7
+ transformers