Skip to content

docs(cookbooks): pose augmentation with left/right keypoint remapping - #2537

Open
adhavan18 wants to merge 3 commits into
roboflow:developfrom
adhavan18:feat/pose-flip-cookbook
Open

adhavan18 wants to merge 3 commits into
roboflow:developfrom
adhavan18:feat/pose-flip-cookbook

Conversation

@adhavan18

Copy link
Copy Markdown
Contributor
Before submitting
  • Self-reviewed the code
  • Updated documentation, follow Google-style
  • Added docs entry for autogeneration (if new functions/classes) — no new functions/classes added
  • Added/updated tests
  • All tests pass locally

Description

A self-contained cookbook showing how to augment sv.KeyPoints with a horizontal flip while preserving left/right landmark semantics, as requested.

Type of Change

  • 📝 Documentation update

Motivation and Context

Closes #2519.

sv.KeyPoints.xy has a fixed row order per skeleton: for a COCO-17 pose, row 1 is always left_eye, row 2 always right_eye, and so on. A horizontal flip mirrors coordinates, but Albumentations' HorizontalFlip has no notion of which row is semantically left or right, so after mirroring, row 1 still says left_eye even though its position is now where the right eye visually is. The cookbook makes this concrete and shows the fix.

Changes Made

  • Added docs/notebooks/pose-augmentation-left-right-remapping.ipynb
  • Builds a small deterministic pose (right arm raised, no model or dataset needed)
  • Flips it with A.HorizontalFlip, then fixes the row order by swapping each left/right pair after mirroring
  • Numerically verifies every remapped row against Albumentations' actual pixel-index mirror convention (width - 1 - x)
  • Renders a side-by-side comparison (left joints blue, right red) that makes the bug visible at a glance: the naive flip still colors the raised arm red after mirroring; the corrected version colors it blue

Testing

  • I have tested this code locally
  • I have added unit tests that prove my fix is effective or that my feature works — the notebook's own numeric assertions
  • All new and existing tests pass — executed the full notebook end-to-end via jupyter nbconvert --execute before committing; zero errors, all assertions pass

Screenshots/Videos (optional)

The notebook's own rendered output (visible in the Files changed diff): three panels — original pose, naive flip (still labels the raised arm "right" after mirroring), corrected flip (correctly relabels it "left").

Additional Notes

The issue mentions AlbumentationsX's KeypointParams(label_mapping=...), which automates this exact row swap inside the transform. I deliberately didn't use it here: AlbumentationsX requires torch unconditionally (even for a plain HorizontalFlip), which is a multi-GB install just to demonstrate one kwarg, and works against the issue's own stated goal of a cookbook that "needs no model or dataset download." Doing the remap explicitly with vanilla albumentations keeps the notebook self-contained and, I'd argue, is more instructive for a cookbook — it shows exactly what that option automates rather than hiding it behind a library flag. Happy to add an AlbumentationsX variant alongside this if that's preferred.

@adhavan18
adhavan18 requested a review from SkalskiP as a code owner September 4, 2026 12:46
@review-notebook-app

Copy link
Copy Markdown

Check out this pull request on  ReviewNB

See visual diffs & provide feedback on Jupyter Notebooks.


Powered by ReviewNB

@codecov

codecov Bot commented Sep 4, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 88%. Comparing base (47b090a) to head (2c401c2).

Additional details and impacted files
@@           Coverage Diff           @@
##           develop   #2537   +/-   ##
=======================================
  Coverage       88%     88%           
=======================================
  Files           85      85           
  Lines        12312   12312           
=======================================
+ Hits         10857   10860    +3     
+ Misses        1455    1452    -3     
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@Borda
Borda requested a balanced review from Copilot September 4, 2026 17:31
@Borda Borda added the documentation Improvements or additions to documentation label Sep 4, 2026

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.

🟡 Changes recommended

The cookbook lacks required installation and publication metadata and contains misleading claims about universal keypoint ordering.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Adds a self-contained cookbook demonstrating horizontal pose augmentation with COCO-17 left/right keypoint remapping.

Changes:

  • Implements deterministic horizontal flipping and semantic row remapping.
  • Adds numeric verification and comparative visualization.
  • Uses Supervision keypoint annotators for rendering.

Review scores: Code quality 4/5 · Testing 3/5 · Documentation 2/5

File summaries
File Description
docs/notebooks/pose-augmentation-left-right-remapping.ipynb Adds the pose-remapping cookbook and visualization.
Review details
  • Files reviewed: 1/1 changed files
  • Comments generated: 6
  • Review effort level: Balanced

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

Comment on lines +38 to +41
"import albumentations as A\n",
"import cv2\n",
"import numpy as np\n",
"import supervision as sv"
"id": "48a8a347",
"metadata": {},
"source": [
"# Pose augmentation with left/right keypoint remapping\n",
"source": [
"# Pose augmentation with left/right keypoint remapping\n",
"\n",
"`sv.KeyPoints.xy` has a fixed row order: row 1 is always `left_eye`, row 2 is always `right_eye`, and so on for every left/right pair in the skeleton. A horizontal flip mirrors *coordinates*, but on its own it does nothing about *row order* \u2014 after mirroring, the position that used to hold the left eye is now where the right eye visually is, but row 1 is still labeled `left_eye`.\n",
Comment on lines +27 to +36
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"C:\\Users\\sktam\\AppData\\Local\\Temp\\ccwork\\svenv\\Lib\\site-packages\\tqdm\\auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n",
" from .autonotebook import tqdm as notebook_tqdm\n"
]
}
],
"source": [
"## A deterministic pose\n",
"\n",
"17 points in COCO order \u2014 the order `sv.KeyPoints.from_ultralytics`, `from_inference`, and RF-DETR's pose models already return. The pose has one arm raised so a wrong flip is visibly different from a correct one, not just numerically."
"RIGHT_INDICES = {right for _, right in LEFT_RIGHT_PAIRS}\n",
"\n",
"\n",
"def render(key_points: sv.KeyPoints, canvas: np.ndarray) -> np.ndarray:\n",
Closes roboflow#2519. sv.KeyPoints.xy has a fixed row order per skeleton (row 1 is
always left_eye, row 2 always right_eye, and so on), but a horizontal flip
only mirrors coordinates. Albumentations' HorizontalFlip has no notion of
which row is semantically left or right, so after mirroring, row 1 still
says left_eye even though its position is now where the right eye visually
is.

The cookbook builds a small deterministic pose (right arm raised, no model
or dataset needed), flips it, and shows the fix: after mirroring
coordinates, also swap each left/right pair's row so the label matches the
mirrored side. AlbumentationsX's KeypointParams(label_mapping=...)
automates this same swap inside the transform for larger pipelines; doing
it explicitly here (rather than adding a hard torch dependency just to
demonstrate one kwarg) shows exactly what that option does under the hood,
and keeps the cookbook as self-contained as the issue asked for.

Includes a numeric verification (every remapped row lands exactly where
albumentations' own pixel-index mirror, width - 1 - x, says it should) and
a rendered comparison (left joints blue, right red) that makes the bug
visible: the naive flip still colors the raised arm red after mirroring,
the corrected version colors it blue. Executed end-to-end via jupyter
nbconvert before committing; matches the repo's existing notebooks in
shipping baked-in outputs (mkdocs-jupyter's execute: false renders them
as-is).
- add the missing install cell (supervision, albumentations, opencv-python)
  and open in colab badge, per CONTRIBUTING.md's cookbook checklist
- add the cookbooks.html card so it's discoverable from the cookbooks page
- scope the "row 1 is always left_eye" and "these converters return coco-17"
  claims to coco-17 specifically, since keypoint order actually comes from
  the source model/skeleton
- clear the committed stderr output that leaked a local windows path and an
  unrelated tqdm warning (fixed at the source by installing ipywidgets,
  not just stripped from the diff)
- add a docstring to the render() helper per agents.md
- re-executed end to end so every output is real, not hand-edited
@adhavan18
adhavan18 force-pushed the feat/pose-flip-cookbook branch from c4c7c4a to 6b7f782 Compare September 9, 2026 15:59
@adhavan18

Copy link
Copy Markdown
Contributor Author

addressed all 6 points from the copilot review:

  • added the missing install cell (supervision, albumentations, opencv-python) and open in colab badge
  • added the cookbooks.html card
  • scoped the "row 1 is always left_eye" and "these converters return coco-17" claims to coco-17 specifically, since keypoint order actually comes from the source model/skeleton, not from KeyPoints itself
  • cleared the leaked local windows path in the committed stderr output. fixed at the source (installed ipywidgets so the tqdm warning that triggered it doesn't fire), not just stripped
  • added a docstring to render()
  • rebased onto develop and re-executed the whole notebook end to end so every output is real

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Pose augmentation cookbook with left/right keypoint remapping

3 participants