A computer vision system for detecting and analyzing vehicle overtaking events from image sequences. The system combines deep learning-based object detection (RT-DETR) with computer vision tracking (ByteTrack) and geometric analysis for robust passing event validation.
New User? Jump straight to docs/QUICKSTART.md for automated 5-minute setup!
- This Project: MIT License (Copyright 2025 Feng Group)
- RT-DETR Model: Apache 2.0 License (PaddleDetection)
- ByteTrack: MIT License
- All dependencies: Permissive licenses (see docs/THIRD_PARTY_LICENSES.md)
- Python 3.8-3.11 (Python 3.12+ not supported by PaddlePaddle)
- Windows, Linux, or macOS
- 16GB RAM, 64-bit OS recommended
- Vehicle detection using RT-DETR (Real-Time DEtection TRansformer) via ONNX
- Multi-object tracking with ByteTrack
- Real-time visualization and event logging
- Support for multiple camera positions
- CSV export of detected events
- Permissive Apache/MIT license stack
- Jupyter notebook for interactive analysis (
vehicle_pass_tracker_analysis.ipynb)
# Create and activate virtual environment
python -m venv venv
# Windows
.\venv\Scripts\activate
# macOS/Linux
source venv/bin/activate
# Install requirements
pip install -r requirements.txtYou must obtain the RT-DETR ONNX model before running the tracker.
# Windows
.\scripts\download_model.bat
# Linux/macOS
bash scripts/download_model.shDownloads the pre-exported ONNX model (~169MB) from GitHub Releases. No PaddlePaddle installation needed.
For manual export or if download fails:
- See docs/QUICKSTART.md for automated export
- See docs/MODEL_SETUP.md for manual steps
- See docs/KNOWN_ISSUES.md for troubleshooting
Note: Export requires Python 3.8-3.11 with PaddlePaddle
See docs/MODEL_MANAGEMENT.md for model sharing and versioning
# Basic usage (all platforms)
python main.py
# Advanced usage with options (use forward slashes for Windows/macOS/Linux)
python main.py \
--input ./data/my_sequence \
--output ./results \
--mode debug \
--camera-position bottom_center \
--excluded-frames ./data/excluded_frames.csv| Option | Default | Description |
|---|---|---|
| --input | Required | Path to input image sequence folder |
| --output | ./results | Path to output folder |
| --mode | demo | Operation mode (demo/debug) |
| --camera-position | bottom_center | Camera position (bottom_center/bottom_left) |
| --excluded-frames | None | Optional CSV file with frames to exclude |
| --onnx-model | rtdetr.onnx | Path to RT-DETR ONNX model file |
| --no-display | False | Run in headless mode (no visualization window) |
| --output-format | png | Output image format: png (lossless) or jpg (compressed) |
For faster processing without GUI overhead:
python main.py --no-displayUseful for server deployments, batch processing, and remote execution.
- PNG: Lossless, larger files (~2-5MB/frame), best quality
- JPG: Compressed, smaller files (~200-500KB/frame), good quality
Frames are saved asynchronously in a background thread to prevent I/O blocking.
- Format: JPG or PNG
- Naming: frame000000.jpg, frame000001.jpg, etc.
- Resolution: Flexible (tested with IR and GoPro footage)
- Location:
data/input_trip/
For validation:
# ground_truth.csv
frame_number,notes
1500,car_passing
1650,truck_passingtracker = VehiclePassTracker(
image_sequence_path='./data/input_trip/',
output_folder='./results/',
image_source_position='bottom_center', # or 'bottom-left'
)All algorithm parameters are configurable through the TrackerConfig dataclass:
from src.tracker_types import TrackerConfig
config = TrackerConfig(
# Detection parameters
confidence_threshold=0.4, # Minimum confidence for RT-DETR detections (0.0-1.0)
valid_vehicle_classes=[2, 3, 5, 7], # COCO classes: 2=car, 3=motorcycle, 5=bus, 7=truck
# Angle-based filtering (overtaking direction)
min_angle=0.0, # Minimum angle in degrees (default: right half of frame)
max_angle=90.0, # Maximum angle in degrees
min_angle_slope=0.7, # Minimum angle increase rate (deg/frame) for overtaking
min_angle_increase_count=5, # Minimum frames with angle increase (out of history)
angle_trend_threshold=0.5, # Threshold for detecting angle trends (deg/frame)
# Bounding box growth filtering (approaching vehicles)
min_bbox_growth_rate=100.0, # Minimum bbox area growth (px²/frame) - PRIMARY filter
# History and evaluation windows
history_window_size=10, # Frames retained in angle/position history
min_frames_for_evaluation=7, # Minimum frames before evaluating overtaking
probation_frames=2, # Consecutive frames passing checks before yellow box
# Confirmation line positions (fraction of frame width)
confirmation_line_bottom_center=0.85, # For rear-center camera
confirmation_line_bottom_left=0.65, # For rear-left camera
# Event management
cleanup_frames=30, # Frames of inactivity before removing track
buffer_frames=5, # Buffer added to event boundaries
tolerance_threshold=10, # Tolerance for merging overlapping events (frames)
)pass_id,track_id,first_frame,last_frame,vehicle_class,passing_frame,ref_point_distance,passing_angle,bbox_x1,bbox_y1,bbox_x2,bbox_y2
1,145,1500,1530,2,1520,150.5,45.2,100,200,300,400- pass_id: Unique event identifier
- track_id: Internal tracking ID
- first_frame: Event start frame
- last_frame: Event end frame
- vehicle_class: 2=Car, 3=Motorcycle, 5=Bus, 7=Truck
- passing_frame: Frame when vehicle crossed confirmation line
- ref_point_distance: Distance from reference point (pixels)
- passing_angle: Vehicle bearing angle at passing confirmation (degrees)
- bbox_x1, bbox_y1, bbox_x2, bbox_y2: Bounding box coordinates at passing
Auto-saved every 1000 frames with full post-processing applied.
- Red bounding boxes: confirmed passing
- Vehicle class and ID labels
- All frames saved to
output_folder/inference_images/
from src.tracker import VehiclePassTracker
tracker = VehiclePassTracker(
image_sequence_path='./data/my_sequence/',
output_folder='./my_results/'
)
tracker.process_sequence()from src.tracker import VehiclePassTracker
from src.tracker_types import TrackerConfig
config = TrackerConfig(
confidence_threshold=0.5,
min_angle_slope=1.0,
min_bbox_growth_rate=150.0,
probation_frames=3,
valid_vehicle_classes=[2, 3] # Cars and motorcycles only
)
tracker = VehiclePassTracker(
image_sequence_path='./data/my_sequence/',
output_folder='./my_results/',
mode='debug',
image_source_position='bottom_left',
config=config
)
tracker.process_sequence()tracker = VehiclePassTracker(
image_sequence_path='./data/sequence/',
output_folder='./results/',
excluded_frames_path='./data/excluded_frames.csv'
)The algorithm uses 3 core checks for overtaking detection:
- Angle slope - Vehicle moving left->right (direction)
- Angle increases - Consistent trend (jitter-robust)
- Bbox growth - Vehicle approaching (distance)
- Increase
confidence_threshold(0.4 → 0.5-0.6) for fewer false detections - Decrease
confidence_threshold(0.4 → 0.3) for distant vehicles - Default 0.4 is optimized for validation datasets
Stricter detection (fewer false positives):
config = TrackerConfig(
min_angle_slope=1.0,
min_bbox_growth_rate=200.0,
probation_frames=3,
min_frames_for_evaluation=10
)More sensitive detection (catch all overtakes):
config = TrackerConfig(
min_angle_slope=0.5,
min_bbox_growth_rate=50.0,
probation_frames=1,
min_frames_for_evaluation=5
)config = TrackerConfig(
min_angle=0.0,
max_angle=90.0,
confirmation_line_bottom_center=0.85,
confirmation_line_bottom_left=0.65,
)Urban/low-speed environments:
min_bbox_growth_rate: 50-75probation_frames: 3-4history_window_size: 15
Highway/high-speed environments:
min_bbox_growth_rate: 150-200probation_frames: 2history_window_size: 10
Large vehicles only (trucks/buses):
valid_vehicle_classes=[5, 7]
- Check image quality and lighting
- Adjust confidence threshold
- Verify camera position matches configuration
- Increase
min_angle_slope(0.7 -> 1.0) - Increase
min_bbox_growth_rate(100 -> 150-200) - Increase
probation_frames(2 -> 3-4) - Increase
confidence_threshold(0.4 -> 0.5)
- Lower
min_angle_slope(0.7 -> 0.5) - Lower
min_bbox_growth_rate(100 -> 50-75) - Reduce
probation_frames(2 -> 1) - Reduce
confidence_threshold(0.4 -> 0.3) - Check excluded frames
- Enable GPU acceleration when available
- Adjust frame processing rate if needed
- Optimize image resolution for your use case
We welcome contributions! Please see our Contributing Guide for details.
If you use this software in your research, please cite:
This Tracker:
@software{vehicle_overtaking_tracker,
author = {Padmanaban, Gandhimathi and Moustafa, Rayane and Feng, Fred},
title = {Vehicle Overtaking Tracker: An Automated Overtaking Event Detection System},
year = {2025},
publisher = {GitHub},
url = {https://github.com/fenggroup/vehicle-overtaking-tracker.git}
}rtdetr-vot/
├── data/
│ ├── ground_truth_annotations/
│ └── input_trip/
├── docs/
│ ├── ALGORITHM_REFERENCE.md
│ ├── CONTRIBUTING.md
│ ├── KNOWN_ISSUES.md
│ ├── MODEL_MANAGEMENT.md
│ ├── MODEL_SETUP.md
│ ├── QUICKSTART.md
│ └── THIRD_PARTY_LICENSES.md
├── models/
│ └── rtdetr_l/
│ └── model.pdparams
├── results/
│ ├── inference_images/
│ ├── vehicle_passing.csv
│ └── tracking_debug.log
├── scripts/
│ ├── download_rtdetr.bat
│ ├── download_rtdetr.sh
│ └── export_rtdetr_onnx.py
├── src/
│ ├── detectors.py
│ ├── tracker.py
│ ├── tracker_types.py
│ ├── utils.py
│ └── visualization.py
├── LICENSE
├── main.py
├── README.md
├── requirements.txt
└── vehicle_pass_tracker_analysis.ipynb
See docs/MODEL_SETUP.md for model setup issues.
For runtime issues:
- Verify image sequence naming convention
- Confirm camera position matches configuration
- Check input paths are accessible
- Monitor RAM usage for large sequences
- On macOS, grant permissions for protected directories
- Use forward slashes (/) in paths
MIT License - See LICENSE file for details
For issues:
- Check Issues
- Review Troubleshooting section
- Open a new issue with system details and error messages