This system integrates computer vision, density-based clustering (DBSCAN), and heatmap generation to deliver real-time crowd density analysis and clustering visualization.
This project utilizes Python and OpenCV to process video feeds, detect individuals using MobileNetSSD, and apply the DBSCAN algorithm to identify high-density clusters. It visualizes this data using a color-coded heatmap overlay.
- πΉ Real-time Video Processing and Person Detection (OpenCV)
- π§ Deep Learning Detection (MobileNet SSD)
- π‘οΈ Dynamic Heatmap Generation
- π Person Cluster Identification (DBSCAN)
- π¨ Crowd/Cluster Alerts (Threshold-based warnings)
Here is a screenshot from a run of the project with the bounding boxes around object(s) detected and person and cluster count at the top, as well as heatmap.
- Python β Script execution and main logic
- OpenCV (cv2) β Frame capture, preprocessing, drawing functions, heatmap blending
- DBSCAN (sklearn) β Density-based clustering
- NumPy β Array and matrix operations
Camera β MobileNet SSD β Person Detection β Centroids β DBSCAN Clustering β Heatmap Overlay
- π‘ Capture webcam feed
- π§ Detect people using MobileNet SSD
- π€ Extract centroids (middle of bounding box)
- π§© Cluster using DBSCAN
- π¨ Generate heatmap
- πΌοΈ Overlay heatmap on the live frame
crowd-monitoring-heatmap-system/
βββ mobilenet/ # MobileNet SSD model files
β βββ MobileNetSSD_deploy.prototxt
β βββ MobileNetSSD_deploy.caffemodel
βββ crowd_detect.py # Main application script
βββ requirements.txt # Dependencies list
βββ LICENSE.md # License file
βββ README.md # Documentation (this file)
Contains:
| File | Purpose |
|---|---|
MobileNetSSD_deploy.prototxt |
Defines network architecture (layers, input shape). |
MobileNetSSD_deploy.caffemodel |
Pre-trained network weights. |
Includes:
opencv-python # ποΈ Used for video processing, drawing, heatmap blending, and MobileNet SSD inference
numpy # π’ Handles array operations, centroid math, and heatmap matrix calculations
scikit-learn # π Provides DBSCAN clustering for grouping detected people spatially
Below is the complete code and then a breakdown of how each block works.
import cv2
import numpy as np
import time
from sklearn.cluster import DBSCAN
# Load model
net = cv2.dnn.readNetFromCaffe(
'mobilenet/MobileNetSSD_deploy.prototxt',
'mobilenet/MobileNetSSD_deploy.caffemodel'
)
# Classes (focus only on people)
PERSON_CLASS_ID = 15
# Start webcam
cap = cv2.VideoCapture(0)
ALERT_THRESHOLD = 5
CLUSTER_DISTANCE = 75 # Adjust based on camera scale
CLUSTER_SIZE_THRESHOLD = 3 # Number of people per cluster
ret, frame = cap.read()
h, w = frame.shape[:2]
heatmap = np.zeros((h, w), dtype=np.float32)
while True:
ret, frame = cap.read()
if not ret:
break
h, w = frame.shape[:2]
blob = cv2.dnn.blobFromImage(cv2.resize(frame, (300, 300)), 0.007843, (300, 300), 127.5)
net.setInput(blob)
detections = net.forward()
people_centroids = []
for i in range(detections.shape[2]):
confidence = detections[0, 0, i, 2]
class_id = int(detections[0, 0, i, 1])
if confidence > 0.5 and class_id == PERSON_CLASS_ID:
box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
x1, y1, x2, y2 = box.astype("int")
cx, cy = int((x1 + x2) / 2), int((y1 + y2) / 2)
if 0 <= cx < w and 0 <= cy < h:
people_centroids.append([cx, cy])
heatmap[cy, cx] += 1
cv2.rectangle(frame, (x1, y1), (x2, y2), (57, 255, 20), 3)
# Cluster detection
cluster_count = 0
if len(people_centroids) > 0:
people_np = np.array(people_centroids)
clustering = DBSCAN(eps=CLUSTER_DISTANCE, min_samples=CLUSTER_SIZE_THRESHOLD).fit(people_np)
labels = clustering.labels_
unique_clusters = set(labels)
if -1 in unique_clusters:
unique_clusters.remove(-1) # Remove noise points
cluster_count = len(unique_clusters)
# Heatmap
heatmap_blur = cv2.GaussianBlur(heatmap, (51, 51), 0)
heatmap_norm = cv2.normalize(heatmap_blur, None, 0, 255, cv2.NORM_MINMAX)
heatmap_color = cv2.applyColorMap(heatmap_norm.astype(np.uint8), cv2.COLORMAP_JET)
heatmap_color = cv2.resize(heatmap_color, (w, h))
overlay = cv2.addWeighted(heatmap_color, 0.6, frame, 0.4, 0)
# Display crowd info
cv2.putText(overlay, f"People: {len(people_centroids)}", (20, 30),
cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2)
cv2.putText(overlay, f"Clusters: {cluster_count}", (w - 250, 30),
cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 0), 2)
# Optional alert
if len(people_centroids) >= ALERT_THRESHOLD:
cv2.putText(overlay, "ALERT: CROWD FORMING", (20, 70),
cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 3)
# Display
cv2.namedWindow("CrowdHawk", cv2.WINDOW_NORMAL)
cv2.resizeWindow("CrowdHawk", 1280, 720)
cv2.imshow("CrowdHawk", overlay)
if cv2.waitKey(1) == 27:
break
cap.release()
cv2.destroyAllWindows()```-
Loads the MobileNet SSD model using:
cv2.dnn.readNetFromCaffe()
-
Only class ID 15 (person) is used.
-
Webcam stream:
cap = cv2.VideoCapture(0)
-
Frames are resized and normalized into a blob for neural-network inference.
-
net.forward()returns detections. -
For each detection:
- Check if
confidence > 0.5 - Check
class_id == PERSON_CLASS_ID - Extract centroid
(cx, cy) - Draw bounding box
- Add intensity point to heatmap
- Check if
-
Clusters people based on:
DBSCAN(eps=CLUSTER_DISTANCE, min_samples=CLUSTER_SIZE_THRESHOLD)
-
Removes βnoise" points with label
-1.
-
Each detected centroid increments heatmap value.
-
Gaussian Blur smooths hotspots.
-
Heatmap converted into colorized map via:
cv2.COLORMAP_JET
-
Blended with frame using
cv2.addWeighted.
-
Displays:
- Total people
- Cluster count
-
Shows warning when a crowd is forming
-
ESC key exits the program
git clone https://github.com/rh3nium/Crowd-Monitoring-Heatmap-System
cd Crowd-Monitoring-Heatmap-Systempython3 -m venv envActivate it:
Windows:
env\Scripts\activatemacOS / Linux:
source env/bin/activatepip install -r requirements.txtpython3 crowd_detect.py- Increase/reduce
CLUSTER_DISTANCEto change clustering sensitivity. - Heatmap builds over time β more accurate in dense areas.
MIT License. Free to modify and distribute with attribution. Read license here at LICENSE.md.
