Instructions to use camstack/camstack-trainer with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- ultralytics
How to use camstack/camstack-trainer with ultralytics:
from huggingface_hub import hf_hub_download from ultralytics import YOLO # pick the weights file from this repo's "Files and versions" tab weights = hf_hub_download("camstack/camstack-trainer", "<weights>.pt") model = YOLO(weights) source = 'http://images.cocodataset.org/val2017/000000039769.jpg' model.predict(source=source, save=True) - Notebooks
- Google Colab
- Kaggle
File size: 4,322 Bytes
ebeed67 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | """COCO replay: public images mixed into a detector fine-tune.
A fine-tune on a few thousand frames of ~10 cameras forgets what the COCO head
knew about everything those cameras never show. Mixing a fixed slice of COCO
val2017 back in keeps the 80 classes alive. The slice is pinned: the images of
val2017 that hold at least one person / vehicle / animal, in file-name order,
the first ``count`` of them — the same images on every run.
Nothing here is uploaded by the hub: the container fetches the public files
once into the provider's cache volume (``/cache/coco``) and reuses them. All
80 COCO classes are labelled (the head is kept whole).
``fetch`` is injectable: tests never touch the network.
"""
from __future__ import annotations
import io
import json
import urllib.request
import zipfile
from pathlib import Path
from typing import Callable
from ._vendor.camstack_eval.classes import DETECTOR_CLASSES, macro_of
ANNOTATIONS_URL = "http://images.cocodataset.org/annotations/annotations_trainval2017.zip"
ANNOTATIONS_MEMBER = "annotations/instances_val2017.json"
IMAGE_URL = "http://images.cocodataset.org/val2017/{file}"
Fetch = Callable[[str], bytes]
def http_fetch(url: str) -> bytes:
with urllib.request.urlopen(url, timeout=120) as response: # noqa: S310 (fixed public URLs)
return response.read()
def load_annotations(cache: Path, fetch: Fetch) -> dict:
"""``instances_val2017.json``, fetched once into ``cache``."""
target = cache / "instances_val2017.json"
if not target.is_file():
cache.mkdir(parents=True, exist_ok=True)
archive = zipfile.ZipFile(io.BytesIO(fetch(ANNOTATIONS_URL)))
target.write_bytes(archive.read(ANNOTATIONS_MEMBER))
return json.loads(target.read_text("utf-8"))
def select_images(annotations: dict, count: int) -> list[dict]:
"""The pinned slice: images with a detector-class object, file-name order."""
names = {c["id"]: c["name"] for c in annotations["categories"]}
wanted: set[int] = set()
for a in annotations["annotations"]:
if not a.get("iscrowd") and macro_of(names[a["category_id"]]) in DETECTOR_CLASSES:
wanted.add(a["image_id"])
images = sorted((im for im in annotations["images"] if im["id"] in wanted), key=lambda im: im["file_name"])
return images[:count]
def yolo_lines(annotations: dict, image: dict, coco80: list[str]) -> list[str]:
names = {c["id"]: c["name"] for c in annotations["categories"]}
w, h = float(image["width"]), float(image["height"])
lines = []
for a in annotations["annotations"]:
if a["image_id"] != image["id"] or a.get("iscrowd"):
continue
name = names[a["category_id"]]
if name not in coco80:
continue
x, y, bw, bh = a["bbox"]
if bw <= 0 or bh <= 0:
continue
lines.append(
f"{coco80.index(name)} {(x + bw / 2) / w:.6f} {(y + bh / 2) / h:.6f} {bw / w:.6f} {bh / h:.6f}"
)
return lines
def prepare_replay(count: int, cache: Path, out_root: Path, coco80: list[str], fetch: Fetch = http_fetch) -> int:
"""Write ``count`` replay images + labels under ``out_root/images|labels/replay``."""
if count <= 0:
return 0
annotations = load_annotations(cache, fetch)
images_dir = out_root / "images" / "replay"
labels_dir = out_root / "labels" / "replay"
images_dir.mkdir(parents=True, exist_ok=True)
labels_dir.mkdir(parents=True, exist_ok=True)
by_image: dict[int, list[dict]] = {}
for a in annotations["annotations"]:
by_image.setdefault(a["image_id"], []).append(a)
indexed = {**annotations, "annotations": []}
written = 0
for image in select_images(annotations, count):
cached = cache / "val2017" / image["file_name"]
if not cached.is_file():
cached.parent.mkdir(parents=True, exist_ok=True)
cached.write_bytes(fetch(IMAGE_URL.format(file=image["file_name"])))
stem = Path(image["file_name"]).stem
(images_dir / f"{stem}.jpg").write_bytes(cached.read_bytes())
lines = yolo_lines({**indexed, "annotations": by_image.get(image["id"], [])}, image, coco80)
(labels_dir / f"{stem}.txt").write_text("".join(line + "\n" for line in lines), "utf-8")
written += 1
return written
|