phanerozoic commited on
Commit
d4eb5c6
·
0 Parent(s):

Argus demo Space

Browse files
.gitattributes ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ *.7z filter=lfs diff=lfs merge=lfs -text
2
+ *.arrow filter=lfs diff=lfs merge=lfs -text
3
+ *.bin filter=lfs diff=lfs merge=lfs -text
4
+ *.bz2 filter=lfs diff=lfs merge=lfs -text
5
+ *.ckpt filter=lfs diff=lfs merge=lfs -text
6
+ *.ftz filter=lfs diff=lfs merge=lfs -text
7
+ *.gz filter=lfs diff=lfs merge=lfs -text
8
+ *.h5 filter=lfs diff=lfs merge=lfs -text
9
+ *.joblib filter=lfs diff=lfs merge=lfs -text
10
+ *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
+ *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
+ *.model filter=lfs diff=lfs merge=lfs -text
13
+ *.msgpack filter=lfs diff=lfs merge=lfs -text
14
+ *.npy filter=lfs diff=lfs merge=lfs -text
15
+ *.npz filter=lfs diff=lfs merge=lfs -text
16
+ *.onnx filter=lfs diff=lfs merge=lfs -text
17
+ *.ot filter=lfs diff=lfs merge=lfs -text
18
+ *.parquet filter=lfs diff=lfs merge=lfs -text
19
+ *.pb filter=lfs diff=lfs merge=lfs -text
20
+ *.pickle filter=lfs diff=lfs merge=lfs -text
21
+ *.pkl filter=lfs diff=lfs merge=lfs -text
22
+ *.pt filter=lfs diff=lfs merge=lfs -text
23
+ *.pth filter=lfs diff=lfs merge=lfs -text
24
+ *.rar filter=lfs diff=lfs merge=lfs -text
25
+ *.safetensors filter=lfs diff=lfs merge=lfs -text
26
+ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
+ *.tar.* filter=lfs diff=lfs merge=lfs -text
28
+ *.tar filter=lfs diff=lfs merge=lfs -text
29
+ *.tflite filter=lfs diff=lfs merge=lfs -text
30
+ *.tgz filter=lfs diff=lfs merge=lfs -text
31
+ *.wasm filter=lfs diff=lfs merge=lfs -text
32
+ *.xz 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
+ examples/bear.jpg filter=lfs diff=lfs merge=lfs -text
37
+ examples/cat.jpg filter=lfs diff=lfs merge=lfs -text
38
+ examples/skier.jpg filter=lfs diff=lfs merge=lfs -text
39
+ examples/banana.jpg filter=lfs diff=lfs merge=lfs -text
40
+ argus_banner.png filter=lfs diff=lfs merge=lfs -text
41
+ argus_avatar.png filter=lfs diff=lfs merge=lfs -text
README.md ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: Argus
3
+ emoji: 👁
4
+ colorFrom: gray
5
+ colorTo: indigo
6
+ sdk: gradio
7
+ sdk_version: 5.0.0
8
+ python_version: "3.12"
9
+ app_file: app.py
10
+ pinned: false
11
+ license: other
12
+ license_name: fair-research-license
13
+ models:
14
+ - phanerozoic/argus
15
+ ---
16
+
17
+ # Argus
18
+
19
+ Multi-task perception from a single 86-million-parameter backbone. Upload an
20
+ image and Argus produces a top-5 classification, an ADE20K segmentation map,
21
+ a metric depth map, and (with a second image) dense keypoint correspondences,
22
+ all from one forward pass through a frozen EUPE-ViT-B encoder.
23
+
24
+ See the [model card](https://huggingface.co/phanerozoic/argus) for benchmark
25
+ results, training details, and licensing.
app.py ADDED
@@ -0,0 +1,191 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import importlib.util
2
+ import time
3
+
4
+ import gradio as gr
5
+ import numpy as np
6
+ import torch
7
+ from huggingface_hub import hf_hub_download
8
+ from PIL import Image, ImageDraw
9
+
10
+ REPO_ID = "phanerozoic/argus"
11
+
12
+
13
+ def _load_argus():
14
+ argus_py_path = hf_hub_download(repo_id=REPO_ID, filename="argus.py")
15
+ spec = importlib.util.spec_from_file_location("argus_module", argus_py_path)
16
+ mod = importlib.util.module_from_spec(spec)
17
+ spec.loader.exec_module(mod)
18
+ device = "cuda" if torch.cuda.is_available() else "cpu"
19
+ return mod.Argus.from_pretrained(REPO_ID, device=device)
20
+
21
+
22
+ print("Loading Argus...")
23
+ MODEL = _load_argus()
24
+ print(f"Argus ready on {MODEL.device}")
25
+
26
+
27
+ def colorize_segmentation(seg_map: np.ndarray, num_classes: int = 150) -> Image.Image:
28
+ rng = np.random.RandomState(42)
29
+ palette = rng.randint(0, 255, size=(num_classes + 1, 3), dtype=np.uint8)
30
+ palette[0] = [0, 0, 0]
31
+ color = palette[seg_map.astype(np.int64) % (num_classes + 1)]
32
+ return Image.fromarray(color)
33
+
34
+
35
+ def colorize_depth(depth_map: np.ndarray) -> Image.Image:
36
+ d = depth_map - depth_map.min()
37
+ if d.max() > 0:
38
+ d = d / d.max()
39
+ grey = (255 * (1 - d)).astype(np.uint8)
40
+ rgb = np.stack([grey, grey, grey], axis=-1)
41
+ return Image.fromarray(rgb)
42
+
43
+
44
+ def make_overlay(image: Image.Image, mask: Image.Image, alpha: float = 0.55) -> Image.Image:
45
+ base = image.convert("RGB").resize(mask.size)
46
+ return Image.blend(base, mask.convert("RGB"), alpha=alpha)
47
+
48
+
49
+ def perceive(image):
50
+ if image is None:
51
+ return None, None, None, ""
52
+
53
+ image = image.convert("RGB")
54
+ result = MODEL.perceive(image)
55
+
56
+ classification = {
57
+ c["class_name"].split(",")[0]: float(c["score"])
58
+ for c in result["classification"]
59
+ }
60
+
61
+ seg_color = colorize_segmentation(result["segmentation"])
62
+ seg_overlay = make_overlay(image, seg_color, alpha=0.55)
63
+
64
+ depth_img = colorize_depth(result["depth"])
65
+
66
+ t = result["timings_ms"]
67
+ d = result["depth"]
68
+ stats = (
69
+ f"**Inference** classify {t['classify']:.0f} ms · segment {t['segment']:.0f} ms · "
70
+ f"depth {t['depth']:.0f} ms · total {t['total']:.0f} ms \n"
71
+ f"**Depth range** {d.min():.2f} – {d.max():.2f} m"
72
+ )
73
+ return classification, seg_overlay, depth_img, stats
74
+
75
+
76
+ def correspondence(src_image, tgt_image, grid_size: int = 5):
77
+ if src_image is None or tgt_image is None:
78
+ return None, ""
79
+
80
+ src = src_image.convert("RGB")
81
+ tgt = tgt_image.convert("RGB")
82
+ sw, sh = src.size
83
+ tw, th = tgt.size
84
+
85
+ src_pts = []
86
+ for y in range(grid_size):
87
+ for x in range(grid_size):
88
+ src_pts.append([sw * (x + 0.5) / grid_size, sh * (y + 0.5) / grid_size])
89
+
90
+ t0 = time.time()
91
+ pred_pts = MODEL.correspond(src, tgt, src_pts, resolution=512)
92
+ elapsed_ms = (time.time() - t0) * 1000
93
+
94
+ annotated = tgt.copy()
95
+ draw = ImageDraw.Draw(annotated)
96
+ n = len(pred_pts)
97
+ radius = max(6, min(tw, th) // 80)
98
+ for i, (px, py) in enumerate(pred_pts):
99
+ hue = int(255 * i / max(n - 1, 1))
100
+ color = (255, hue, 50)
101
+ draw.ellipse(
102
+ (px - radius, py - radius, px + radius, py + radius),
103
+ fill=color,
104
+ outline="white",
105
+ width=2,
106
+ )
107
+
108
+ stats = f"**Correspondence** matched {n} keypoints in {elapsed_ms:.0f} ms"
109
+ return annotated, stats
110
+
111
+
112
+ HEADER = """
113
+ # Argus
114
+ Multi-task perception from a single 86-million-parameter backbone.
115
+ [model card](https://huggingface.co/phanerozoic/argus)
116
+ """
117
+
118
+ CORRESPONDENCE_NOTE = """
119
+ ## Correspondence
120
+ Upload two images of related objects (the same scene from a different angle, the
121
+ same category but different instance, etc). Argus extracts dense features from
122
+ both, then for each point in a 5×5 grid on the source it finds the best-matching
123
+ point in the target by cosine similarity.
124
+ """
125
+
126
+
127
+ with gr.Blocks(title="Argus", theme=gr.themes.Soft()) as demo:
128
+ gr.Image(
129
+ "argus_banner.png",
130
+ show_label=False,
131
+ show_download_button=False,
132
+ container=False,
133
+ interactive=False,
134
+ height=240,
135
+ )
136
+ gr.Markdown(HEADER)
137
+
138
+ with gr.Row():
139
+ with gr.Column(scale=1):
140
+ input_image = gr.Image(type="pil", label="Input image", height=380)
141
+ gr.Examples(
142
+ examples=[
143
+ ["examples/bear.jpg"],
144
+ ["examples/cat.jpg"],
145
+ ["examples/aircraft.jpg"],
146
+ ["examples/skier.jpg"],
147
+ ["examples/banana.jpg"],
148
+ ],
149
+ inputs=[input_image],
150
+ label="Examples",
151
+ )
152
+ with gr.Column(scale=1):
153
+ classification = gr.Label(
154
+ label="Classification (kNN over ImageNet-1k)",
155
+ num_top_classes=5,
156
+ )
157
+
158
+ with gr.Row():
159
+ seg_output = gr.Image(label="Segmentation (ADE20K, 150 classes)", height=380)
160
+ depth_output = gr.Image(label="Depth (NYU-trained, meters)", height=380)
161
+
162
+ stats_md = gr.Markdown("")
163
+
164
+ input_image.change(
165
+ fn=perceive,
166
+ inputs=[input_image],
167
+ outputs=[classification, seg_output, depth_output, stats_md],
168
+ )
169
+
170
+ gr.Markdown("---")
171
+ gr.Markdown(CORRESPONDENCE_NOTE)
172
+
173
+ with gr.Row():
174
+ corr_src = gr.Image(type="pil", label="Source image", height=380)
175
+ corr_out = gr.Image(label="Target with predicted matches", height=380, interactive=False)
176
+
177
+ with gr.Row():
178
+ corr_tgt = gr.Image(type="pil", label="Target image", height=200)
179
+ corr_btn = gr.Button("Find correspondences", variant="primary")
180
+
181
+ corr_stats = gr.Markdown("")
182
+
183
+ corr_btn.click(
184
+ fn=correspondence,
185
+ inputs=[corr_src, corr_tgt],
186
+ outputs=[corr_out, corr_stats],
187
+ )
188
+
189
+
190
+ if __name__ == "__main__":
191
+ demo.launch()
argus_avatar.png ADDED

Git LFS Details

  • SHA256: caaabc5b507bff7956048751e676fe7f13b440b0c9fc40e380c7e9cf362631bf
  • Pointer size: 132 Bytes
  • Size of remote file: 1.43 MB
argus_banner.png ADDED

Git LFS Details

  • SHA256: ea402aa2a0adf7b8b849a64e8fca3f1f04ebba97de7fc39c5aea3b5260abb6b2
  • Pointer size: 132 Bytes
  • Size of remote file: 2.45 MB
examples/aircraft.jpg ADDED
examples/banana.jpg ADDED

Git LFS Details

  • SHA256: 32455751f0b5d1d7579a2262cd42c9700f057f3d68e0e3384e05d919202e5dc7
  • Pointer size: 131 Bytes
  • Size of remote file: 182 kB
examples/bear.jpg ADDED

Git LFS Details

  • SHA256: 6875cde5e28f56180e4f2ab43f1d893a691cdf86ae147bb0161c84ab1a98f12e
  • Pointer size: 131 Bytes
  • Size of remote file: 248 kB
examples/cat.jpg ADDED

Git LFS Details

  • SHA256: 86ab1dc282970661f745864e656176fc58ab7b170b9594a212ab5b11b7ea62bc
  • Pointer size: 131 Bytes
  • Size of remote file: 158 kB
examples/skier.jpg ADDED

Git LFS Details

  • SHA256: da3112d0adc19a415d1980c9f184f152b267dda609df356775cffc3b2e870b8c
  • Pointer size: 131 Bytes
  • Size of remote file: 145 kB
requirements.txt ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ torch>=2.0.0
2
+ torchvision>=0.15.0
3
+ Pillow>=9.0.0
4
+ numpy>=1.20.0
5
+ huggingface_hub>=0.25.0,<1.0
6
+ gradio>=5.0.0