Skip to content

mfranzon/speedcam

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

speedcam

output.mp4

Vehicle speed estimation, heatmaps, and traffic flow counting from video — bring your own detector.

speedcam traffic.mp4 --heatmap --flow --export-json report.json

Features

  • Speed estimation — per-vehicle km/h from pixel trajectories, auto-calibrated from known vehicle dimensions or manual scale
  • 3D speed estimation — true 3D velocities using metric depth estimation (Depth Anything V2) for accurate speeds regardless of perspective
  • Speed heatmap — colour overlay showing where vehicles move fast or slow across the scene
  • Traffic flow counting — virtual counting line with directional (up/down) counts per class
  • Multi-object tracking — IoU-based Hungarian-algorithm tracker with trajectory trails
  • SAHI support — sliced inference for detecting small or distant vehicles
  • Analytics export — JSON summary with counts, avg speed, dwell time, per-class breakdown
  • Detector-agnostic — works with RF-DETR (default) or any YOLO model via Ultralytics

Install

# Core library only (no detector)
pip install speedcam

# With RF-DETR detector (recommended)
pip install "speedcam[detection]"

# With 3D depth estimation
pip install "speedcam[detection,depth]"

# With YOLO detector
pip install "speedcam[yolo]"

Requires Python 3.10+ and ffmpeg on PATH for video output.


CLI

speedcam VIDEO [options]

Arguments

Argument Default Description
video Path to input video file
--model rf-detr-base Model name (rf-detr-base, rf-detr-large, or any YOLO model path)
--backend rfdetr Detection backend: rfdetr or yolo
--conf 0.25 Detection confidence threshold
--output output.mp4 Output video path
--scale 0.0 Meters per pixel (0 = auto-calibrate from vehicle sizes)
--depth off Enable 3D depth estimation for accurate speed (requires depth-anything-v2)
--depth-model small Depth model size: small, base, or large
--focal-length 500.0 Camera focal length in pixels (for 3D projection)
--heatmap off Enable speed heatmap overlay
--flow off Enable traffic flow counting line
--flow-line-y 0.5 Counting line vertical position as fraction of frame height (0–1)
--sahi off Enable sliced inference for small/distant objects
--slice-size 640 SAHI slice size in pixels
--overlap 0.25 SAHI slice overlap ratio
--export-json Export analytics summary to a JSON file
--clean off Hide bounding boxes, labels, and HUD panel (trails still shown)
--no-trails off Hide trajectory trails
--no-display off Disable live preview window

Examples

# Basic — RF-DETR, live preview, output video
speedcam highway.mp4

# With heatmap and flow counter, export analytics
speedcam highway.mp4 --heatmap --flow --export-json stats.json

# 3D depth estimation for accurate speeds (perspective-aware)
speedcam highway.mp4 --depth --depth-model small

# Use YOLO, set known scale, no preview
speedcam parking.mp4 --backend yolo --model yolov8n.pt --scale 0.04 --no-display

# Small vehicles far from camera — use SAHI
speedcam aerial.mp4 --sahi --slice-size 512 --overlap 0.3

# Clean output for presentation
speedcam footage.mp4 --clean --no-display --output clean.mp4

Library API

All components are importable directly and can be composed freely around any detector.

import cv2
from speedcam import (
    SpeedEstimator,
    Tracker,
    DepthEstimator,
    FlowCounter,
    SpeedHeatmap,
    Analytics,
    draw_tracks,
    VideoWriter,
    Detection,
)

cap = cv2.VideoCapture("traffic.mp4")
fps = cap.get(cv2.CAP_PROP_FPS)
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

# Optional: 3D depth estimation for accurate speeds
depth_estimator = DepthEstimator(model_size="small", metric=True)

tracker = Tracker(frame_rate=fps, depth_estimator=depth_estimator)
speed_estimator = SpeedEstimator(meters_per_pixel=0.05)  # or 0.0 for auto
analytics = Analytics(fps=fps, speed_estimator=speed_estimator, use_3d=True)
heatmap = SpeedHeatmap(width, height)
flow_counter = FlowCounter(height, line_y_ratio=0.5)
writer = VideoWriter("output.mp4", fps, width, height)

while True:
    ret, frame = cap.read()
    if not ret:
        break

    # Plug in your own detector here — produce sv.Detections
    from supervision import Detections
    detections: Detections = my_detector(frame)

    tracks = tracker.update(detections, frame)
    analytics.update(tracks)

    annotated = draw_tracks(
        frame, tracks, frame_idx=0, fps=fps,
        speed_estimator=speed_estimator,
        heatmap=heatmap,
        flow_counter=flow_counter,
        use_3d=True,
    )
    writer.write(annotated)

cap.release()
writer.release()

analytics.print_summary(tracker.all_tracks)
analytics.export_json(tracker.all_tracks, "report.json")

Detection format

from speedcam import Detection
import numpy as np

det = Detection(
    bbox=np.array([x1, y1, x2, y2], dtype=float),
    score=0.85,
    class_id=2,  # COCO class: 2=car, 3=motorcycle, 5=bus, 7=truck
)

Class IDs

Class YOLO (0-indexed) RF-DETR (1-indexed)
car 2 3
motorcycle 3 4
bus 5 6
truck 7 8

VEHICLE_CLASSES_YOLO and VEHICLE_CLASSES_RFDETR dicts are exported from the package for convenience.


How scale calibration works

When --scale 0 (default), SpeedEstimator estimates meters_per_pixel automatically by observing the pixel width of detected vehicles and comparing to known average lengths (car ≈ 4.5 m, motorcycle ≈ 2.2 m, bus ≈ 12 m, truck ≈ 8 m). The estimate is averaged across all detections seen so far.

For accurate results on perspective or wide-angle cameras, use --depth for 3D speed estimation, or measure a known distance in the scene and pass --scale <value> explicitly.


Analytics JSON output

{
  "total_frames": 1800,
  "total_unique_vehicles": 47,
  "avg_vehicles_per_frame": 3.2,
  "per_class_count": { "car": 38, "truck": 6, "motorcycle": 3 },
  "avg_dwell_time_sec": 4.71,
  "avg_speed_kmh": 52.3,
  "mode": "3d",
  "avg_depth_m": 15.4,
  "meters_per_pixel": 0.0431
}

License

MIT

About

Speedcam is a Python package for vehicle speed estimation, heatmaps, and traffic flow counting.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages