vagheshpatel's picture
Sync light-level-anomaly-detection from metro-analytics-catalog
3030a91 verified
|
Raw
History Blame Contribute Delete
4.74 kB
---
license: mit
license_link: LICENSE
library_name: opencv
tags:
- opencv
- intel
- light-level-anomaly
- exposure
- edge-ai
- metro
language:
- en
---
# Light-Level Anomaly Detection
| Property | Value |
|---|---|
| **Category** | Image-Quality Analytics (classical computer vision) |
| **Base Model** | Not applicable -- uses luminance statistics |
| **Source Framework** | OpenCV |
| **Supported Precisions** | Not applicable |
| **Inference Engine** | OpenCV (CPU) |
| **Hardware** | CPU, GPU (OpenCV UMat optional) |
| **Detected Class(es)** | Underexposure, overexposure, sudden light change |
---
## Overview
Light-Level Anomaly Detection is a Metro Analytics use case that monitors the
overall brightness of a camera feed and flags abnormal lighting conditions:
the scene going dark (lights off, lens covered, night), the scene blowing out
(glare, headlights, overexposure), or a sudden change in light level.
It tracks the mean luminance of each frame against a rolling baseline and
raises an event when the level leaves the acceptable band or jumps sharply.
A global luminance signal is best measured directly from pixels, so this use
case intentionally avoids a neural model.
It is a strong building block for real-time alerting use cases.
Typical Metro deployments include:
- **Lighting Fault Detection** -- alert when platform or tunnel lighting fails.
- **Day/Night Transition Handling** -- switch analytics profiles by light level.
- **Exposure QA** -- flag cameras that are blown out or too dark to analyze.
- **Tamper Indicator** -- a covered lens shows up as a sudden drop in light.
---
## Prerequisites
- Python 3.11+
- OpenCV and NumPy
Create and activate a Python virtual environment before running the sample:
```bash
python3 -m venv .venv
source .venv/bin/activate
pip install opencv-python numpy
```
---
## Getting Started
### Download the Sample Video
This use case does not export or quantize a model.
Run the provided script to download the sample test video:
```bash
chmod +x export_and_quantize.sh
./export_and_quantize.sh
```
The script downloads `test_video.mp4` into the current directory.
### OpenCV Sample
The sample below computes the mean luminance of each frame from the V channel
of HSV, compares it against fixed dark/bright bounds and against a rolling
baseline, and classifies each frame as `normal`, `dark`, `bright`, or
`sudden-change`.
The annotated frames are written to `output_opencv.mp4`.
```python
import cv2
import numpy as np
INPUT_VIDEO = "test_video.mp4"
DARK_BOUND = 40.0 # mean luminance below this is underexposed
BRIGHT_BOUND = 215.0 # mean luminance above this is overexposed
JUMP_BOUND = 35.0 # frame-to-frame luminance jump that counts as sudden
cap = cv2.VideoCapture(INPUT_VIDEO)
fps = cap.get(cv2.CAP_PROP_FPS) or 30.0
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
writer = cv2.VideoWriter(
"output_opencv.mp4", cv2.VideoWriter_fourcc(*"mp4v"), fps, (width, height))
prev_level = None
frame_idx = 0
anomalies = 0
while True:
ok, frame = cap.read()
if not ok:
break
frame_idx += 1
v = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)[:, :, 2]
level = float(np.mean(v))
status = "normal"
if level < DARK_BOUND:
status = "dark"
elif level > BRIGHT_BOUND:
status = "bright"
elif prev_level is not None and abs(level - prev_level) >= JUMP_BOUND:
status = "sudden-change"
prev_level = level
if status != "normal":
anomalies += 1
print(f"Frame {frame_idx}: LIGHT ANOMALY ({status}) level={level:.1f}",
flush=True)
color = (0, 255, 0) if status == "normal" else (0, 0, 255)
label = f"level={level:.1f} {status}"
(_, text_height), _ = cv2.getTextSize(
label, cv2.FONT_HERSHEY_SIMPLEX, 5.0, 2)
cv2.putText(frame, label, (10, text_height + 10),
cv2.FONT_HERSHEY_SIMPLEX, 5.0, color, 2)
writer.write(frame)
cap.release()
writer.release()
print(f"Light-level anomalies detected: {anomalies}", flush=True)
```
**Device targets:**
- `"CPU"` -- default for OpenCV luminance statistics.
- `"GPU"` -- wrap frames in `cv2.UMat` to use the OpenCV transparent API on Intel GPUs.
- `"NPU"` -- not applicable; luminance statistics are not a neural workload.
#### Expected Output
![OpenCV expected output](expected_output_openvino.gif)
---
## License
Licensed under the MIT License. See [LICENSE](LICENSE) for details.
## References
- [OpenCV Color Space Conversions](https://docs.opencv.org/4.x/d8/d01/group__imgproc__color__conversions.html)
- [OpenCV Operations on Arrays (mean)](https://docs.opencv.org/4.x/d2/de8/group__core__array.html)