Inspiration

Dehradun, where I'm from, has seen a sharp rise in car accidents and violent crime recently. It's the kind of thing that stops being an abstract statistic once it starts feeling close to home. And it raised a specific, uncomfortable question: if you're the victim of a crime and left for dead, does anyone even know in time to help?

The frustrating part is that the infrastructure to know already exists. India has one of the densest CCTV networks in the world; Delhi alone runs over 300,000 cameras. That footage is already being actively reviewed, every day, by government systems, to issue traffic challans. The cameras that fine you for jaywalking are switched on, staffed, and watching. They're just watching for the wrong thing.

That gap, massive surveillance infrastructure sitting idle for the one job that actually matters, is what Prahar is built to close.

What it does

Prahar is a real-time AI triage layer that sits on top of existing CCTV infrastructure and flags violent crime, theft, emergencies, and property damage as they happen, not after, when footage is pulled for an investigation that's already too late to prevent anything.

It doesn't replace human judgment. Every flagged clip goes to a human operator who reviews the AI's confidence score and threat classification before any dispatch happens. No autonomous alarms, no automatic escalation. The AI's job is to cut through the noise of hundreds of simultaneous feeds and put the right clip in front of a human, fast.

How we built it

The core is a custom-trained X3D-M (a lightweight 3D convolutional network) feeding into a 2-layer Transformer encoder and a dual-head Multiple Instance Learning setup:

  • Head A answers "is something wrong?" using binary anomaly detection via Top-K bag aggregation
  • Head B answers "what kind of wrong?" using a 4-class classifier (Violence / Theft / Emergency / Property Damage)

We trained on UCF-Crime and XD-Violence (4,215 real-world CCTV clips), and split the two heads deliberately. A single model trying to do both binary detection and fine-grained classification on imbalanced real-world data tends to just learn the majority class. Separating them let each head optimize for the signal it actually needed.

One of the biggest wins was the preprocessing pipeline: converting raw .mp4 clips into pre-computed .npy bags (4 bags × 8 frames × 112×112) ahead of training. That took epoch time from 4.5 hours down to under 2 minutes, which meant we could actually iterate: 30 epochs in 57 minutes on a single free-tier T4 GPU.

On top of the model sits a three-tier system:

  • A Flask-SocketIO backend running per-camera inference threads on a round-robin GPU scheduler, holding flagged incidents in a pending_incidents state machine
  • A React tactical dashboard with a live multi-feed viewer and a triage sidebar, where operators see the flagged clip, confidence score, and predicted class, and choose to dispatch or dismiss

Challenges we ran into

  • Weak labels. Real CCTV datasets tell you a 10-minute clip contains a robbery, not which frames. Multiple Instance Learning was the right call, but getting the bag aggregation to actually converge cleanly, rather than overfitting to a few dominant frames, took real tuning.
  • I/O bottlenecks. Our first training loop spent most of its time reading raw video off disk. The .npy preprocessing step fixed this, but figuring out that was the bottleneck, not the model, cost us real debugging time.
  • Keeping humans structurally in the loop, not just as a checkbox. It would've been easier to just fire an alert straight to dispatch above a confidence threshold. Building a real pending_incidents state machine that cannot skip human review, and making sure the frontend didn't unmount and silently drop pending alerts when operators switched tabs, took more engineering than the shortcut would have.
  • Deployment realism. It's easy to build something that only works on a research cluster. Every architectural choice, X3D-M over heavier 3D CNNs, RGB-only over optical flow, .npy caching, was made so this could plausibly run on the hardware a municipal control room actually has, not a GPU cluster.

Accomplishments that we're proud of

  • We beat published state-of-the-art baselines using a cheaper modality on cheaper hardware. Prahar hits 93.49% frame-level AUC, RGB-only, on a single T4 GPU. That's ahead of: | Model | Modality | AUC | |---|---|---| | Sultani et al. (2018) | RGB | 75.41% | | RTFM (Wu et al., 2021) | RGB | 84.30% | | MGFN (Chen et al., 2023) | RGB + Optical Flow | 86.98% | | Prahar (ours) | RGB only | 93.49% |

MGFN uses optical flow, which is computationally expensive and requires paired frame computation, and we still beat it by about 6.5 points using RGB alone, on hardware a municipal control room could actually afford.

  • We got epoch time down from 4.5 hours to under 2 minutes through the .npy preprocessing pipeline, which let us run 30 full epochs to convergence in 57 minutes.
  • We built a genuinely human-in-the-loop system, not a human-in-the-loop label. No code path in the backend lets an anomaly skip straight to dispatch.

What we learned

  • Architecture choices can matter more than raw compute. Prahar's RGB-only, single-T4 setup outperformed baselines that used optical flow on research clusters because the modeling decisions (dual-head MIL, efficient backbone) mattered more than throwing hardware at the problem.
  • Responsible AI in a public safety context isn't a section you write at the end. It has to shape the architecture from the start. The human-in-the-loop design wasn't added for compliance; it's the reason the system is defensible to deploy at all.
  • The hardest part of a project like this isn't the model. It's building something that respects the fact that a false positive costs a few seconds of operator time, and a false negative can cost a life, and designing every layer around that asymmetry.

What's next for Prahar - AI-Powered Real-Time Crime Detection

  • Fine-tuning on locally collected Indian CCTV footage to close the distribution-shift gap between UCF-Crime/XD-Violence (largely US/European) and Indian urban environments: lighting, crowd density, camera angles.
  • Adding a message queue (Redis) between the inference layer and backend to support true city-scale, multi-precinct deployment.
  • Partnering with a municipal traffic/challan authority to pilot Prahar on cameras that are already legally authorized and actively staffed, since that's the whole premise: no new infrastructure, just a new use for what's already watching.
  • Building calibration tooling so operators can tune the 0.85 confidence threshold against their own local false-positive/false-negative tradeoffs, rather than using a fixed global value.
Share this project:

Updates

Submission history