2026-02-15 17:18:57 +00:00
|
|
|
"""Heatmap generation for video activity visualization."""
|
|
|
|
|
|
|
|
|
|
from typing import List, Tuple
|
|
|
|
|
|
2022-01-09 11:25:22 +00:00
|
|
|
import numpy as np
|
|
|
|
|
from matplotlib import pyplot as plt
|
2022-01-09 19:25:44 +00:00
|
|
|
|
2026-02-15 17:16:45 +00:00
|
|
|
|
2022-01-09 11:25:22 +00:00
|
|
|
class HeatMap:
|
2026-02-15 17:18:57 +00:00
|
|
|
"""
|
|
|
|
|
Generate heatmap visualization of video activity.
|
|
|
|
|
|
|
|
|
|
Creates a heatmap showing areas of movement/activity in a video by
|
|
|
|
|
accumulating contour locations over time.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
def __init__(self, x: int, y: int, contours: List[List[Tuple[int, int, int, int]]], resize_factor: float = 1):
|
|
|
|
|
"""
|
|
|
|
|
Initialize HeatMap.
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
x: Width of the heatmap image
|
|
|
|
|
y: Height of the heatmap image
|
|
|
|
|
contours: List of contour lists, where each contour is (x, y, w, h)
|
|
|
|
|
resize_factor: Factor to scale contours (for upscaling from processed size)
|
|
|
|
|
"""
|
2022-09-11 09:25:36 +00:00
|
|
|
self.image_bw = np.zeros(shape=[y, x, 3], dtype=np.float64)
|
|
|
|
|
self._resize_factor = resize_factor
|
|
|
|
|
self._create_image(contours)
|
2022-01-09 11:25:22 +00:00
|
|
|
|
2026-02-15 17:18:57 +00:00
|
|
|
def _create_image(self, contours: List[List[Tuple[int, int, int, int]]]):
|
|
|
|
|
"""
|
|
|
|
|
Create heatmap image from contours.
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
contours: List of contour lists to accumulate into heatmap
|
|
|
|
|
"""
|
2022-01-09 11:25:22 +00:00
|
|
|
for contour in contours:
|
|
|
|
|
for x, y, w, h in contour:
|
2022-01-09 19:25:44 +00:00
|
|
|
x, y, w, h = (
|
2022-09-11 09:25:36 +00:00
|
|
|
x * self._resize_factor,
|
|
|
|
|
y * self._resize_factor,
|
|
|
|
|
w * self._resize_factor,
|
|
|
|
|
h * self._resize_factor,
|
2022-01-09 19:25:44 +00:00
|
|
|
)
|
2022-09-11 09:25:36 +00:00
|
|
|
self.image_bw[int(y) : int(y + h), int(x) : int(x + w)] += 1
|
2022-01-09 11:25:22 +00:00
|
|
|
|
2022-09-11 09:25:36 +00:00
|
|
|
self.image_bw = np.nan_to_num(self.image_bw / self.image_bw.sum(axis=1)[:, np.newaxis], 0)
|
2022-01-09 11:25:22 +00:00
|
|
|
|
2022-09-11 09:25:36 +00:00
|
|
|
def show_image(self):
|
2026-02-15 17:18:57 +00:00
|
|
|
"""Display the heatmap using matplotlib."""
|
2022-09-11 09:25:36 +00:00
|
|
|
plt.imshow(self.image_bw * 255)
|
2022-01-09 11:25:22 +00:00
|
|
|
plt.show()
|
2022-09-11 09:25:36 +00:00
|
|
|
|
2026-02-15 17:18:57 +00:00
|
|
|
def save_image(self, path: str):
|
|
|
|
|
"""
|
|
|
|
|
Save heatmap to file.
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
path: Output file path for the heatmap image
|
|
|
|
|
"""
|
2026-02-15 17:16:45 +00:00
|
|
|
plt.imsave(path, (255 * self.image_bw).astype(np.uint8))
|