Skip to content

fix(annotators): avoid divide-by-zero in HeatMapAnnotator on empty detections#2269

Merged
Borda merged 3 commits into
roboflow:developfrom
Ace3Z:fix/heatmap-annotator-empty-detections
May 26, 2026
Merged

fix(annotators): avoid divide-by-zero in HeatMapAnnotator on empty detections#2269
Borda merged 3 commits into
roboflow:developfrom
Ace3Z:fix/heatmap-annotator-empty-detections

Conversation

@Ace3Z

@Ace3Z Ace3Z commented May 25, 2026

Copy link
Copy Markdown
Contributor

Calling HeatMapAnnotator.annotate(...) on a fresh annotator with empty detections (e.g. the first few frames of a video before the model produces output) raises RuntimeWarning: invalid value encountered in divide. self.heat_mask is all zeros, so temp / temp.max() divides by zero, and the resulting nan/inf flows through the rest of the function.

Minimal repro:

import warnings
import numpy as np
import supervision as sv

warnings.simplefilter("error", RuntimeWarning)
annotator = sv.HeatMapAnnotator()
scene = np.zeros((100, 100, 3), dtype=np.uint8)
annotator.annotate(scene=scene, detections=sv.Detections.empty())
# RuntimeWarning: invalid value encountered in divide

Skip the normalisation step when temp.max() == 0; the resulting all-zero temp filters out via the self.heat_mask.astype(np.uint8) > 0 mask check below, so the scene is returned unchanged.

tests/annotators/test_core.py::TestHeatMapAnnotator::test_annotate_with_no_detections_does_not_warn covers the regression: it converts RuntimeWarning to an error and asserts the call succeeds with the scene unchanged.

…tections

When HeatMapAnnotator is called on a fresh annotator with empty detections
(common on the first frames of a video before the model produces any output),
self.heat_mask is all zeros, so temp / temp.max() raises
RuntimeWarning: invalid value encountered in divide and produces nan/inf
in-flight. Skip the normalisation when temp.max() == 0; the resulting
all-zero heat mask filters out via the > 0 check below, so the scene is
returned unchanged.
@Ace3Z Ace3Z requested a review from SkalskiP as a code owner May 25, 2026 09:43
@CLAassistant

CLAassistant commented May 25, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a RuntimeWarning: invalid value encountered in divide in HeatMapAnnotator.annotate(...) when called with empty detections on a fresh annotator, ensuring the scene is returned unchanged without emitting warnings.

Changes:

  • Guard heatmap normalization to avoid dividing by zero when the heatmask maximum is 0.
  • Add a regression test that converts RuntimeWarning to an error and verifies empty detections do not warn and do not modify the scene.

Quality Assessment (n/5):

  • Code quality: 4/5
  • Testing: 5/5
  • Documentation: 5/5

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
src/supervision/annotators/core.py Skips normalization when temp.max() == 0 to prevent divide-by-zero warnings on empty heat masks.
tests/annotators/test_core.py Adds a regression test ensuring HeatMapAnnotator does not warn and returns an unchanged image on empty detections.

Comment thread src/supervision/annotators/core.py Outdated
@codecov

codecov Bot commented May 26, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 78%. Comparing base (fb2dec9) to head (3acea90).

Additional details and impacted files
@@           Coverage Diff           @@
##           develop   #2269   +/-   ##
=======================================
  Coverage       78%     78%           
=======================================
  Files           66      66           
  Lines         8410    8412    +2     
=======================================
+ Hits          6552    6580   +28     
+ Misses        1858    1832   -26     
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@Ace3Z

Ace3Z commented May 26, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the autofix, the regression test still passes locally.

…or coverage

- Fix `kernel_size: int = 25` → `int | None = 25`; document None disables blur
- Add Note to annotate docstring: empty detections returns scene unchanged
- Add happy path test: single detection must produce visible heat output
- Add stateful tests: empty→real and real→empty sequence coverage

/review findings by foundry:linting-expert, foundry:doc-scribe, foundry:qa-specialist
(report: .reports/review/2026-05-26T19-42-53Z/review-report.md)

---
Co-authored-by: Claude Code <noreply@anthropic.com>
@Borda Borda merged commit 2fdb970 into roboflow:develop May 26, 2026
26 checks passed
Borda added a commit to Ace3Z/supervision that referenced this pull request May 27, 2026
…e-dtype

Bring PR branch up to date with upstream develop (HeatMapAnnotator divide-by-zero fix, roboflow#2269).

---
Co-authored-by: Claude Code <noreply@anthropic.com>
@Borda Borda mentioned this pull request Jun 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants