Crowd Shield: crowd-counting models for Indian crowd safety
Author: Khushi Jain (@khushi-git-7) · Live app: crowd-shield-india.streamlit.app · Code: github.com/khushi-git-7/Crowd_shield
These are the counting models behind Crowd Shield, a crowd-safety tool built for India. It helps the staff running a railway station, a mela or a festival see crowd danger before it becomes a crush: it counts people in camera images, turns the count into people per square metre for each zone, and warns when a zone is heading towards a dangerous density.
This repository holds two models, both trained for the project with a held-out model-selection protocol:
| File | Model | Role in Crowd Shield |
|---|---|---|
pet_shab.pth |
PET point model + count correction | Main counter. Places a point on every head. |
dmcount_shab.pth |
DM-Count density model | Fallback counter. Predicts a density map. |
Results
Both models were evaluated on the 498 test photos of ShanghaiTech, the standard public benchmark of hand-labelled crowd photos (Part A: packed crowds collected from the web; Part B: busy streets). None of these photos were used for training, model selection or the count correction.
| Model | Part A accuracy | Part A MAE ↓ | Part B accuracy | Part B MAE ↓ |
|---|---|---|---|---|
| Standard YOLO person detector (Crowd Shield v1) | 7.1% | 402.7 | 42.1% | 71.7 |
| DM-Count (this repo) | 83.8% | 70.1 | 86.4% | 16.9 |
| PET + count correction (this repo) | 86.5% | 58.5 | 92.7% | 9.0 |
Accuracy = 1 − (total absolute counting error ÷ total true count) over the test set. MAE = mean absolute error, the average number of people a photo's count is off by.
Accuracy by crowd size (number of test photos in brackets):
| Part | Model | 0–100 | 100–250 | 250–500 | 500–1000 | 1000+ |
|---|---|---|---|---|---|---|
| A | YOLO (v1) | 26% (7) | 14% (62) | 8% (67) | 6% (28) | 4% (18) |
| A | DM-Count | 77% (7) | 83% (62) | 82% (67) | 85% (28) | 85% (18) |
| A | PET + correction | 86% (7) | 87% (62) | 87% (67) | 90% (28) | 83% (18) |
| B | YOLO (v1) | 67% (169) | 42% (117) | 21% (27) | 10% (3) | – |
| B | DM-Count | 87% (169) | 86% (117) | 86% (27) | 86% (3) | – |
| B | PET + correction | 94% (169) | 94% (117) | 91% (27) | 82% (3) | – |
Per-photo predictions and the evaluation scripts are in the results/shanghaitech folder of the code repository.
India evaluation: in progress
ShanghaiTech is used here because it is the benchmark the field reports on, so these numbers can be checked against published work. It does not contain Indian scenes. A hand-checked test set of Indian crowd photos (railway stations, melas, festivals) is being prepared, and its results will be added to this card.
Model details
PET (pet_shab.pth)
- Architecture: PET, Point-Query Quadtree (Liu et al., ICCV 2023), with a VGG16-BN backbone, a 4-layer transformer encoder and 2-layer decoder (hidden size 256, 8 heads); about 20.9 M parameters. It outputs one point per detected head, so it gives both the count and each person's location.
- Initialisation: the PET authors' JHU-Crowd++ checkpoint, which had not seen ShanghaiTech.
- Count correction: the raw point count is mapped to the final count with
count = 1.375 × raw^0.942. This single power-law fit reduces PET's overcounting in packed crowds and its undercounting on streets. It was fitted on the 70 held-out training photos, never on test photos.
DM-Count (dmcount_shab.pth)
- Architecture: DM-Count (Wang et al., NeurIPS 2020): VGG19 convolutional features, 2× bilinear upsampling and a small regression head that outputs a density map at 1/8 of the input resolution. The map sums to the count.
- Initialisation: ImageNet-pretrained VGG19.
Training data
ShanghaiTech Part A and Part B training sets combined (700 photos). 10% of them (70 photos) were held out and never trained on; they were used only to choose the best checkpoint and to fit PET's count correction.
Training procedure
| PET | DM-Count | |
|---|---|---|
| Hardware | 1 × NVIDIA T4 (Kaggle) | 1 × NVIDIA T4 (Kaggle) |
| Training length | 9.5 hours of fine-tuning | 870 epochs |
| Best checkpoint | epoch 240 | epoch 130 |
| Optimiser settings | lr 1e-4 (backbone 1e-5), batch size 8, weight decay 1e-4 | lr 1e-5, batch size 10, weight decay 1e-4, 256 px crops |
| Checkpoint selection | MAE on the 70 held-out training photos | MAE and MSE on the 70 held-out training photos (DM-Count's criterion) |
The original PET and DM-Count training scripts select the best checkpoint by its score on the test set, which makes test results optimistic. Here the checkpoint was chosen on held-out training photos, so the test set stayed unseen until the final evaluation.
Evaluation protocol
- Test sets: ShanghaiTech Part A (182 photos) and Part B (316 photos), 498 in total.
- One model for both parts (published PET and DM-Count results train a separate model per part).
- Images larger than 2048 px on the long side are downscaled before inference.
- Metrics: MAE per part, and count accuracy as defined above.
For context, PET's Part A MAE of 58.5 is slightly better than the 59.7 reported in the DM-Count paper and behind the 49.1 reported in the PET paper, which selected its checkpoint on the test set and trained a model for each part.
Intended use
- Estimating how many people are in an image or video frame, and where they are concentrated, so that crowd density (people per m²) can be monitored for safety at stations, religious gatherings, festivals, stadiums and events.
- Research and teaching in crowd counting.
Out-of-scope use
- Surveillance or tracking of individuals. The models output counts and head positions, not identities, and must not be combined with face recognition or other identification systems.
- Any automated decision about people without a human in the loop. Crowd Shield's warnings are prompts for trained staff to look and act.
- Commercial use (see Licence).
- Safety-critical deployment in a new location without first checking accuracy on footage from that location.
Limitations and bias
- Tested only on ShanghaiTech so far. The photos come from China; Indian crowds differ in clothing, head coverings, camera angles, lighting and density. Accuracy on Indian scenes is not yet measured (see India evaluation above).
- Very large crowds: on photos with 1,000+ people, DM-Count is slightly more accurate than PET (85% vs 83%).
- Count correction: the power-law correction was fitted on 70 photos from the same benchmark and may not transfer to other cameras or scenes.
- Single images: each frame is counted independently. Densities in people per m² also need a calibrated, fixed camera; that step is done by the Crowd Shield app, not by these models.
How to use
The simplest route is the Crowd Shield code, which builds the networks and downloads and checksums the weights on first use:
git clone https://github.com/khushi-git-7/Crowd_shield
cd Crowd_shield
pip install -r requirements.txt
import cv2
from crowdshield.points import count_points # PET + count correction
from crowdshield.density import estimate_density # DM-Count
img = cv2.imread("crowd.jpg") # BGR image
pet = count_points(img)
print(pet["count"]) # corrected head count
print(pet["raw_count"]) # number of predicted head points
print(pet["points"][:5]) # head positions (row, column) in pixels
dm = estimate_density(img)
print(dm["count"]) # density-map count
To download the weight files directly from this repository:
from huggingface_hub import hf_hub_download
pet_path = hf_hub_download("Khushi-7/crowd-shield-counting", "pet_shab.pth")
dm_path = hf_hub_download("Khushi-7/crowd-shield-counting", "dmcount_shab.pth")
pet_shab.pth is a PET training checkpoint (the weights are under the "model"
key) and loads into the network in crowdshield/pet. dmcount_shab.pth is a
plain state_dict for the network in crowdshield/density.py.
Licence
PET's and DM-Count's code are MIT-licensed. PET's authors ask that it be used for academic purposes, and ShanghaiTech is a research dataset, so these weights are released for research and education only, not commercial use.
Citation
If you use these models, please cite Crowd Shield and the original works:
@misc{jain2026crowdshield,
title = {Crowd Shield: crowd counting and density warnings for crowd safety in India},
author = {Jain, Khushi},
year = {2026},
howpublished = {\url{https://github.com/khushi-git-7/Crowd_shield}}
}
@inproceedings{liu2023pet,
title = {Point-Query Quadtree for Crowd Counting, Localization, and More},
author = {Liu, Chengxin and Lu, Hao and Cao, Zhiguo and Liu, Tongliang},
booktitle = {Proceedings of the IEEE/CVF International Conference on Computer Vision (ICCV)},
pages = {1676--1685},
year = {2023}
}
@inproceedings{wang2020dmcount,
title = {Distribution Matching for Crowd Counting},
author = {Wang, Boyu and Liu, Huidong and Samaras, Dimitris and Nguyen, Minh Hoai},
booktitle = {Advances in Neural Information Processing Systems (NeurIPS)},
year = {2020}
}
@inproceedings{zhang2016shanghaitech,
title = {Single-Image Crowd Counting via Multi-Column Convolutional Neural Network},
author = {Zhang, Yingying and Zhou, Desen and Chen, Siqin and Gao, Shenghua and Ma, Yi},
booktitle = {Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition (CVPR)},
pages = {589--597},
year = {2016}
}
Acknowledgements
Built on PET, DM-Count and the ShanghaiTech dataset. Trained on free Kaggle GPUs. Models trained and evaluated by Khushi Jain.
Evaluation results
- MAE on ShanghaiTech Part Atest set Crowd Shield evaluation58.500
- Count accuracy (%) on ShanghaiTech Part Atest set Crowd Shield evaluation86.500
- MAE on ShanghaiTech Part Btest set Crowd Shield evaluation9.000
- Count accuracy (%) on ShanghaiTech Part Btest set Crowd Shield evaluation92.700
- MAE on ShanghaiTech Part Atest set Crowd Shield evaluation70.100
- Count accuracy (%) on ShanghaiTech Part Atest set Crowd Shield evaluation83.800
- MAE on ShanghaiTech Part Btest set Crowd Shield evaluation16.900
- Count accuracy (%) on ShanghaiTech Part Btest set Crowd Shield evaluation86.400
