Real-time motion & object detection → event-driven alerts
An end-to-end monitoring platform: an OpenCV sensor watches a live camera for cats, bodies and faces and streams confirmed events to a Laravel admin panel, which stores them in MySQL and fires queued email alerts. A Python watchdog polls the database and raises the alarm when the sensor goes silent.
The Surveillance System turns a plain webcam into a self-monitoring security platform. It runs four Haar-cascade classifiers in real time, confirms detections over consecutive frames to cut false positives, snapshots each confirmed event, and notifies you by email — all the way through to a Persian-language admin dashboard for reviewing and managing events.
Because event-driven alerts only fire when something is detected, a background watchdog polls the database and emails you if the sensor has been silent for too long, catching outages before they matter.
- Multi-class detection — cats, full bodies, upper bodies and frontal faces via OpenCV Haar cascades
- Consecutive-frame confirmation — 3 frames with a detection before an event is reported, reducing false positives
- Automatic snapshots — each confirmed event saves a timestamped image, available in the admin panel
- REST ingest API — sensor reports events over HTTP, decoupled from the database
- Queued email alerts — detection events trigger email notifications via a background job
- Silence watchdog — polls MySQL and alerts when no event has been recorded for N days
- Admin panel (Persian UI) — event listing, date filtering, event deletion, and event-type → action mapping
- Config via environment variables — no credentials hardcoded anywhere
┌─────────────────────────┐ HTTP POST ┌──────────────────────────────┐
│ SENSOR (Python/OpenCV)│ ─────────────> │ CONTROLLER (Laravel 8) │
│ webcam → Haar cascades │ /api/event/ │ stores events in MySQL │
│ 3-frame confirmation │ create │ dispatches queued email job │
│ snapshot + report │ │ admin web panel (Persian) │
└─────────────────────────┘ └──────────────┬───────────────┘
│ reads
┌─────────────────────────┐ ┌──────────────▼───────────────┐
│ WATCHDOG (Python) │ <────────────> │ MySQL (surveillance_system) │
│ no event for N days │ reads │ │
│ → SMTP alert email │ ────────────> │ SMTP alert email │
└─────────────────────────┘ └──────────────────────────────┘
| Layer | Technology |
|---|---|
| Backend | Laravel 8 (PHP ^7.3|^8.0), MySQL |
| Sensor | Python 3, OpenCV, NumPy, Requests |
| Watchdog | Python 3, mysql-connector-python, smtplib |
| Admin UI | Bootstrap 4, jQuery, Vue 2, StarAdmin |
| Notifications | Queued Laravel mail jobs + SMTP |
prj/
├── controller/ # Laravel 8 backend: REST API + admin panel
│ ├── app/Http/Controllers/ # EventController, EventActionController
│ ├── app/Jobs/SendEmailJob # queued alert email + event "done" flag
│ ├── database/migrations # events, event_actions, users tables
│ ├── database/seeders # demo user + event-action mappings
│ └── routes/ # web.php, api.php
├── sensor/ # OpenCV webcam detection service
│ ├── main.py # capture loop entry point
│ ├── detector.py # Haar-cascade detector wrapper
│ ├── tracker.py # consecutive-frame confirmation + throttling
│ ├── reporter.py # snapshot saving + REST reporting
│ ├── config.py # env-driven configuration
│ ├── data/ # Haar-cascade XML classifiers
│ └── legacy/ # original prototypes (kept for reference)
└── watchdog/ # silence-detection alert service
├── main.py # polling loop entry point
├── database.py # MySQL access
├── notifier.py # SMTP alert delivery
├── config.py # env-driven configuration
└── legacy/ # original prototype (kept for reference)
assets/screenshots/ # admin-panel UI screenshots
cd prj/controller
composer install
cp .env.example .env
php artisan key:generate
# edit .env: set DB_DATABASE, DB_USERNAME/DB_PASSWORD and MAIL_* settings
php artisan migrate
php artisan db:seed
php artisan servedb:seed creates a demo user and the cat / body / face event-action mappings the sensor depends on.
pip install -r requirements.txt # or: pip install -r prj/sensor/requirements.txt
cd prj/sensor
export SENSOR_API_URL=http://localhost:8000/api/event/create
python main.py # press 'q' to quitRequires a webcam. The Haar-cascade XML files are already bundled in prj/sensor/data/.
pip install -r requirements.txt # or: pip install -r prj/watchdog/requirements.txt
export DB_HOST=localhost DB_USER=root DB_PASSWORD= DB_DATABASE=surveillance_system
export SMTP_HOST=smtp.mailtrap.io SMTP_PORT=2525 SMTP_USERNAME= SMTP_PASSWORD=
export ALERT_EMAIL_TO=admin@example.com
cd prj/watchdog
python main.pyAll secrets and endpoints are read from the environment — nothing is committed.
| Variable | Service | Default | Purpose |
|---|---|---|---|
SENSOR_API_URL |
sensor | http://localhost:8000/api/event/create |
Controller ingest endpoint |
SENSOR_CAMERA_INDEX |
sensor | 0 |
Webcam device index |
SENSOR_CONFIRMATION_FRAMES |
sensor | 3 |
Consecutive frames before reporting |
SENSOR_SNAPSHOT_THROTTLE_MINUTES |
sensor | 1 |
Min minutes between snapshots of a class |
SURVEILLANCE_ALERT_AFTER_DAYS |
watchdog | 3 |
Silence threshold before alerting |
SURVEILLANCE_POLL_INTERVAL |
watchdog | 5 |
Seconds between database polls |
DB_HOST / DB_USER / DB_PASSWORD / DB_DATABASE |
watchdog | local defaults | MySQL connection |
SMTP_HOST / SMTP_PORT / SMTP_USERNAME / SMTP_PASSWORD |
watchdog | mailtrap defaults | Outgoing mail |
ALERT_EMAIL_FROM / ALERT_EMAIL_TO |
watchdog | — | Alert sender/recipient |
- Start the Laravel server, then the sensor. When an object is detected for 3 consecutive frames, a snapshot is saved and an event appears in the admin panel at
http://localhost:8000. - The sensor throttles snapshots to one per minute per class.
- The watchdog runs continuously; if the last event is older than
SURVEILLANCE_ALERT_AFTER_DAYS, it sends one alert email per day.
curl -X POST http://localhost:8000/api/event/create \
-d 'type=face' -d 'image=test.png'| Admin dashboard | Events |
|---|---|
![]() |
![]() |
- Protect the ingest API with a shared token between sensor and controller
- Replace Haar cascades with a deep detector (e.g. YOLO) for higher accuracy
- Live dashboard with detection trends and charts
- Dedicated feature tests for the event API
Seyed Farhad Hosseini — farhadhsn8

