Inspiration
A campus with two hundred cameras records about eight thousand hours of innocent people every week, so that on the rare day something happens, someone can go back and look. We think that trade is wrong in three ways:
- It arrives too late. A student who falls on a stairwell at 7 pm is found when someone walks past. The camera was a witness, and nobody was watching.
- It keeps everybody. Every person who walked past a lens becomes a file that can be searched, leaked or sold.
- It changes how a campus feels, and that cost is paid every day by people who will never be involved in an incident.
Our answer is that safety does not require watching people. It requires noticing events. Those are different problems.
Normal CCTV records thousands of innocent students to catch one incident. ARJUN watches no one, until someone gives it a reason to.
The name comes from the Mahabharata: asked what he could see, Arjuna said he saw only the eye of the bird, and nothing else.
What it does
ARJUN turns every camera into a stream of anonymous skeletons with temporary ID numbers. The dashboard never receives the camera image. It draws joints onto a blank canvas, so there is no face to blur, and no setting that could turn faces back on.
Eleven rules read that geometry and raise an alert:
- Fall: the hips drop sharply, the body ends up horizontal, and the person stays down for two seconds.
- Signal for Help: the silent hand gesture (palm, thumb tucked, fingers folded over). The alert goes to the guard's phone with no sound.
- Restricted zone, loitering, crowd density, unattended bag, blocked fire exit, panic running, entry/exit counting and after-hours occupancy.
- Exam mode (off by default): flags a phone at a desk for an invigilator to check. It never names or accuses anyone.
When a rule fires, the alert reaches the dashboard and the guard's Telegram with a skeleton snapshot. It never contains a photograph. The system also saves a 15-second clip (10 s before, 5 s after) that only staff with a PIN can open.
The privacy ledger on the dashboard shows what we hold, and what we refuse to hold. Every raw-view unlock is written to an audit log that everyone can see: staff can see faces when they need to, but they cannot do it quietly.
How we built it
- Vision: YOLOv8n-pose with ByteTrack, run every frame, gives every skeleton a stable ID in one pass. A second YOLOv8n model looks for bags and phones every third frame. MediaPipe handles hand landmarks (Signal for Help) and head yaw (exam mode) on small crops, only when needed.
- Rules: one file per detector. Speeds are measured in body heights per second and distances in multiples of the person's own height, never pixels, so one set of numbers works near the lens and far down a corridor.
- Privacy by structure: the renderer's function signature cannot accept an image. The only component that writes pixels is the incident recorder. A test reads the source code and fails if anything else gains a video writer.
- Backend: Python, FastAPI and WebSockets, with one thread per camera. SQLite stores events, zones and the audit log.
- Frontend: a single page in plain HTML, CSS and JavaScript with no build step. The look comes from Renaissance anatomical studies: ivory figures on near-black with a warm glow. Chart.js draws the analytics.
- Alerts: Telegram first, with optional WhatsApp. Cooldowns stop one incident from spamming the guard.
- Assistant: an optional Claude integration answers questions like "any falls today?" and writes incident reports. It sees structured event rows only, never images. Without a key it falls back to a local keyword search and a report template.
Challenges we ran into
- Frame rate. The obvious design (detector, then MediaPipe Pose on each person) costs one inference per person and falls to single-digit fps. We inverted it: pose and tracking on every frame, objects every third frame. On a CPU-only laptop we measured about 13.8 fps with one real camera.
- A rule that would have never fired. Our first "unattended bag" rule required nobody within two metres. In a busy corridor somebody is always nearby, so the timer reset forever. That is worse than having no rule, because you would believe you had it. Now someone must be near the bag and stopped, and a test sweeps a pedestrian past it every few seconds and still expects the alert.
- A line-counting bug. A foot landing exactly on the dead-band became the "previous side", and the real crossing was skipped. We fixed it with hysteresis.
- Laptop throttling and cloud sync. After an hour of load the same code ran 2.7 times slower. OneDrive syncing our clips took half the CPU, so the app now warns about it and the data can live outside the synced folder.
- Honest limits. We have no labelled dataset of real falls, so we do not quote an accuracy percentage. We built each rule to reject its look-alikes (sitting down, bending over, a fist, someone walking past a bag) and test those cases.
Accomplishments that we're proud of
- The privacy claim is structural: you can verify it by reading one function, and tests fail if it breaks.
- A working end-to-end alert path: from a fall on camera to a skeleton image on a phone in a few seconds.
- 91 automated tests that run in about a second with no camera and no model weights.
- A system that still runs with no API keys at all.
What we learned
- Confirmation windows are what make alerts trustworthy: a rule nobody trusts is a rule nobody acts on.
- Measuring beat guessing. Profiling found the real frame-rate problems.
- An honest limitation, stated clearly, is stronger than a flat denial.
What's next for ARJUN
- A labelled dataset of real falls, so the thresholds are measured instead of hand-tuned.
- On-device inference (Jetson or Coral), so frames never leave the camera.
- A formal privacy-impact assessment and a student-facing page explaining exactly what the cameras do.
What this should never be used for: attendance, productivity monitoring, or discipline based on an alert alone. Those need identity, and identity is the thing we deliberately did not build.
Note: the demo's scripted scenes (Atrium, Exam Hall, Gate) are labelled "Simulated" and run through the same detectors as a real camera.
Built With
- anthropic-claude-api
- bytetrack
- chart.js
- coco-dataset
- css3
- fastapi
- google-fonts
- html5
- javascript
- mediapipe
- numpy
- opencv
- pytest
- python
- python-dotenv
- pytorch
- sqlite
- telegram-bot-api
- twilio
- ultralytics-yolov8
- uvicorn
- websockets
Log in or sign up for Devpost to join the conversation.