Sempy32 commited on
Commit
76cb8f0
·
verified ·
1 Parent(s): ebaf5c7

Upload folder using huggingface_hub

Browse files
Files changed (3) hide show
  1. README.md +7 -6
  2. app.py +77 -0
  3. requirements.txt +10 -0
README.md CHANGED
@@ -1,13 +1,14 @@
1
  ---
2
  title: SAM3 Panoptic
3
- emoji: 👁
4
- colorFrom: blue
5
- colorTo: indigo
6
  sdk: gradio
7
- sdk_version: 6.15.2
8
- python_version: '3.12'
9
  app_file: app.py
10
  pinned: false
 
11
  ---
12
 
13
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
1
  ---
2
  title: SAM3 Panoptic
3
+ emoji: 🎯
4
+ colorFrom: indigo
5
+ colorTo: blue
6
  sdk: gradio
7
+ sdk_version: 6.6.0
 
8
  app_file: app.py
9
  pinned: false
10
+ short_description: SAM 3 open-vocabulary panoptic concept segmentation API
11
  ---
12
 
13
+ `api_panoptic(image, concepts, conf)` -> JSON detections with base64-PNG masks.
14
+ Requires the `HF_TOKEN` Space secret to have access to gated `facebook/sam3`.
app.py ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """SAM 3 panoptic concept-segmentation API (ZeroGPU). Self-contained."""
2
+ import base64
3
+ import io
4
+ import os
5
+
6
+ import gradio as gr
7
+ import numpy as np
8
+ import spaces
9
+ import torch
10
+ from PIL import Image
11
+ from transformers import Sam3Model, Sam3Processor
12
+
13
+ HF_TOKEN = os.environ.get("HF_TOKEN")
14
+ MODEL_ID = "facebook/sam3"
15
+
16
+ # Built at import on CPU; moved to CUDA inside the @spaces.GPU function.
17
+ processor = Sam3Processor.from_pretrained(MODEL_ID, token=HF_TOKEN)
18
+ model = Sam3Model.from_pretrained(MODEL_ID, token=HF_TOKEN)
19
+ model.eval()
20
+
21
+
22
+ def _encode_mask(mask_bool: np.ndarray) -> str:
23
+ arr = (mask_bool.astype(np.uint8)) * 255
24
+ buf = io.BytesIO()
25
+ Image.fromarray(arr, mode="L").save(buf, format="PNG")
26
+ return base64.b64encode(buf.getvalue()).decode("ascii")
27
+
28
+
29
+ @spaces.GPU(duration=120)
30
+ def api_panoptic(image, concepts, conf):
31
+ if image is None:
32
+ return {"error": "no image provided"}
33
+ image = image.convert("RGB")
34
+ W, H = image.size
35
+ concept_list = [c.strip() for c in (concepts or "").split(",") if c.strip()]
36
+ device = "cuda"
37
+ model.to(device)
38
+ detections = []
39
+ for concept in concept_list:
40
+ inputs = processor(images=image, text=concept, return_tensors="pt").to(device)
41
+ with torch.no_grad():
42
+ outputs = model(**inputs)
43
+ target_sizes = (inputs["original_sizes"].tolist()
44
+ if "original_sizes" in inputs else [[H, W]])
45
+ res = processor.post_process_instance_segmentation(
46
+ outputs, threshold=float(conf), mask_threshold=0.5,
47
+ target_sizes=target_sizes)[0]
48
+ # NOTE (verify on live Space): expected keys masks/scores/boxes.
49
+ masks, scores = res["masks"], res["scores"]
50
+ boxes = res.get("boxes")
51
+ for i in range(len(scores)):
52
+ m = masks[i]
53
+ m = m.cpu().numpy() if hasattr(m, "cpu") else np.asarray(m)
54
+ mb = m > 0.5 if m.dtype != bool else m
55
+ box = (boxes[i].cpu().numpy().tolist()
56
+ if boxes is not None else [0, 0, 0, 0])
57
+ detections.append({
58
+ "label": concept, "score": float(scores[i]),
59
+ "box": box, "mask_png_b64": _encode_mask(mb.astype(bool)),
60
+ })
61
+ return {"version": "3", "model": MODEL_ID, "width": W, "height": H,
62
+ "detections": detections}
63
+
64
+
65
+ with gr.Blocks(title="SAM3 Panoptic") as demo:
66
+ gr.Markdown("# SAM 3 Panoptic API\nUpload an image, enter comma-separated concepts.")
67
+ with gr.Row():
68
+ inp = gr.Image(type="pil", label="Image")
69
+ out = gr.JSON(label="Detections")
70
+ txt = gr.Textbox(label="Concepts (comma-separated)",
71
+ value="person, car, road, sky, building, tree")
72
+ conf = gr.Slider(0.0, 1.0, value=0.4, step=0.05, label="Confidence")
73
+ gr.Button("Segment").click(api_panoptic, [inp, txt, conf], out,
74
+ api_name="api_panoptic")
75
+
76
+ if __name__ == "__main__":
77
+ demo.queue().launch()
requirements.txt ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ transformers==5.9.0
2
+ torch==2.11.0
3
+ torchvision
4
+ gradio==6.6.0
5
+ spaces
6
+ accelerate
7
+ kernels
8
+ sentencepiece
9
+ pillow
10
+ numpy