Fix KeyPoints 2D boolean mask indexing (uniform-count selection)#2188
Merged
Fix KeyPoints 2D boolean mask indexing (uniform-count selection)#2188
Conversation
…ce > 0.5]) Agent-Logs-Url: https://github.com/roboflow/supervision/sessions/44a8a907-7f5d-4c67-aa42-56889af86802 Co-authored-by: Borda <6035284+Borda@users.noreply.github.com>
Copilot
AI
changed the title
[WIP] Fix KeyPoints filtering with confidence parameter
Fix KeyPoints 2D boolean mask indexing (e.g. Mar 30, 2026
keypoints[keypoints.confidence > 0.5])
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## develop #2188 +/- ##
=======================================
Coverage 77% 77%
=======================================
Files 62 62
Lines 7615 7637 +22
=======================================
+ Hits 5881 5903 +22
Misses 1734 1734 🚀 New features to boost your workflow:
|
…nts-filtering-issue
- Break error message string at line 686 to stay within 88-char ruff E501 limit - Add explicit npt.NDArray[np.float32] | None annotation on conf_selected; use cast() at the branch assignment to prevent mypy widening to Optional[Any] (mypy 1.19.1 + numpy 2.x stubs treat npt.NDArray as Any, so narrowing via `if conf_selected is not None` requires a concrete type from cast, and the self.confidence access needs its own is-not-None guard inside the loop) [resolve #1] /review finding by sw-engineer (report: _outputs/2026/03/output-review-2026-03-30-5.md): "conf_selected inferred as Optional[Any]; mypy pre-commit hook fails" [resolve #3] /review finding by linting-expert (report: _outputs/2026/03/output-review-2026-03-30-5.md): "ruff E501: line too long (89 > 88) at core.py:686" --- Co-authored-by: Claude Code <noreply@anthropic.com>
[resolve #2] /review finding by linting-expert (report: _outputs/2026/03/output-review-2026-03-30-5.md): "PT011: pytest.raises(ValueError) too broad — missing match= parameter at test_core.py:295" --- Co-authored-by: Claude Code <noreply@anthropic.com>
Validate that the mask shape matches (n_objects, n_keypoints) before processing. A row-count mismatch now raises ValueError with a clear message instead of a confusing IndexError; a column-count mismatch similarly raises ValueError instead of silently producing incorrect results. [resolve #4] /review finding by sw-engineer (report: _outputs/2026/03/output-review-2026-03-30-5.md): "No shape validation between index and self.xy — mismatched masks silently misfilter or raise IndexError" --- Co-authored-by: Claude Code <noreply@anthropic.com>
Four new parametrized cases: - confidence=None path: 2D mask on a KeyPoints with no confidence array - column count mismatch: raises ValueError matching "column count" - row count mismatch: raises ValueError matching "row count" - all-False mask: all rows select 0 keypoints — equal counts (0==0), result has shape (n, 0, 2) [resolve #5] /review finding by qa-specialist (report: _outputs/2026/03/output-review-2026-03-30-5.md): "Missing edge-case tests: confidence=None path, shape-mismatch mask, empty result, all-False mask" --- Co-authored-by: Claude Code <noreply@anthropic.com>
keypoints[keypoints.confidence > 0.5])
Contributor
There was a problem hiding this comment.
Pull request overview
Fixes KeyPoints.__getitem__ behavior when indexing with a 2D boolean mask (e.g., keypoints[keypoints.confidence > 0.5]) by adding explicit handling for (n, m) boolean masks and adding tests for the new behavior.
Changes:
- Added a dedicated
__getitem__branch to support 2D boolean mask filtering of keypoints per object, with validation for shape consistency. - Added parametrized tests covering valid 2D-mask filtering and expected
ValueErrorcases (row/column mismatch and unequal per-row selection counts).
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
src/supervision/key_points/core.py |
Implements 2D boolean mask handling in KeyPoints.__getitem__. |
tests/key_points/test_core.py |
Adds test cases for 2D boolean mask indexing behavior and error conditions. |
Borda
reviewed
Mar 30, 2026
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…vate method Agent-Logs-Url: https://github.com/roboflow/supervision/sessions/c5039033-e508-4f5d-b86e-b9a05ec34151 Co-authored-by: Borda <6035284+Borda@users.noreply.github.com>
…ct test The 2D boolean mask path requires every row to select the same number of keypoints (uniform-count invariant) so the result fits a rectangular (n, k, 2) array. The docstring now explains this clearly and notes that kp[kp.confidence > 0.5] works for n==1 but raises ValueError for n>1 when the threshold yields different keypoint counts per object. Also adds the canonical single-object confidence-filter test case to guard against regressions on the primary advertised use case. --- Co-authored-by: Claude Code <noreply@anthropic.com>
Borda
approved these changes
Mar 30, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes
KeyPoints.__getitem__to handle 2D boolean mask indexing where each row selects the same number of keypoints. Previously this raisedIndexError; it now produces a correct(n, k, 2)result.Use cases that now work
Limitation (documented)
A 2D mask where different rows select different numbers of
Truevalues still raisesValueError— NumPy cannot represent a jagged(n, ?, 2)array. This is the common case when usingkp[kp.confidence > 0.5]with multiple objects (each person may have a different number of high-confidence keypoints). For that pattern process each object individually or zero out low-confidence entries in-place.Changes
KeyPoints.__getitem__/_get_by_2d_bool_mask: New private method handles 2Dnp.ndarrayboolean indices. Applies the mask row-by-row producing a(n, k, 2)result. RaisesValueErrorwith a clear message if rows have different counts or mask shape mismatches.mask.shapeagainst(n_objects, n_keypoints)before processing.confidence=None, shape-mismatch ×2, all-False mask, and the canonical single-objectkp[kp.confidence > 0.5]expression.