<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Alugam Sahasra</title>
    <description>The latest articles on DEV Community by Alugam Sahasra (@sahasra_alugam).</description>
    <link>https://dev.to/sahasra_alugam</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4114131%2F4bfac5a4-13d7-45af-8ea1-abf50e1231f2.png</url>
      <title>DEV Community: Alugam Sahasra</title>
      <link>https://dev.to/sahasra_alugam</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sahasra_alugam"/>
    <language>en</language>
    <item>
      <title>Building a Real-Time Crowd Anomaly Detector with MobileNetV2 and OpenCV</title>
      <dc:creator>Alugam Sahasra</dc:creator>
      <pubDate>Mon, 07 Sep 2026 16:49:00 +0000</pubDate>
      <link>https://dev.to/sahasra_alugam/building-a-real-time-crowd-anomaly-detector-with-mobilenetv2-and-opencv-44d</link>
      <guid>https://dev.to/sahasra_alugam/building-a-real-time-crowd-anomaly-detector-with-mobilenetv2-and-opencv-44d</guid>
      <description>&lt;p&gt;I recently built a real-time video anomaly detection system that classifies footage as violent or non-violent using transfer learning - and wanted to share what I learned, including the environment issues that ate up more time than the actual model building.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Problem
&lt;/h3&gt;

&lt;p&gt;Crowd monitoring systems today mostly rely on manual observation - someone watching camera feeds and reacting after something's already gone wrong. I wanted to build something that could flag anomalous behavior automatically, in real time, without needing a massive custom-trained model from scratch.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Approach
&lt;/h3&gt;

&lt;p&gt;Rather than training a CNN from zero (which needs huge datasets and compute I didn't have), I used transfer learning with MobileNetV2, pretrained on ImageNet:&lt;/p&gt;

&lt;p&gt;Froze the base MobileNetV2 layers to keep the pretrained visual features intact&lt;br&gt;
Added a custom head: GlobalAveragePooling2D → Dense(512, relu) → Dropout(0.5) → Dense(1, sigmoid)&lt;br&gt;
Trained as a binary classifier: violent vs. non-violent&lt;br&gt;
Total params: 2.91M, of which only 656K were trainable (the rest frozen in the pretrained base)&lt;/p&gt;

&lt;p&gt;Dataset: 2,543 training images and 635 validation images across the two classes, resized to 150×150.&lt;/p&gt;

&lt;p&gt;Augmentation: rotation, shifts, shear, zoom, brightness jitter, horizontal flip - since real-world footage varies wildly in lighting and camera angle.&lt;/p&gt;

&lt;p&gt;Training safeguards: early stopping (patience=5) and a learning rate scheduler (halving LR on plateau) to avoid overfitting.&lt;/p&gt;

&lt;h3&gt;
  
  
  Results
&lt;/h3&gt;

&lt;p&gt;Validation accuracy: 94.65% (best epoch hit 95.43%)&lt;br&gt;
Training accuracy: 97.32% - close enough to validation that overfitting wasn't a major issue&lt;br&gt;
Trained for 27 epochs (early-stopped from a max of 30) in ~9 minutes on CPU&lt;br&gt;
Final loss: 0.088 (train) / 0.143 (val)&lt;br&gt;
Live webcam inference: ~135 ms/frame, ~6.6 FPS end-to-end (tested over 1,200+ live frames)&lt;br&gt;
Model size: 16.5 MB - small enough to run on modest hardware, no GPU required&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fn7rsxs9rrrb1ya6crhlj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fn7rsxs9rrrb1ya6crhlj.png" alt="Training accuracy and loss curves" width="800" height="320"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What Didn't Work / What I'd Change
&lt;/h3&gt;

&lt;p&gt;Environment setup was harder than the ML itself. I hit a chain of dependency conflicts - TensorFlow failing due to Windows' 260-character path limit, then h5py needing an exact version range TensorFlow was compatible with, then a NumPy version too new for SciPy. Every fix surfaced the next one. Lesson: pin your dependency versions before starting, not after debugging blind for an hour.&lt;br&gt;
~6.6 FPS on CPU is usable for monitoring, not for high-frame-rate applications. For genuine real-time deployment, I'd either quantize the model (TFLite) or run inference on a GPU.&lt;br&gt;
The frozen backbone limits how specialized the features are to violence detection specifically - fine-tuning the last few MobileNetV2 layers instead of freezing all of them is the obvious next experiment.&lt;/p&gt;

&lt;h3&gt;
  
  
  What's Next
&lt;/h3&gt;

&lt;p&gt;Fine-tune the last few layers of MobileNetV2 instead of freezing all of them, test on a larger and more diverse dataset, and quantize the model for faster edge inference. I'd also like to wrap this into a small web dashboard that logs alerts instead of just a webcam overlay.&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>computervision</category>
      <category>python</category>
      <category>tensorflow</category>
    </item>
  </channel>
</rss>
