"""Gaussian density heatmap from car detections.""" import cv2 import numpy as np def generate_heatmap(image: np.ndarray, detections: list[dict]) -> np.ndarray: """Create a density heatmap blended with the original image. Places impulses at detection centers, applies Gaussian blur proportional to average box size, then overlays a JET colormap. """ h, w = image.shape[:2] if not detections: return image.copy() # Compute average box dimension for blur sigma widths = [] heights = [] for det in detections: x1, y1, x2, y2 = det["bbox"] widths.append(x2 - x1) heights.append(y2 - y1) avg_size = (np.mean(widths) + np.mean(heights)) / 2 sigma = max(int(avg_size * 1.5), 1) # Kernel size must be odd ksize = sigma * 6 + 1 if ksize % 2 == 0: ksize += 1 # Place impulses at detection centers heat = np.zeros((h, w), dtype=np.float32) for det in detections: x1, y1, x2, y2 = det["bbox"] cx = int((x1 + x2) / 2) cy = int((y1 + y2) / 2) cx = np.clip(cx, 0, w - 1) cy = np.clip(cy, 0, h - 1) heat[cy, cx] += 1.0 # Gaussian blur to spread the density heat = cv2.GaussianBlur(heat, (ksize, ksize), sigma) # Normalize to 0-255 and apply colormap if heat.max() > 0: heat = (heat / heat.max() * 255).astype(np.uint8) else: heat = heat.astype(np.uint8) colormap = cv2.applyColorMap(heat, cv2.COLORMAP_JET) # Blend with original blended = cv2.addWeighted(image, 0.6, colormap, 0.4, 0) return blended