feat: store keypoints on detections#2290
Conversation
- Update AGENTS.md with detailed API design principles for consistency. - Expand CONTRIBUTING.md to include a new "API Design Principles" section.
Add validated keypoints support to Detections, including slicing, equality, merge, and inner-object merge preservation. Remove the RF-DETR-specific KeyPoints adapter and make VertexEllipseAnnotator rely on caller-selected keypoints instead of an annotator confidence threshold. Co-authored-by: Codex <codex@openai.com>
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## develop #2290 +/- ##
=======================================
Coverage 79% 79%
=======================================
Files 66 66
Lines 8569 8537 -32
=======================================
- Hits 6806 6785 -21
+ Misses 1763 1752 -11 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
This PR extends Supervision’s core detection container to carry per-detection keypoints as a first-class field, updates validation/merge/slicing behavior accordingly, and aligns keypoint annotators + contributor docs with newly documented API design principles (generic, composable APIs; filtering before annotation; no model-quality gates in annotators).
Changes:
- Add
Detections.keypoints(shape(n, K, 2)or(n, K, 3)), with validation plus preservation throughmerge,__getitem__, and inner-merge behavior. - Simplify keypoint annotator API by removing confidence-threshold filtering logic, and remove RF-DETR-specific keypoint conversion utilities/tests to keep the API generic.
- Add “API Design Principles” guidance to contributor/agent documentation to make these expectations explicit and canonical.
Quality Assessment (n/5)
- Code quality: 4/5
- Testing: 3/5
- Docs: 4/5
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
src/supervision/detection/core.py |
Adds keypoints to Detections and preserves it through equality, merge, slicing, and inner-merge. |
src/supervision/validators/__init__.py |
Introduces keypoint-shape validation for Detections and wires it into validate_detections_fields. |
src/supervision/key_points/annotators.py |
Removes annotator-side confidence gating (constructor + annotate logic). |
src/supervision/key_points/core.py |
Removes RF-DETR-specific conversion utilities and associated docs. |
tests/detection/test_core.py |
Adds coverage for keypoints validation, slicing, and merge preservation. |
tests/key_points/test_annotators.py |
Updates tests for annotator API change and shifts filtering responsibility to the caller. |
tests/key_points/test_core.py |
Removes tests tied to the deleted RF-DETR conversion pathway. |
tests/key_points/test_from_rfdetr.py |
Deletes RF-DETR conversion tests (and implicitly the feature). |
AGENTS.md |
Adds canonical API guidance link and clarifies “filter before annotate” expectations. |
.github/CONTRIBUTING.md |
Documents “API Design Principles” as canonical guidance. |
- Document third-channel confidence convention and sv.KeyPoints decision rule in Detections.keypoints Attributes docstring - Add Note to Detections.__iter__ explaining keypoints is intentionally excluded from 6-tuple for API stability - Add Google-style docstring with Args/Raises/Examples to validate_detection_keypoints - Add numeric dtype guard to validate_detection_keypoints to reject object-dtype arrays silently --- Co-authored-by: Claude Code <noreply@anthropic.com>
- Parametrize validate_xy with optional m arg (m=None skips second-dim check) so validate_detection_keypoints delegates shape validation there instead of duplicating it - Add dtype guard (np.issubdtype numeric check) in validate_detection_keypoints before shape check - Raise descriptive ValueError in Detections.merge when keypoints arrays have mismatched (K, channels) shapes instead of propagating generic np.vstack error --- Co-authored-by: Claude Code <noreply@anthropic.com>
…add KeyPoints filter example - Principle 1: add decision rule (Detections.keypoints for box-coincident keypoints, sv.KeyPoints for standalone pose) - Principle 3: add key_points[key_points.confidence > 0.5] example alongside detections slicing example --- Co-authored-by: Claude Code <noreply@anthropic.com>
…pter Converts Detections.keypoints (n, K, 2) or (n, K, 3) to sv.KeyPoints so users can pass detection-attached keypoints to keypoint annotators which accept KeyPoints not raw arrays. When the third channel is present it is stored as confidence. --- Co-authored-by: Claude Code <noreply@anthropic.com>
…ield sets - Add object-dtype case to test_detections_keypoints_validation (exercises new numeric dtype guard) - Add three parametrize cases to test_equal covering matching non-None keypoints, one-sided None, and same-shape different values - Rewrite test_get_instance_variables expected sets to use set(Detections.__dataclass_fields__) instead of hardcoded enumerations so future field additions don't break the test - Fix validate_detection_keypoints to re-raise with keypoints-specific message when validate_xy raises (preserves user-facing error wording) --- Co-authored-by: Claude Code <noreply@anthropic.com>
- Add boolean-mask, slice, and None-keypoints getitem cases - Add three-way merge, all-None merge, and (N,K,2) no-confidence merge cases - Add Detections.empty().keypoints is None regression guard - Strengthen pre-masked-keypoint annotator test: assert top-left pixels unchanged --- Co-authored-by: Claude Code <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 11 out of 11 changed files in this pull request and generated 3 comments.
Comments suppressed due to low confidence (1)
src/supervision/validators/init.py:209
validate_xyvalidates a 3D array (either(n, m, 2/3)or(n, K, 2/3)), but the raised error message currently says "2D". This is confusing for callers and makes debugging shape issues harder.
if not is_valid:
raise ValueError(
f"xy must be a 2D np.ndarray with shape {expected_shape}, but got shape "
f"{actual_shape}"
)
[lint-gate] foundry:linting-expert step-9 fixes: - key_points/core.py: cast detections.class_id to np.int_ in from_detections to satisfy mypy - validators/__init__.py: reformat deprecate import to multi-line style --- Co-authored-by: Claude Code <noreply@anthropic.com>
This pull request introduces several improvements and clarifications to the Supervision library, focusing on API design consistency, enhanced keypoint support in detection containers, and improved documentation. The main changes include the addition of API design principles to the documentation, extension of the
Detectionsclass to support keypoints, and the removal of model-quality gates from annotator constructors.Documentation and API Design Consistency:
.github/CONTRIBUTING.md,AGENTS.md: Added a new "API Design Principles" section and updated agent guidelines to clarify that Supervision APIs should remain generic, composable, and predictable. Emphasized that model integrations should normalize external outputs,from_*methods are for raw external conversions only, and annotators should not filter by model-quality gates. These sections are now referenced as canonical API guidance. [1] [2] [3]Keypoint Support in Detection Containers:
src/supervision/detection/core.py: Extended theDetectionsclass to include akeypointsfield, updated all relevant methods (__init__,__eq__,merge,__getitem__, etc.) to support and correctly merge keypoints, and clarified docstrings to reflect these changes. [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11]Annotator and KeyPoints API Simplification:
src/supervision/key_points/annotators.py: Removed theconfidence_thresholdparameter from annotator constructors and logic, ensuring that annotators only control visual presentation, not data filtering, in line with the new API principles. [1] [2] [3] [4]Internal Cleanup and Refactoring:
src/supervision/key_points/core.py: Removed unused or redundant RF-DETR-specific utility functions and logger usage, streamlining the codebase and documentation. [1] [2] [3] [4]These changes collectively make the API more predictable and easier to use, especially when integrating new models or extending annotation capabilities.
Following the pattern established with Detection has an attribute
mask, so adding also attributekeypoints