Most hobby surveillance projects stop at "stream a webcam to a browser." Netra doesn't. It's a closed-loop system: an ESP32-CAM streams frames, a YOLOv8 model finds the person in them, and the result drives two servos that physically turn the camera to keep that person centered — all coordinated over MQTT. The name comes from the Sanskrit word for eye, and that's the honest description of what it is: an eye that moves on its own.
It started as a Microprocessors & Microcontrollers course project and I kept building until it was a full edge-to-cloud stack. This post walks through how the pieces actually fit together.
There are four moving parts, and each one only does its own job:
Everything talks over MQTT, a lightweight pub/sub protocol, with WebSocket used to push real-time updates into the dashboard. The value of pub/sub here is decoupling: the detector doesn't need to know how many things are listening to its output, and the dashboard doesn't need a direct socket to the camera.
The tracking loop is the heart of the project, and the interesting part is that naïve tracking looks terrible. If you simply move the servo whenever the target isn't perfectly centered, the camera jitters constantly — it chases sub-pixel noise forever and never settles.
Two design choices fix that:
Proportional control. The servo speed scales with how far the target is from the center of the frame. A person at the edge of the frame gets a fast correction; a person almost centered gets a gentle nudge. This is the difference between a camera that snaps and overshoots and one that glides.
A dead zone. There's a 12% tolerance band around the center where the camera simply does nothing. Inside that band, "close enough" is treated as "centered," which kills the jitter entirely. The servos are MG90S metal-gear units, with roughly 0°–180° of pan and 30°–150° of tilt.
Those two rules — scale the response, and ignore tiny errors — are what turn a twitchy demo into something that tracks a walking person smoothly.
The dashboard exposes three modes, and they map cleanly onto real use:
Detecting a person is table stakes. The layer I'm most happy with is BASE — the Behavioral Anomaly Signature Engine. Instead of just firing an alert every time it sees a human (which would make the alerts useless), BASE does multi-factor threat scoring against configurable thresholds and builds time-weighted patrol heat-maps of where activity concentrates. The goal is signal, not noise: a system that can tell "someone walked through the hallway at noon" apart from "someone is lingering somewhere they shouldn't be at 3 a.m."
A single node is a demo; a security system is many cameras. Netra is designed for that with ESP-NOW mesh handoff, supporting up to eight camera nodes so a target can be tracked as it moves between their fields of view. The dashboard was built with this in mind too — the live feed uses stream-isolated rendering so that React re-rendering the surrounding UI never tears down the video element and drops the feed. Small detail, but if you've ever had a stream die every time a sibling component updates, you know why it matters. There's also a 4-second auto-reconnect so a dropped stream recovers on its own.
Three things carried most of the weight:
Netra spans firmware, computer vision, a real-time backend, and a frontend — which is exactly why it was worth building. The full architecture, wiring diagrams, API reference, and setup guide are in the repository, released under Apache 2.0.