EyeNet: Turning a Webcam Feed Into Actionable Security Incidents

작성자

카테고리:

← 피드로
DEV Community · Sparsh Jain · 2026-07-07 개발(SW)

I built a real-time campus surveillance system that turns noisy camera feeds into actionable security incidents

Most computer vision surveillance demos end the moment a model detects something.

A bounding box appears around a knife. A confidence score flashes on the screen. Maybe a label says “person” or “fire”.

And that’s usually where the demo stops.

The problem is that security teams don’t respond to detections—they respond to incidents.

Turning webcam input into security incidents is mostly a triage problem. The valuable part isn’t that an AI spotted something in a single frame; it’s preserving enough context for a human to quickly decide whether the event actually matters.

A camera that reports “knife detected” 60 times because one object stayed in frame isn’t helpful.

A camera that says:

Unknown individual entered Building A at 2:14 PM. The person remained in view for eight seconds, confidence 96%, snapshot attached, similar alert suppressed for the next five minutes.

…is something a security team can actually work with.

That idea became EyeNet.

Rather than treating object detection as the product, EyeNet treats it as the first stage of an incident-response pipeline that converts live video into structured, queryable events with context, persistence, prioritization, and notifications.

The problem

Campus security teams face a surprisingly familiar set of problems:

  • Nobody can realistically monitor dozens of camera feeds all day.
  • Alerts usually happen through phone calls or WhatsApp messages with little structure or history.
  • Naive computer vision systems generate huge numbers of false positives.
  • When an actual incident occurs, there’s often no searchable audit trail with snapshots or timestamps.

The challenge isn’t detecting objects.

It’s deciding when a detection deserves to become an incident.

Designing for triage instead of detection

That mindset influenced almost every architectural decision in EyeNet.

One camera reader, many consumers

Instead of letting multiple parts of the system compete for webcam access, a SharedFrameBuffer owns the camera and distributes frames to everyone else.

Camera
    ↓
SharedFrameBuffer
    ├── Detection Pipeline
    ├── Dashboard Stream
    └── Future Consumers

Enter fullscreen mode Exit fullscreen mode

Adding another consumer doesn’t mean opening another camera stream.

Multiple signals, one decision

Every frame is analyzed by multiple independent detectors.

  • Face recognition identifies enrolled students.
  • Known students are checked for uniform compliance using HSV color analysis over the torso region.
  • YOLOv8 detects hazards such as weapons, smoke, or fire.

Each detector contributes evidence.

None of them immediately generates an alert.

Tracking before alerting

One of the biggest improvements came from refusing to trust single-frame detections.

Hazards and unknown faces are tracked across frames using ByteTrack. Only detections that remain stable for a configurable number of frames become incidents.

That single design decision eliminated most false-positive alerts.

Instead of:

Frame 182
Knife detected
Alert!

Enter fullscreen mode Exit fullscreen mode

the pipeline behaves more like:

Frame 182
Possible knife

Frame 183
Still visible

Frame 184
Still visible

Frame 185
Track confirmed

→ Create incident

Enter fullscreen mode Exit fullscreen mode

Persistence becomes evidence.

Events instead of detections

Once a track qualifies, it becomes a structured DetectionEvent.

That event contains far more than “knife detected.”

It includes:

  • timestamp
  • severity
  • anomaly score
  • snapshot path
  • tracking ID
  • metadata
  • acknowledgement status

From that point onward, the computer vision pipeline is finished.

Everything else works with incidents.

An event-driven architecture

EyeNet routes incidents through an in-process priority event bus.

Camera
   ↓
Detection Pipeline
   ↓
Object Tracker
   ↓
Detection Event
   ↓
Priority Event Bus
      ├── SQLite
      ├── Notifications
      └── Live Dashboard

Enter fullscreen mode Exit fullscreen mode

Events aren’t processed FIFO.

Critical incidents like firearms or fire always jump ahead of uniform violations.

Handlers operate independently, so a slow SMTP request never blocks database writes or dashboard updates.

Reducing alert fatigue

Alert fatigue is a real operational problem.

EyeNet tries to avoid it in several ways.

Anomaly scoring

Each event receives a score between 0 and 100 based on:

  • detection type
  • model confidence
  • track persistence

That score determines how aggressively the system responds.

For example, SMS notifications are only sent once an event crosses a configurable threshold.

Cooldowns

Two independent cooldown systems prevent repeated notifications.

A severity-based cooldown ensures the same incident isn’t repeatedly escalated.

The SMS service also maintains its own subtype cooldown so ongoing hazards don’t spam administrators every few seconds.

The goal is simple:

One incident.

One meaningful notification.

Persistence matters

Incidents aren’t ephemeral.

EyeNet stores alerts and metrics inside SQLite running in WAL mode, allowing the detection pipeline to keep writing while the dashboard performs concurrent reads.

The dashboard provides:

  • live MJPEG camera streaming
  • Server-Sent Events for new incidents
  • snapshot thumbnails
  • acknowledgement workflow
  • filtering by severity and event type
  • hourly analytics
  • pipeline performance metrics

Instead of simply watching cameras, operators can review what happened, when it happened, and what actions have already been taken.

Notifications

Different incidents require different responses.

EyeNet currently supports:

  • Twilio SMS for hazards and unknown visitors once anomaly scores exceed a threshold.
  • SMTP email notifications for uniform violations, automatically routed to institutional student email addresses.

Tech stack

  • Python
  • Flask
  • OpenCV
  • Ultralytics YOLOv8
  • face-recognition (dlib)
  • ByteTrack via supervision
  • SQLite (WAL mode)
  • Twilio
  • Docker Compose

What I’d improve next

If I continued working on EyeNet, I’d focus less on new detectors and more on improving incident management.

Some things on the roadmap include:

  • Redis Pub/Sub instead of an in-process event bus
  • Role-based access control
  • Storing face encodings directly in the database
  • API rate limiting
  • A proper investigation workflow with assignments, notes, escalation states, and case history

Final thoughts

The biggest lesson from building EyeNet was that surveillance isn’t primarily a computer vision problem.

It’s an information triage problem.

The challenge isn’t getting a model to recognize a knife, a face, or a uniform.

The challenge is deciding when those detections become meaningful enough for a human to interrupt what they’re doing and respond.

That’s the gap I wanted EyeNet to close.

Demo: https://www.youtube.com/watch?v=iarosznhHE8

Repository: https://github.com/SplinterSword/EyeNet

If you’re building real-time CV systems, event-driven pipelines, or anything focused on reducing alert fatigue, I’d love to hear how you’re approaching the problem.

원문에서 계속 ↗

코멘트

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다