mandresyandri commited on
Commit
2549bbe
·
verified ·
1 Parent(s): 67e048b

Upload folder using huggingface_hub

Browse files
.claude/settings.local.json ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(file /config/workspace/demo_img/*.tif)",
5
+ "Bash(python3 -c ' *)",
6
+ "Bash(python3 *)",
7
+ "Bash(uv run python -c ' *)",
8
+ "Bash(/config/.local/bin/uv run *)",
9
+ "Bash(git -C /config/workspace remote -v)",
10
+ "Bash(huggingface-cli whoami *)",
11
+ "Bash(git lfs *)",
12
+ "Bash(git remote *)",
13
+ "Bash(git add *)",
14
+ "Bash(git commit *)",
15
+ "Bash(git config *)",
16
+ "Bash(git push *)",
17
+ "Bash(hf auth *)",
18
+ "Bash(git -C /config/workspace add README.md)",
19
+ "Bash(git -C /config/workspace commit -m \"fix: valid HF colorTo value in README\")"
20
+ ]
21
+ }
22
+ }
.gitattributes CHANGED
@@ -33,3 +33,9 @@ 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
+ demo_img/tile_00005.tif filter=lfs diff=lfs merge=lfs -text
37
+ demo_img/tile_00010.tif filter=lfs diff=lfs merge=lfs -text
38
+ demo_img/tile_00049.tif filter=lfs diff=lfs merge=lfs -text
39
+ demo_img/tile_00059.tif filter=lfs diff=lfs merge=lfs -text
40
+ demo_img/tile_00060.tif filter=lfs diff=lfs merge=lfs -text
41
+ demo_img/tile_00065.tif filter=lfs diff=lfs merge=lfs -text
.gitignore ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Python
2
+ __pycache__/
3
+ *.py[oc]
4
+ *.egg-info/
5
+ build/
6
+ dist/
7
+
8
+ # Virtual environments
9
+ .venv/
10
+
11
+ # Local dev tooling
12
+ .python-version
13
+ uv.lock
14
+ pyproject.toml
15
+
16
+ # Gradio
17
+ .gradio/
18
+
19
+ # App outputs
20
+ pedestrian_detection.png
21
+ .claude
.gradio/certificate.pem ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ -----BEGIN CERTIFICATE-----
2
+ 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
31
+ -----END CERTIFICATE-----
README.md CHANGED
@@ -1,12 +1,15 @@
1
  ---
2
- title: Geoimg Sam3 Demo
3
- emoji: 🌖
4
- colorFrom: pink
5
  colorTo: yellow
6
  sdk: gradio
7
- sdk_version: 6.13.0
8
  app_file: app.py
9
  pinned: false
10
  ---
11
 
12
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
1
  ---
2
+ title: SAM3 Pedestrian Crossing Detector
3
+ emoji: 🚶
4
+ colorFrom: red
5
  colorTo: yellow
6
  sdk: gradio
7
+ sdk_version: 5.29.0
8
  app_file: app.py
9
  pinned: false
10
  ---
11
 
12
+ # SAM3 — Détection de passages piétons
13
+
14
+ Détecte et surligne les **passages piétons** (zebra crossing / crosswalk) par segmentation guidée par texte avec [SAM3](https://huggingface.co/facebook/sam3).
15
+
app.py ADDED
@@ -0,0 +1,155 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import torch
3
+ import numpy as np
4
+ from PIL import Image, ImageDraw, ImageFilter
5
+ from transformers import Sam3Processor, Sam3Model
6
+ import os
7
+
8
+ DEMO_IMAGES = sorted([f"demo_img/{f}" for f in os.listdir("demo_img") if f.endswith(".tif")])
9
+
10
+ OVERLAY_COLOR = (255, 50, 50)
11
+
12
+
13
+ class Sam3PedestrianDetector:
14
+ def __init__(self):
15
+ self.device = "cuda" if torch.cuda.is_available() else "cpu"
16
+ self.model = None
17
+ self.processor = None
18
+ print(f"Initializing SAM3 on {self.device}")
19
+ try:
20
+ self.model = Sam3Model.from_pretrained("facebook/sam3").to(self.device)
21
+ self.processor = Sam3Processor.from_pretrained("facebook/sam3")
22
+ print("SAM3 loaded successfully.")
23
+ except Exception as e:
24
+ print(f"Error loading SAM3: {e}")
25
+
26
+ def predict_masks(self, image_pil, text_prompt, threshold=0.35):
27
+ if self.model is None:
28
+ return []
29
+ inputs = self.processor(
30
+ images=image_pil,
31
+ text=text_prompt,
32
+ return_tensors="pt"
33
+ ).to(self.device)
34
+ with torch.no_grad():
35
+ outputs = self.model(**inputs)
36
+ results = self.processor.post_process_instance_segmentation(
37
+ outputs,
38
+ threshold=threshold,
39
+ mask_threshold=0.5,
40
+ target_sizes=inputs["original_sizes"].tolist()
41
+ )[0]
42
+ masks = []
43
+ if "masks" in results:
44
+ for mask_tensor in results["masks"]:
45
+ mask_np = (mask_tensor.cpu().numpy() * 255).astype(np.uint8)
46
+ masks.append(Image.fromarray(mask_np))
47
+ return masks
48
+
49
+
50
+ engine = Sam3PedestrianDetector()
51
+
52
+
53
+ def draw_overlay(image_pil, masks, color_rgb, opacity):
54
+ """Semi-transparent colored fill over each detected mask."""
55
+ result = image_pil.copy().convert("RGBA")
56
+ overlay = Image.new("RGBA", image_pil.size, (0, 0, 0, 0))
57
+ alpha = int(opacity * 255)
58
+ r, g, b = color_rgb
59
+ for mask in masks:
60
+ fill = Image.new("RGBA", image_pil.size, (r, g, b, alpha))
61
+ overlay.paste(fill, mask=mask)
62
+ return Image.alpha_composite(result, overlay).convert("RGB")
63
+
64
+
65
+ def draw_contours(image_pil, masks, color_rgb=(255, 50, 0)):
66
+ """Draw a 3-pixel contour border around each mask."""
67
+ result = image_pil.copy()
68
+ for mask in masks:
69
+ eroded = mask.filter(ImageFilter.MinFilter(5))
70
+ contour = np.clip(
71
+ np.array(mask).astype(int) - np.array(eroded).astype(int), 0, 255
72
+ ).astype(np.uint8)
73
+ contour_pil = Image.fromarray(contour)
74
+ color_layer = Image.new("RGB", image_pil.size, color_rgb)
75
+ result.paste(color_layer, mask=contour_pil)
76
+ return result
77
+
78
+
79
+ def compute_stats(masks, image_pil):
80
+ w, h = image_pil.size
81
+ total_pixels = w * h
82
+ covered = np.zeros((h, w), dtype=bool)
83
+ areas = []
84
+ for mask in masks:
85
+ mask_np = np.array(mask) > 127
86
+ areas.append(int(mask_np.sum()))
87
+ covered |= mask_np
88
+ coverage_pct = round(100.0 * covered.sum() / total_pixels, 2)
89
+ return {"count": len(masks), "areas": areas, "coverage_pct": coverage_pct}
90
+
91
+
92
+ def format_stats(stats):
93
+ lines = [f"**Passages piétons détectés : {stats['count']}**"]
94
+ lines.append(f"Couverture totale : **{stats['coverage_pct']}%** de l'image")
95
+ for i, area in enumerate(stats["areas"]):
96
+ lines.append(f"- Passage #{i+1} : {area:,} px")
97
+ return "\n\n".join(lines)
98
+
99
+
100
+ def process_image(input_img, text_prompt, confidence, opacity):
101
+ if input_img is None:
102
+ return None, None, "Aucune image fournie."
103
+ if isinstance(input_img, np.ndarray):
104
+ image_pil = Image.fromarray(input_img).convert("RGB")
105
+ else:
106
+ image_pil = input_img.convert("RGB")
107
+
108
+ masks = engine.predict_masks(image_pil, text_prompt, confidence)
109
+
110
+ result = draw_overlay(image_pil, masks, OVERLAY_COLOR, opacity)
111
+ result = draw_contours(result, masks, OVERLAY_COLOR)
112
+
113
+ stats = compute_stats(masks, image_pil)
114
+ output_path = "pedestrian_detection.png"
115
+ result.save(output_path)
116
+
117
+ return np.array(result), output_path, format_stats(stats)
118
+
119
+
120
+
121
+ with gr.Blocks(title="SAM3 — Détection de passages piétons", theme=gr.themes.Soft()) as demo:
122
+ gr.Markdown("# SAM3 — Détection de passages piétons")
123
+ gr.Markdown(
124
+ "Détecte et surligne les **passages piétons** (zebra crossing / crosswalk) "
125
+ "par segmentation guidée par texte avec SAM3."
126
+ )
127
+
128
+ with gr.Row():
129
+ with gr.Column():
130
+ im_input = gr.Image(label="Image d'entrée", type="numpy")
131
+ im_prompt = gr.Textbox(
132
+ label="Prompt texte",
133
+ value="pedestrian crossing",
134
+ info="Exemples : 'zebra crossing', 'crosswalk', 'pedestrian crossing'"
135
+ )
136
+ im_conf = gr.Slider(0.1, 1.0, value=0.35, step=0.05, label="Seuil de confiance")
137
+ im_opacity = gr.Slider(0.1, 1.0, value=0.45, step=0.05, label="Opacité de l'overlay")
138
+ with gr.Column():
139
+ im_output = gr.Image(label="Résultat")
140
+ im_stats = gr.Markdown()
141
+ im_dl = gr.File(label="Télécharger l'image")
142
+
143
+ gr.Examples(
144
+ examples=DEMO_IMAGES,
145
+ inputs=im_input,
146
+ label="Images de démonstration (demo_img/)"
147
+ )
148
+
149
+ im_input.change(
150
+ process_image,
151
+ [im_input, im_prompt, im_conf, im_opacity],
152
+ [im_output, im_dl, im_stats]
153
+ )
154
+
155
+ demo.launch()
demo_img/tile_00005.tif ADDED

Git LFS Details

  • SHA256: 4782cc6de6a0bede5e652b7c6f9c900b57c81b8d4483ddef2fd1a5cb0ac6a071
  • Pointer size: 131 Bytes
  • Size of remote file: 787 kB
demo_img/tile_00010.tif ADDED

Git LFS Details

  • SHA256: 82b28c90ffc77acd2ce7ce11c877ebdd91e5cb6c29980d5428418e559103bc0e
  • Pointer size: 131 Bytes
  • Size of remote file: 787 kB
demo_img/tile_00049.tif ADDED

Git LFS Details

  • SHA256: 4f346e039c756d436aeeddf26649d3907af755db4bc97296803b8fd2d1ba0fbc
  • Pointer size: 131 Bytes
  • Size of remote file: 787 kB
demo_img/tile_00059.tif ADDED

Git LFS Details

  • SHA256: c97ba10fc6a656cc7772992e358e4e7c5b61fb95bb64ff01064e3bb8429b3c90
  • Pointer size: 131 Bytes
  • Size of remote file: 787 kB
demo_img/tile_00060.tif ADDED

Git LFS Details

  • SHA256: b70a48a1a42f4f89a737fbc7c38eed2ffd687315f3f9ceec3ce496ac5a7a566a
  • Pointer size: 131 Bytes
  • Size of remote file: 787 kB
demo_img/tile_00065.tif ADDED

Git LFS Details

  • SHA256: 510febdaf9663c4323a9d5e5f84a8215c43cb13b0d2c826ad97fb469e497b126
  • Pointer size: 131 Bytes
  • Size of remote file: 787 kB
requirements.txt ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ accelerate>=1.13.0
2
+ gradio>=6.13.0
3
+ numpy>=2.4.4
4
+ pillow>=12.2.0
5
+ torch>=2.11.0
6
+ torchvision>=0.26.0
7
+ git+https://github.com/huggingface/transformers.git