MTerryJack commited on
Commit
0bd4bcf
·
verified ·
1 Parent(s): bf36f56

Upload 9 files

Browse files
Files changed (9) hide show
  1. README.md +13 -0
  2. best.pt +3 -0
  3. element.yaml +3 -0
  4. entrypoint.py +82 -0
  5. example.jpg +0 -0
  6. pyproject.toml +8 -0
  7. sample_input.json +6 -0
  8. sample_output.json +62 -0
  9. uv.lock +0 -0
README.md ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Example Element Repo
2
+
3
+ This is a minimal Hugging Face-style Element repo.
4
+
5
+ ## Run
6
+
7
+ ```bash
8
+ uv run python entrypoint.py < sample_input.json
9
+ ```
10
+
11
+ ## Output
12
+
13
+ The entrypoint runs the YOLOv8 model in `best.pt` against the input frames and returns Detect output.
best.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:482f0782bc283651ff8365612c01097b4ab4ff3974d103ab03fd3b4b166456ac
3
+ size 6249194
element.yaml ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version: 0.1.0
2
+ element_type: Detect
3
+ entrypoint: entrypoint.py
entrypoint.py ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ import sys
3
+ from io import BytesIO
4
+ from pathlib import Path
5
+ from typing import Any, Dict, List
6
+
7
+ import requests
8
+ from PIL import Image
9
+ from ultralytics import YOLO
10
+
11
+
12
+ def load_image(frame: str, base_dir: Path) -> Image.Image:
13
+ if frame.startswith("http://") or frame.startswith("https://"):
14
+ response = requests.get(frame, timeout=30)
15
+ response.raise_for_status()
16
+ return Image.open(BytesIO(response.content)).convert("RGB")
17
+
18
+ path = Path(frame)
19
+ if not path.is_absolute():
20
+ path = (Path.cwd() / path).resolve()
21
+ if not path.exists():
22
+ candidate = (base_dir / frame).resolve()
23
+ if candidate.exists():
24
+ path = candidate
25
+ return Image.open(path).convert("RGB")
26
+
27
+
28
+ def detect(model: YOLO, image: Image.Image, frame_idx: int) -> List[Dict[str, Any]]:
29
+ results = model(image)
30
+ detections: List[Dict[str, Any]] = []
31
+ result = results[0]
32
+ names = result.names or model.names
33
+
34
+ for det_idx, box in enumerate(result.boxes):
35
+ xyxy = box.xyxy[0].tolist()
36
+ class_id = int(box.cls[0].item())
37
+ detections.append(
38
+ {
39
+ "frame_idx": frame_idx,
40
+ "class": names.get(class_id, str(class_id)),
41
+ "bbox": [float(x) for x in xyxy],
42
+ "score": float(box.conf[0].item()),
43
+ "track_id": f"f{frame_idx}-d{det_idx}",
44
+ }
45
+ )
46
+
47
+ return detections
48
+
49
+
50
+ def main() -> None:
51
+ raw = sys.stdin.read().strip()
52
+ if not raw:
53
+ print("[]")
54
+ return
55
+ try:
56
+ payload = json.loads(raw)
57
+ except json.JSONDecodeError:
58
+ print("[]")
59
+ return
60
+
61
+ base_dir = Path(__file__).resolve().parent
62
+ model_path = base_dir / "best.pt"
63
+ if not model_path.exists():
64
+ print("[]")
65
+ return
66
+
67
+ model = YOLO(str(model_path))
68
+ frames = payload.get("frames", [])
69
+ output: List[Dict[str, Any]] = []
70
+
71
+ for frame_idx, frame in enumerate(frames):
72
+ try:
73
+ image = load_image(frame, base_dir)
74
+ except Exception:
75
+ continue
76
+ output.extend(detect(model, image, frame_idx))
77
+
78
+ print(json.dumps(output))
79
+
80
+
81
+ if __name__ == "__main__":
82
+ main()
example.jpg ADDED
pyproject.toml ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ [project]
2
+ name = "vehicle-detect-element"
3
+ version = "0.1.0"
4
+ requires-python = ">=3.11"
5
+ dependencies = [
6
+ "requests>=2.31.0",
7
+ "ultralytics>=8.0.0",
8
+ ]
sample_input.json ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ {
2
+ "clip_id": "sha256:example",
3
+ "fps": 5,
4
+ "frames": ["example.jpg"],
5
+ "ts_start_ms": 1234567890
6
+ }
sample_output.json ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {
3
+ "frame_idx": 0,
4
+ "class": "car",
5
+ "bbox": [
6
+ 272.696044921875,
7
+ 238.8153839111328,
8
+ 304.9505615234375,
9
+ 284.86334228515625
10
+ ],
11
+ "score": 0.7260516881942749,
12
+ "track_id": "f0-d0"
13
+ },
14
+ {
15
+ "frame_idx": 0,
16
+ "class": "car",
17
+ "bbox": [
18
+ 317.4508056640625,
19
+ 249.2779083251953,
20
+ 351.03350830078125,
21
+ 295.40264892578125
22
+ ],
23
+ "score": 0.6707994937896729,
24
+ "track_id": "f0-d1"
25
+ },
26
+ {
27
+ "frame_idx": 0,
28
+ "class": "car",
29
+ "bbox": [
30
+ 404.1763610839844,
31
+ 279.63201904296875,
32
+ 470.1379089355469,
33
+ 345.353759765625
34
+ ],
35
+ "score": 0.3774946928024292,
36
+ "track_id": "f0-d2"
37
+ },
38
+ {
39
+ "frame_idx": 0,
40
+ "class": "car",
41
+ "bbox": [
42
+ 360.1339416503906,
43
+ 231.34637451171875,
44
+ 396.8412170410156,
45
+ 269.111328125
46
+ ],
47
+ "score": 0.33625954389572144,
48
+ "track_id": "f0-d3"
49
+ },
50
+ {
51
+ "frame_idx": 0,
52
+ "class": "bus",
53
+ "bbox": [
54
+ 337.4912414550781,
55
+ 277.13092041015625,
56
+ 395.4140930175781,
57
+ 351.0
58
+ ],
59
+ "score": 0.3119567632675171,
60
+ "track_id": "f0-d4"
61
+ }
62
+ ]
uv.lock ADDED
The diff for this file is too large to render. See raw diff