lukemelas commited on
Commit
94e6f4c
1 Parent(s): 6c04cab

Update with description and CRF

Browse files
Files changed (2) hide show
  1. app.py +46 -5
  2. 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' # TODOL Figure out how to make this user-editable
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 = "Deep spectral segmentation (add description here) ..."
 
 
 
 
 
 
 
 
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