Skip to content

v0.15.0

Latest

Choose a tag to compare

@niksirbi niksirbi released this 09 Mar 12:11
· 4 commits to main since this release
e0fbb2b

To update movement to the latest version, see the update guide.

What's Changed

⚡️ Highlight 1: new example for scaling pose tracks to real-world coordinates

  • Add example for scaling pose tracks to real-world coordinates by @HollyMorley in #827

This new gallery example by @HollyMorley walks through a complete workflow for converting pixel-based pose data to real-world units using a a known reference distance. It demonstrates pre-processing (confidence filtering, interpolation, smoothing), measuring a reference distance in napari, applying movement.transforms.scale(), and computing real-world body measurements and inter-limb distances.

napari_scale_draw-and-measure

Holly is working on a few more examples for our gallery, so keep an eye out for those in the coming releases!

⚡️ Highlight 2: Save and load RoIs via GeoJSON

  • Add ROI save/load functionality via GeoJSON by @niksirbi in #773

Regions of interest (RoIs) can now be saved to and loaded from GeoJSON files using movement.roi.save_rois() and movement.roi.load_rois(). Each RoI is stored as a GeoJSON Feature containing its geometry and properties (name and RoI type), within a FeatureCollection. This makes it easy to persist ROI definitions across sessions and share them with collaborators.

from movement.roi import LineOfInterest, PolygonOfInterest, save_rois, load_rois

# Create 2 RoIs: a polygon and a line
square = PolygonOfInterest([(0, 0), (1, 0), (1, 1), (0, 1)], name="square")
diagonal = LineOfInterest([(0, 0), (1, 1)], name="diagonal")

# Save them to a GeoJSON file
save_rois([square, diagonal], "rois.geojson")

# Load RoIs from a GeoJSON file
rois = load_rois("rois.geojson")
[roi.name for roi in rois]  # returns ["square", "diagonal"]

⚡️ Highlight 3: derive bounding boxes from pose tracks

  • Adds poses_to_bboxes() to movement.transforms to generate 2D bounding by @Edu92337 in #757

Thanks to @Edu92337, you can now compute bounding boxes from sets of keypoints (poses). The new movement.transforms.poses_to_bboxes() function finds the minimum and maximum coordinates across all keypoints for each individual at each time point. The resulting bounding boxes are represented by their centroid (center point position) and shape (width and height).

Suppose poses_ds is a movement poses dataset with a "position" variable containing keypoint coordinates.

from movement.transforms import poses_to_bboxes

# Compute bounding boxes with zero padding
bbox_centroid, bbox_shape = poses_to_bboxes(poses_ds["position"])

# Compute bounding boxes with 10 pixels of padding
bbox_centroid, bbox_shape = poses_to_bboxes(poses_ds["position"], padding=10)

🐛 Bug fixes

📚 Documentation

  • Updated conda installation instructions with pyqt6 by @niksirbi in #825
  • Add "See Also" to load_multiview_dataset docstring by @niksirbi in #824
  • Remove docstring types and use annotations for docs by @ParthChatupale in #727
  • Draft roadmap for 2026 by @niksirbi in #809
  • fix: correct loader param name, path assignment, and spelling in docs by @dhruv1955 in #857

🧹 Housekeeping

  • Remove OSSS announcement banner by @adamltyson in #828
  • Make hide_pooch_hash_logs internal by renaming to _hide_pooch_hash_logs by @Shreecharana24 in #842
  • Use idiomatic xarray coordinate comparison in test_load_poses by @Kayd-06 in #876
  • [pre-commit.ci] pre-commit autoupdate by @pre-commit-ci[bot] in #861
  • Contributors-Readme-Action: Update contributors list by @github-actions[bot] in #856
  • Bump actions/download-artifact from 7 to 8 by @dependabot[bot] in #859
  • Contributors-Readme-Action: Update contributors list by @github-actions[bot] in #880

New Contributors

Full Changelog: v0.14.0...v0.15.0