Spaces:
Runtime error
Runtime error
Update with description and CRF
Browse files- app.py +46 -5
- requirements.txt +2 -1
app.py
CHANGED
@@ -1,4 +1,6 @@
|
|
|
|
1 |
import io
|
|
|
2 |
|
3 |
import gradio as gr
|
4 |
import matplotlib.pyplot as plt
|
@@ -9,12 +11,12 @@ import torch.nn.functional as F
|
|
9 |
import torchvision.transforms.functional as TF
|
10 |
from gradio.inputs import Image as GradioInputImage
|
11 |
from gradio.outputs import Image as GradioOutputImage
|
|
|
12 |
from PIL import Image
|
13 |
from scipy.sparse.linalg import eigsh
|
14 |
from torch.utils.hooks import RemovableHandle
|
15 |
from torchvision import transforms
|
16 |
from torchvision.utils import make_grid
|
17 |
-
from matplotlib.pyplot import get_cmap
|
18 |
|
19 |
|
20 |
def get_model(name: str):
|
@@ -60,7 +62,7 @@ def get_diagonal(W: scipy.sparse.csr_matrix, threshold: float = 1e-12):
|
|
60 |
|
61 |
|
62 |
# Parameters
|
63 |
-
model_name = 'dino_vitb16' #
|
64 |
K = 5
|
65 |
|
66 |
# Fixed parameters
|
@@ -160,6 +162,7 @@ def segment(inp: Image):
|
|
160 |
# Arrange eigenvectors into grid
|
161 |
cmap = get_cmap('viridis')
|
162 |
output_images = []
|
|
|
163 |
for i in range(1, K + 1):
|
164 |
eigenvector = eigenvectors[i].reshape(1, 1, H_patch, W_patch) # .reshape(1, 1, H_pad, W_pad)
|
165 |
eigenvector: torch.Tensor = F.interpolate(eigenvector, size=(H_pad, W_pad), mode='bilinear', align_corners=False) # slightly off, but for visualizations this is okay
|
@@ -169,10 +172,40 @@ def segment(inp: Image):
|
|
169 |
eigenvector_vis = Image.open(buffer).convert('RGB')
|
170 |
# eigenvector_vis = TF.to_tensor(eigenvector_vis).unsqueeze(0)
|
171 |
eigenvector_vis = np.array(eigenvector_vis)
|
|
|
172 |
output_images.append(eigenvector_vis)
|
173 |
# output_images = torch.cat(output_images, dim=0)
|
174 |
# output_images = make_grid(output_images, nrow=8, pad_value=1)
|
175 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
176 |
# # Postprocess for Gradio
|
177 |
# output_images = np.array(TF.to_pil_image(output_images))
|
178 |
print(f'{len(output_images)=}')
|
@@ -181,15 +214,23 @@ def segment(inp: Image):
|
|
181 |
# Placeholders
|
182 |
input_placeholders = GradioInputImage(source="upload", tool="editor", type="pil")
|
183 |
# output_placeholders = GradioOutputImage(type="numpy", label=f"Eigenvectors")
|
184 |
-
output_placeholders = [GradioOutputImage(type="numpy", label=f"Eigenvector {i}") for i in range(K)]
|
185 |
|
186 |
# Metadata
|
187 |
examples = [f"examples/{stem}.jpg" for stem in [
|
188 |
'2008_000099', '2008_000499', '2007_009446', '2007_001586', '2010_001256', '2008_000764', '2008_000705', # '2007_000039'
|
189 |
]]
|
190 |
|
191 |
-
title = "Deep Spectral Segmentation"
|
192 |
-
description = "
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
193 |
thumbnail = "https://raw.githubusercontent.com/gradio-app/hub-echonet/master/thumbnail.png"
|
194 |
|
195 |
# Gradio
|
|
|
1 |
+
from collections import namedtuple
|
2 |
import io
|
3 |
+
from typing import Tuple
|
4 |
|
5 |
import gradio as gr
|
6 |
import matplotlib.pyplot as plt
|
|
|
11 |
import torchvision.transforms.functional as TF
|
12 |
from gradio.inputs import Image as GradioInputImage
|
13 |
from gradio.outputs import Image as GradioOutputImage
|
14 |
+
from matplotlib.pyplot import get_cmap
|
15 |
from PIL import Image
|
16 |
from scipy.sparse.linalg import eigsh
|
17 |
from torch.utils.hooks import RemovableHandle
|
18 |
from torchvision import transforms
|
19 |
from torchvision.utils import make_grid
|
|
|
20 |
|
21 |
|
22 |
def get_model(name: str):
|
|
|
62 |
|
63 |
|
64 |
# Parameters
|
65 |
+
model_name = 'dino_vitb16' # TODO: Figure out how to make this user-editable
|
66 |
K = 5
|
67 |
|
68 |
# Fixed parameters
|
|
|
162 |
# Arrange eigenvectors into grid
|
163 |
cmap = get_cmap('viridis')
|
164 |
output_images = []
|
165 |
+
eigenvectors_upscaled = []
|
166 |
for i in range(1, K + 1):
|
167 |
eigenvector = eigenvectors[i].reshape(1, 1, H_patch, W_patch) # .reshape(1, 1, H_pad, W_pad)
|
168 |
eigenvector: torch.Tensor = F.interpolate(eigenvector, size=(H_pad, W_pad), mode='bilinear', align_corners=False) # slightly off, but for visualizations this is okay
|
|
|
172 |
eigenvector_vis = Image.open(buffer).convert('RGB')
|
173 |
# eigenvector_vis = TF.to_tensor(eigenvector_vis).unsqueeze(0)
|
174 |
eigenvector_vis = np.array(eigenvector_vis)
|
175 |
+
eigenvectors_upscaled.append(eigenvector)
|
176 |
output_images.append(eigenvector_vis)
|
177 |
# output_images = torch.cat(output_images, dim=0)
|
178 |
# output_images = make_grid(output_images, nrow=8, pad_value=1)
|
179 |
|
180 |
+
# Also add CRF
|
181 |
+
if False:
|
182 |
+
|
183 |
+
# Imports
|
184 |
+
import denseCRF
|
185 |
+
|
186 |
+
# Parameters
|
187 |
+
ParamsCRF = namedtuple('ParamsCRF', 'w1 alpha beta w2 gamma it')
|
188 |
+
DEFAULT_CRF_PARAMS = ParamsCRF(
|
189 |
+
w1 = 6, # weight of bilateral term # 10.0,
|
190 |
+
alpha = 40, # spatial std # 80,
|
191 |
+
beta = 13, # rgb std # 13,
|
192 |
+
w2 = 3, # weight of spatial term # 3.0,
|
193 |
+
gamma = 3, # spatial std # 3,
|
194 |
+
it = 5.0, # iteration # 5.0,
|
195 |
+
)
|
196 |
+
|
197 |
+
# Get unary potentials
|
198 |
+
unary_potentials = eigenvectors_upscaled[0].squeeze(1).squeeze(0)
|
199 |
+
unary_potentials = (unary_potentials - unary_potentials.min()) / (unary_potentials.max() - unary_potentials.min())
|
200 |
+
unary_potentials_np = torch.stack((1 - unary_potentials, unary_potentials), dim=-1).cpu().numpy()
|
201 |
+
img_np = images.cpu().numpy().transpose(0, 2, 3, 1)
|
202 |
+
img_np = (img_np * 255).astype(np.uint8)[0]
|
203 |
+
|
204 |
+
# Return result of CRF
|
205 |
+
out = denseCRF.densecrf(img_np, unary_potentials_np, DEFAULT_CRF_PARAMS)
|
206 |
+
out = out * 255
|
207 |
+
output_images.append(out)
|
208 |
+
|
209 |
# # Postprocess for Gradio
|
210 |
# output_images = np.array(TF.to_pil_image(output_images))
|
211 |
print(f'{len(output_images)=}')
|
|
|
214 |
# Placeholders
|
215 |
input_placeholders = GradioInputImage(source="upload", tool="editor", type="pil")
|
216 |
# output_placeholders = GradioOutputImage(type="numpy", label=f"Eigenvectors")
|
217 |
+
output_placeholders = [GradioOutputImage(type="numpy", label=(f"Eigenvector {i}")) for i in range(K)]
|
218 |
|
219 |
# Metadata
|
220 |
examples = [f"examples/{stem}.jpg" for stem in [
|
221 |
'2008_000099', '2008_000499', '2007_009446', '2007_001586', '2010_001256', '2008_000764', '2008_000705', # '2007_000039'
|
222 |
]]
|
223 |
|
224 |
+
title = "Demo: Deep Spectral Methods for Unsupervised Localization and Segmentation"
|
225 |
+
description = """
|
226 |
+
This is a demo of <a href="https://lukemelas.github.io/deep-spectral-segmentation/">Deep Spectral Methods: A Surprisingly Strong Baseline for Unsupervised Semantic Segmentation and Localization
|
227 |
+
</a> (CVPR 2022 Oral).
|
228 |
+
|
229 |
+
Our method decomposes an image into a set of soft segments in a <em>completely unsupervised</em> manner. Specifically, we extract the Laplacian eigenvectors of a feature affinity matrix from a large self-supervised network, and we find that we find that these eigenvectors can be readily used to localize and segment objects.
|
230 |
+
|
231 |
+
Below, you can upload an image (or select one of the examples) and see how our method decomposes it into soft segments. Hopefully it will localize some of the objects or semantic segments in your image!
|
232 |
+
"""
|
233 |
+
|
234 |
thumbnail = "https://raw.githubusercontent.com/gradio-app/hub-echonet/master/thumbnail.png"
|
235 |
|
236 |
# Gradio
|
requirements.txt
CHANGED
@@ -3,4 +3,5 @@ numpy
|
|
3 |
matplotlib
|
4 |
torch==1.9.1+cpu
|
5 |
torchvision==0.10.1+cpu
|
6 |
-
scipy
|
|
|
|
3 |
matplotlib
|
4 |
torch==1.9.1+cpu
|
5 |
torchvision==0.10.1+cpu
|
6 |
+
scipy
|
7 |
+
# SimpleCRF
|