
Estimate Density Map Peaks
Density-map peak picker. Reads a {{type:DensityMap}} plus a {{type:UInt64}} target count, finds local maxima inside a {{param:window_size}}-by-{{param:window_size}} neighbourhood via morphological dilation + connected components, sorts peaks by density value, and emits the top-N as {{type:[Point<Double>]}}.
How it fits
{{type:DensityMap}} --+
+--> {{component:estimate_density_map_peaks}} --> {{type:[Point<Double>]}}
{{type:UInt64}} --+ (top-N peaks by density, capped at the supplied count)
Pick this as the bridge between a heatmap-style counter (like {{component:estimate_crowd_count}}) and any downstream that expects discrete points — zone counters, visualisers, trackers, geometric gates.
Typical backends
- Crowd points overlay: {{component:estimate_crowd_count}} -> {{component:estimate_density_map_peaks}} -> {{component:visualize}}.
- Per-zone crowd counter: {{component:estimate_crowd_count}} -> {{component:estimate_density_map_peaks}} -> {{component:detect_object_containment}} -> {{component:send_object_counts_mqtt}}.
- Density inspection: {{component:estimate_crowd_count}} -> {{component:estimate_density_map_peaks}} -> {{component:visualize_density_map}}.
Caveats
- {{param:window_size}} controls how close two peaks can sit. The default
4works for medium crowds; lower it for very far-away targets to avoid merging adjacent individuals into one peak, raise it to suppress noise in sparser scenes.0aborts startup with a "window_size must be positive" error. - The number of returned points is CAPPED at the supplied head count. If the density map has fewer distinct peaks than the count, fewer points come out — there is NO padding to the target. If it has more, lower-density peaks are silently dropped.
- A head count of
0short-circuits to an empty {{type:[Point<Double>]}} list without reading the density map. - Peak coordinates are sub-pixel floats in the density-map coordinate frame (which is the source-image resolution as produced by the upstream counter); downstream visualisers can plot them directly on the original frame.
- The {{type:DensityMap}} must have shape
(H, W)withdata.size == H * W; any other shape aborts mid-tick with a shape error. - Peaks are computed via morphological dilation + 4-connected components on the equality mask between the original and dilated maps — multiple pixels tied at the local-max value merge into one peak per connected region (sub-pixel centroid weighted by density).
- A connected-component region whose total density weight is exactly zero is dropped (degenerate region); this can happen when {{type:DensityMap}} contains all-zero patches.
- {{param:window_size}} is captured ONCE at startup; runtime changes have NO effect and require a redeploy.
- Pure CPU; per-tick cost is dominated by the dilation pass and grows linearly with
H * W.
Versions
- 0d8bf04elatestdefaultlinux/amd64
Automated release

