Skip to content

feat(detection): let zones follow camera motion with coord_transform - #2657

Merged
Borda merged 6 commits into
roboflow:developfrom
kari-pikkarainen:feat/zone-coord-transform
Oct 16, 2026
Merged

Borda merged 6 commits into
roboflow:developfrom
kari-pikkarainen:feat/zone-coord-transform

Conversation

@kari-pikkarainen

@kari-pikkarainen kari-pikkarainen commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

Description

PolygonZone and LineZone assume a fixed camera. With a panning camera, a parked car drifts across the frame and can be counted as entering a zone or crossing a line.

This PR adds an optional coord_transform to PolygonZone.trigger and LineZone.trigger. The zone stays defined in a reference frame, and detection anchors are mapped into it with coord_transform.rel_to_abs before the existing tests.

Motivation and Context

Refs #2656 (the counting part; drawing would follow separately).

Changes Made

  • coord_transform=None on both trigger methods. None keeps the current behaviour.
  • Anchors that map to non-finite or out-of-bounds coordinates are not counted. LineZone keeps its crossing history in reference coordinates.
  • sv.CoordinatesTransformation: a typing.Protocol with rel_to_abs and abs_to_rel, the method names trackers and norfair use. No new dependency.
  • Docs: geometry reference entry, a short how-to section and a changelog entry.

Out of scope: annotators still draw zones at their fixed coordinates.

Testing

  • uv run pytest, with and without OpenCV, and uv run pre-commit run.
  • New tests use explicit expected values: a crossing counted in reference coordinates, a parked object under a moving line, and NaN, inf and far anchors.
  • Checked locally with trackers 2.6.1: MotionEstimator transformations work as coord_transform for both triggers.

Additional Notes

Drawing zones at mapped positions can follow in a separate PR if this direction is accepted.

Drafted with AI assistance (Claude Code). I reviewed the code and tests before opening this PR.

🤖 Generated with Claude Code

kari-pikkarainen added a commit to kari-pikkarainen/supervision that referenced this pull request Oct 3, 2026
…oboflow#2657

- Annotators clip the mapped line (Liang-Barsky) or polygon
  (Sutherland-Hodgman) to 4x the frame size along its own edges, in exact
  fractions, so near-horizon and far-translated geometry keeps its
  projected direction or draws nothing instead of crashing or wrapping.
- LineZoneAnnotator rounds mapped end points with np.rint.
- MatrixTransform normalises the matrix sign so k * H maps like H; its
  matrix and inverse_matrix attributes are read-only.
- coord_transform=None is unchanged.
- Tests: pixel probes for near-horizon lines and polygons (also with a
  trackers-style w-clamping transform), NaN frames skipped by LineZone,
  require_all_anchors with a transform; duplicate tests removed.
- Docs: shorter changelog entry linked to roboflow#2657, docstrings and how-to.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kari-pikkarainen

kari-pikkarainen commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor Author

Note: since the PR was trimmed to the trigger API, this demo installs the earlier full version (branch feat/zone-coord-transform-full), which also includes annotator support and sv.MatrixTransform planned as follow-ups.

Colab demo of this API (CPU only, no API key; ~15 s plus a 175 MB video download): Open in Colab

  • Part A (synthetic): a camera pans, tilts and rolls over a scene with a known matrix per frame. Without coord_transform a parked object is "in zone" on 13/60 frames and is falsely counted as crossing the line; with sv.MatrixTransform it is in the zone on 60/60 frames and only the real crossing is counted.
  • Part B (real footage): VideoAssets.BEACH drone clip with trackers.MotionEstimator as coord_transform: the zone stays on the lifeguard tower on 200/200 frames (72/200 without).

Source: gist. It installs supervision from this PR's branch.

Prepared with AI assistance (Claude Code).

kari-pikkarainen added a commit to kari-pikkarainen/supervision that referenced this pull request Oct 6, 2026
…oboflow#2657

- Annotators clip the mapped line (Liang-Barsky) or polygon
  (Sutherland-Hodgman) to 4x the frame size along its own edges, in exact
  fractions, so near-horizon and far-translated geometry keeps its
  projected direction or draws nothing instead of crashing or wrapping.
- LineZoneAnnotator rounds mapped end points with np.rint.
- MatrixTransform normalises the matrix sign so k * H maps like H; its
  matrix and inverse_matrix attributes are read-only.
- coord_transform=None is unchanged.
- Tests: pixel probes for near-horizon lines and polygons (also with a
  trackers-style w-clamping transform), NaN frames skipped by LineZone,
  require_all_anchors with a transform; duplicate tests removed.
- Docs: shorter changelog entry linked to roboflow#2657, docstrings and how-to.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kari-pikkarainen
kari-pikkarainen force-pushed the feat/zone-coord-transform branch from 1e3f3be to db55597 Compare October 6, 2026 14:55
kari-pikkarainen added a commit to kari-pikkarainen/supervision that referenced this pull request Oct 6, 2026
…oboflow#2657

- Annotators clip the mapped line (Liang-Barsky) or polygon
  (Sutherland-Hodgman) to 4x the frame size along its own edges, in exact
  fractions, so near-horizon and far-translated geometry keeps its
  projected direction or draws nothing instead of crashing or wrapping.
- LineZoneAnnotator rounds mapped end points with np.rint.
- MatrixTransform normalises the matrix sign so k * H maps like H; its
  matrix and inverse_matrix attributes are read-only.
- coord_transform=None is unchanged.
- Tests: pixel probes for near-horizon lines and polygons (also with a
  trackers-style w-clamping transform), NaN frames skipped by LineZone,
  require_all_anchors with a transform; duplicate tests removed.
- Docs: shorter changelog entry linked to roboflow#2657, docstrings and how-to.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kari-pikkarainen
kari-pikkarainen force-pushed the feat/zone-coord-transform branch from db55597 to 523c3af Compare October 6, 2026 14:57
@codecov

codecov Bot commented Oct 6, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94%. Comparing base (30354bf) to head (bcb37c2).
⚠️ Report is 1 commits behind head on develop.

Additional details and impacted files
@@           Coverage Diff           @@
##           develop   #2657   +/-   ##
=======================================
  Coverage       94%     94%           
=======================================
  Files           83      83           
  Lines        13459   13489   +30     
=======================================
+ Hits         12642   12672   +30     
  Misses         817     817           
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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.

🟢 Approval recommended

The implementation preserves backward compatibility and covers transformed, invalid, and boundary behaviors, with only a minor test-ID convention issue remaining.

1 open finding
What changed in this PR

Adds camera-motion-aware coordinate transforms to polygon and line zone detection while preserving existing behavior by default.

Changes:

  • Introduces and exports CoordinatesTransformation.
  • Maps detection anchors into reference-frame coordinates before zone checks.
  • Adds tests, API documentation, usage guidance, and a changelog entry.

Assessment: Code quality 4/5; testing 4/5; documentation 5/5.

File Description
tests/​helpers.py Adds reusable test transforms.
tests/​detection/​test_polygonzone.py Tests transformed polygon-zone anchors and invalid coordinates.
tests/​detection/​test_line_counter.py Tests transformed crossing history and invalid anchors.
src/​supervision/​geometry/​core.py Defines the transformation protocol and mapping helper.
src/​supervision/​detection/​tools/​polygon_zone.py Applies transforms before polygon membership checks.
src/​supervision/​detection/​line_zone.py Applies transforms while retaining reference-frame crossing state.
src/​supervision/​__init__.py Exports the new public protocol.
docs/​utils/​geometry.md Adds protocol API documentation.
docs/​how_to/​count_in_zone.md Documents moving-camera usage.
docs/​changelog.md Records the feature.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread tests/detection/test_line_counter.py
@Borda

Borda commented Oct 12, 2026

Copy link
Copy Markdown
Member

@kari-pikkarainen, is this still WIP or ready for review? 🦝

Add an optional per-call `coord_transform` to `PolygonZone.trigger` and
`LineZone.trigger`. Zones stay in reference-frame coordinates: anchors
are mapped with `rel_to_abs` before the existing inside and side tests,
so `LineZone` keeps its crossing history in one coordinate system.
Anchors that map to non-finite or out-of-bounds coordinates are not
counted. `None` keeps the current behaviour; drawing is unchanged.

- `sv.CoordinatesTransformation`: `typing.Protocol` with `rel_to_abs`
  and `abs_to_rel`, the method names used by trackers and norfair.
- Docs: geometry reference entry and a short how-to section.

Refs roboflow#2656

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kari-pikkarainen
kari-pikkarainen force-pushed the feat/zone-coord-transform branch from eb2048b to 3fa1524 Compare October 12, 2026 15:59
@kari-pikkarainen
kari-pikkarainen marked this pull request as ready for review October 12, 2026 15:59
@kari-pikkarainen

Copy link
Copy Markdown
Contributor Author

Ready for review now. I trimmed it to the counting part: coord_transform on PolygonZone.trigger and LineZone.trigger, plus the sv.CoordinatesTransformation protocol (same method names as trackers). Drawing zones at mapped positions would be a separate follow-up PR if this direction works for you.

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.

🟢 Approval recommended

The implementation and edge-case coverage are sound, with only minor stale documentation metadata remaining.

1 open finding
1 resolved since last review

🧠 Review effort: Balanced

Comment thread docs/how_to/count_in_zone.md
kari-pikkarainen and others added 2 commits October 13, 2026 13:41
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Changes:
- Validate transformed anchor coordinates against continuous mask bounds before pixel rounding, so fractional negatives cannot hit edge pixels.
- Add a semantic regression case and a PR-linked changelog note.

Impact:
- PolygonZone.trigger follows documented out-of-bounds behavior for transformed anchors.
- Default coord_transform=None behavior stays unchanged.

Verification:
- Regression and focused PolygonZone suite passed: 32 passed.
- Final gates passed lint, format, mypy, full tests (5,454 passed, 79 skipped, 93% coverage), and diff review.

Residual limits:
- G1 historical review blueprint isolation cannot be established retroactively.
- G2 real trackers MotionEstimator integration remains unexecuted because trackers is not installed or project-declared; the remediation report remains fail.

---

Co-authored-by: Codex <codex@openai.com>
Changes:
- Integrate develop detection indexing, integer box arithmetic, keypoint selection, grayscale annotation, and NumPy rasterization fixes with their regression tests.
- Integrate metrics matching performance, precision, configurable detection limits, and video shutdown fixes.
- Integrate target test typing, dependency metadata, review guidance, notebooks, and documentation updates.
- Preserve both branches' unreleased changelog entries and refresh its modification date; retain transformed-zone test helpers alongside target annotations.

Impact:
- Bring camera-motion counting onto the fetched develop implementation while preserving its protocol, counting behavior, tests, and documentation.
- Resolve the changelog collision without dropping either branch's release notes.

Verification:
- Focused polygon and line zone tests: 134 passed.
- Full pytest with coverage: 5676 passed, 105 skipped, 39 warnings; 94% coverage.
- Repository-wide pre-commit, format, mypy, and staged diff checks passed.
- Reviewed all 44 staged paths: 42 match target exactly; helper auto-merge and changelog union verified.

Residual limits:
- Existing review lacks independent reviewer coverage; no new independent review was performed.
- Optional external motion-estimator integration was not rerun; Codemap provider unavailable.
- Changes remain local; no remote publication.

---

Co-authored-by: Codex <codex@openai.com>
Borda
Borda previously approved these changes Oct 16, 2026
@Borda
Borda merged commit 6ecb279 into roboflow:develop Oct 16, 2026
35 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants