Spaces:
Paused
title: VAR - RFDETR
emoji: π₯
colorFrom: purple
colorTo: blue
sdk: docker
app_port: 7860
pinned: false
VAR - RFDETR β Offside Visualizer
RF-DETR variant: detection uses Roboflow's RF-DETR-Seg (large) with a toggle between bounding boxes and segments. Upload a match clip, scrub to the moment the ball is played, reconstruct selected players in 3D with SAM 3D Body, and place them on a virtual pitch with a draggable offside plane.
Pipeline
- Upload a video clip.
- Scrub to the offside frame (slider + prev/next, frames seeked on demand).
- Detect players on that frame β the only GPU step, cached per (video, frame, threshold).
- Select the players to analyze and mark the defenders (incl. GK).
- Click two goal-parallel lines (4 points) on the detected frame to fix the offside axis.
- Build the 3D scene; drag the offside plane and read the OFFSIDE / NO-OFFSIDE verdict.
The GPU runs once per frame (pipeline/gpu.py). Scrubbing, line geometry,
placement, plotting, and the draggable plane are all CPU on the cached result.
Code layout
app.py Gradio UI + event wiring (CPU)
pipeline/
video.py frame seek/probe (CPU)
gpu.py model load + reconstruct_frame β the ONLY GPU code
geometry.py vanishing point, ground fit, field frame, scene (CPU)
overlay.py detection boxes + line-click drawing (CPU)
Isolating the GPU in pipeline/gpu.py means moving inference to a serverless
backend (Modal / ZeroGPU) later only touches reconstruct_frame.
Deploy
This is a Docker SDK Space for dedicated GPU hardware (A100 recommended):
- Set hardware to an A100 tier.
- Add a secret
HF_TOKENβ a read token for an account with approved access to the gatedfacebook/sam-3d-body-dinov3. (Override the repo with theSAM3D_REPO_IDenv var if you use a different checkpoint.) - First boot builds the image and downloads ~7 GB of weights β give it time. After that, the model stays warm until you pause the Space.
Cost control: dedicated GPU bills while the Space is running, with no auto-shutoff. Pause the Space from its settings when you are not using it.
Why not ZeroGPU?
ZeroGPU allocates the GPU per call, caps call duration, enforces a daily quota, and cold-loads the ~7 GB model stack on each allocation β a poor fit for an interactive video-scrubbing session, and it requires the Gradio SDK (not Docker).
Notes / limits
- Scale comes from the reconstructed body height, so positions are approximate metres β good for relative offside ordering, not sub-10 cm officiating calls. The verdict surfaces a "too close to call" band rather than implying false precision.
- The offside point currently uses the forward-most body vertex including arms;
excluding arms (via MHR body-part labels) is planned β see
TODO.md. - "Find the offside moment" is manual scrubbing; automatic pass-instant detection (ball tracking) is future work.