A Python application for processing RTSP camera streams to detect vehicles and recognize license plates.
- Process RTSP camera streams
- Vehicle detection using YOLOv8
- License plate detection using a pre-trained YOLOv8 model
- License plate recognition using fast-plate-ocr with European plate models
- GPU acceleration for both detection and recognition (CUDA support)
- Fast processing with optimized preprocessing pipeline
- Groups multiple images of the same vehicle to improve recognition accuracy
- Stores vehicle images and plate information in SQLite database
- Near real-time Telegram notifications with best vehicle images
- Automatic cleanup of processed records to manage disk space
- Python 3.13
- OpenCV
- PyTorch
- Ultralytics YOLOv8
- fast-plate-ocr
- PyAV
- Python-Telegram-Bot
-
Clone the repository
git clone https://github.com/yourusername/safewheels.git cd safewheels -
Install Python dependencies
pip install -r requirements.txtThis will install all necessary Python packages for vehicle detection, license plate recognition, and notifications.
Edit the configuration file at config/config.json:
{
"rtsp_url": "rtsp://your-camera-ip:port/stream",
"rtsp_username": "username",
"rtsp_password": "password",
"vehicle_confidence_threshold": 0.4,
"plate_detection_threshold": 0.3,
"ocr_confidence_threshold": 0.2,
"process_every_n_frames": 10,
"storage_path": "data/vehicles",
"vehicle_id_threshold_sec": 5,
"db_filename": "detections.db",
"images_dirname": "images",
"check_interval_sec": 5,
"telegram_token": "",
"authorized_users": [
123456789,
987654321
],
"timestamp_file": "last_processed.txt",
"use_gpu": true,
"model_precision": "fp16",
"cuda_device": 0
}Key configuration parameters:
rtsp_url: URL of your RTSP camera streamrtsp_usernameandrtsp_password: Credentials for your RTSP stream (if required)vehicle_confidence_threshold: Minimum confidence for vehicle detection (0.0-1.0)plate_detection_threshold: Minimum confidence for license plate detection (0.0-1.0)ocr_confidence_threshold: Minimum confidence for OCR recognition (0.0-1.0)process_every_n_frames: Process every Nth frame from video streams for efficiencyvehicle_id_threshold_sec: Time threshold to consider a vehicle as complete/uniquedb_filename: Name of the SQLite database file for storing detectionscheck_interval_sec: How often to check for new completed vehicles (for notifications)authorized_users: Array of Telegram user IDs authorized to receive notificationstimestamp_file: File to store the timestamp of last processed detection (for persistence across restarts)use_gpu: Whether to use GPU acceleration (true/false)model_precision: Model precision to use ('fp32' or 'fp16' for faster CUDA processing)cuda_device: CUDA device ID to use (0 for primary GPU)
Run the application using the RTSP URL defined in the config:
python -m safewheels.scripts.watch_and_detect --config config/config.json
You can specify a custom configuration file path:
python -m safewheels.scripts.watch_and_detect --config /path/to/custom/config.json
Detected vehicles and license plates are stored in the configured storage_path, including:
- Vehicle images in the specified
images_dirnamedirectory - SQLite database (
db_filename) with detection records and metadata
SafeWheels includes several utility scripts to help with monitoring, recognition, and system maintenance.
The watch_and_detect.py script continuously monitors a video stream for vehicle detections:
python -m safewheels.scripts.watch_and_detect --config config/config.jsonThe recognize_and_notify.py script processes detected vehicles, recognizes license plates, and sends notifications:
python -m safewheels.scripts.recognize_and_notify --config config/config.jsonThe script periodically checks the database at the interval specified by check_interval_sec:
- It identifies vehicles that haven't been detected for at least
vehicle_id_threshold_secseconds (considered "completed") - For each completed vehicle not already processed, it selects the best image based on confidence scores
- It recognizes license plates from the detected plate areas
- The selected image is sent to all authorized Telegram users with relevant details
- The script tracks the last processed timestamp and saves it to the file specified by
timestamp_fileto avoid duplicate notifications
The cleanup_processed.py script helps manage disk space by removing detections that don't have corresponding recognition records:
python -m safewheels.scripts.cleanup_processed --config config/config.json --min-age 24Command-line arguments:
--min-age: Minimum age in hours for records to be eligible for cleanup (default: 24)--dry-run: Run in simulation mode without actually deleting files
This script finds and removes:
- Detection records in the database that don't have a corresponding recognition record
- The associated image files for those detections
- Only processes records older than the specified minimum age
-
Create a Telegram bot using BotFather
- Message @BotFather on Telegram
- Use the
/newbotcommand and follow the instructions - Save the API token you receive
-
Get the user IDs for authorized users
- Have each authorized user send a message to the bot
- Visit
https://api.telegram.org/bot<YOUR_TOKEN>/getUpdates - Look for the
fromobject in each message and note theidvalue for each user
-
Update your configuration in
config/config.json:{ ... "db_filename": "detections.db", "check_interval_sec": 5, "telegram_token": "YOUR_BOT_TOKEN", "authorized_users": [ 123456789, // First user's ID 987654321 // Second user's ID ] }
These scripts are designed to run continuously. To ensure they stay running even after system reboots, consider using a service manager like systemd (Linux) or creating a launch agent (macOS).
Example systemd service (Linux):
[Unit]
Description=SafeWheels Vehicle Detection Service
After=network.target
[Service]
User=yourusername
WorkingDirectory=/path/to/safewheels
ExecStart=/usr/bin/python -m safewheels.scripts.watch_and_detect --config /path/to/config.json
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
If you're not receiving notifications:
-
Check the Telegram configuration
- Verify the bot token in config.json
- Ensure your Telegram user ID is correctly listed in the
authorized_usersarray - Verify that each user ID is a number, not a string (e.g.,
123456789, not"123456789") - Confirm that each authorized user has started a chat with the bot
- Test the bot by sending it a direct message
-
Check the database setup
- Ensure the SQLite database file exists at the configured location
- Verify that the database contains records (use
sqlite3 path/to/database.dband run.tablesandSELECT COUNT(*) FROM detections;) - Check that the database has the correct schema (run
.schema detectionsin SQLite)
-
Review logs and permissions
- Check the console output for error messages
- Verify the script has read access to the database and images directory
- Ensure the images referenced in the database exist in the images directory

