Skip to main content

NWB extension to store pose estimation data

Project description

ndx-pose Extension for NWB

PyPI version

ndx-pose is a standardized format for storing pose estimation data in NWB, such as from DeepLabCut and SLEAP. Please post an issue or PR to suggest or add support for another pose estimation tool.

Data types overview

This extension consists of several new neurodata types. They are divided into two main categories:

  1. Pose estimation data: This includes the estimated positions of body parts (keypoints) over time, along with metadata about the pose estimation process.
  2. Training data: This includes ground truth data for training pose estimation models, such as labeled images and

Pose estimation data types:

  • Skeleton which stores the relationship between the body parts (nodes and edges).
  • Skeletons which is a container that stores multiple Skeleton objects.
  • PoseEstimationSeries which stores the estimated positions (x, y) or (x, y, z) of a body part over time as well as the confidence/likelihood of the estimated positions.
  • PoseEstimation which stores the estimated position data (PoseEstimationSeries) for multiple body parts, computed from the same video(s) with the same tool/algorithm.

Training data types:

  • SkeletonInstance which stores the estimated positions and visibility of the body parts for a single frame.
  • TrainingFrame which stores the ground truth data for a single frame. It contains SkeletonInstance objects and references a frame of a source video (ImageSeries). The source videos can be stored internally as data arrays or externally as files referenced by relative file path.
  • TrainingFrames which is a container that stores multiple TrainingFrame objects.
  • SourceVideos which is a container that stores multiple ImageSeries objects representing source videos used in training.
  • PoseTraining which is a container that stores the ground truth data (TrainingFrames) and source videos (SourceVideos) used to train the pose estimation model.

It is recommended to place the Skeletons, PoseEstimation, and PoseTraining objects in an NWB processing module named "behavior", as shown below.

Installation

pip install "ndx-pose"

Development installation

Development dependencies are defined as PEP 735 dependency groups in pyproject.toml. Installing them requires pip 25.1 or later. To set up an editable install with the development tools (tests, docs, and linters), run:

git clone https://github.com/rly/ndx-pose.git
cd ndx-pose
pip install -e . --group dev

The test, docs, and min-reqs groups can be installed individually with pip install -e . --group <name>.

Usage examples

  1. Example writing pose estimates (keypoints) to an NWB file.

  2. Example writing training data to an NWB file.

Handling pose estimates for multiple subjects

NWB files are designed to store data from a single subject and have only one root-level Subject object. As a result, ndx-pose was designed to store pose estimates from a single subject. Pose estimates data from different subjects should be stored in separate NWB files.

Training images can involve multiple skeletons, however. These training images may be the same across subjects, and therefore the same across NWB files. These training images should be duplicated between files.

Resources

Utilities to convert DLC output to/from NWB: https://github.com/DeepLabCut/DLC2NWB

  • For multi-animal projects, one NWB file is created per animal. The NWB file contains only a PoseEstimation object under /processing/behavior. That PoseEstimation object contains PoseEstimationSeries objects, one for each body part, and general metadata about the pose estimation process, skeleton, and videos. The PoseEstimationSeries objects contain the estimated positions for that body part for a particular animal.

Utilities to convert SLEAP pose tracking data to/from NWB: https://github.com/talmolab/sleap-io

Keypoint MoSeq: https://github.com/dattalab/keypoint-moseq

  • Supports read of PoseEstimation objects from NWB files.

NeuroConv: https://neuroconv.readthedocs.io/en/main/conversion_examples_gallery/conversion_example_gallery.html#behavior

  • NeuroConv supports converting data from DeepLabCut, SLEAP (using sleap_io described above), and LightningPose to NWB. It also supports appending pose estimation data to an existing NWB file.

Ethome: Tools for machine learning of animal behavior: https://github.com/benlansdell/ethome

  • Supports read of PoseEstimation objects from NWB files.

Related work:

Several NWB datasets use ndx-pose 0.1.1:

Several open-source conversion scripts on GitHub also use ndx-pose.

Diagram of pose estimation types

%%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#ffffff', "primaryBorderColor': '#144E73', 'lineColor': '#D96F32'}}}%%

classDiagram
    direction LR
    namespace ndx-pose {
        class PoseEstimationSeries{
            <<SpatialSeries>>
            name : str
            description : str
            timestamps : array[float; dims [frame]]
            data : array[float; dims [frame, [x, y]] or [frame, [x, y, z]]]
            confidence : array[float; dims [frame]]
            reference_frame: str
        }

        class PoseEstimation {
            <<NWBDataInterface>>
            name : str
            description : str, optional
            original_videos : array[str; dims [file]], optional
            labeled_videos : array[str; dims [file]], optional
            dimensions : array[uint, dims [file, [width, height]]], optional
            scorer : str, optional
            source_software : str, optional
            source_software__version : str, optional
            PoseEstimationSeries
            Skeleton, link
            Device, link
            source_video : ImageSeries, link, optional
            labeled_video : ImageSeries, link, optional
        }

        class Skeletons {
            <<NWBDataInterface>>
            Skeleton
        }

        class Skeleton {
            <<NWBDataInterface>>
            name : str
            nodes : array[str; dims [body part]]
            edges : array[uint; dims [edge, [node, node]]]
            subject: link (to pynwb.Subject), optional
        }

    }

    class Device
    class ImageSeries

    PoseEstimation --o PoseEstimationSeries : contains 0 or more
    PoseEstimation --> Skeleton : links to
    PoseEstimation --> Device : links to
    PoseEstimation --> ImageSeries : links to
    Skeletons --o Skeleton : contains 0 or more

Diagram of all types

%%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#ffffff', "primaryBorderColor': '#144E73', 'lineColor': '#D96F32'}}}%%

classDiagram
    direction LR
    namespace ndx-pose {
        class PoseEstimationSeries{
            <<SpatialSeries>>
            name : str
            description : str
            timestamps : array[float; dims [frame]]
            data : array[float; dims [frame, [x, y]] or [frame, [x, y, z]]]
            confidence : array[float; dims [frame]]
            reference_frame: str
        }

        class PoseEstimation {
            <<NWBDataInterface>>
            name : str
            description : str, optional
            original_videos : array[str; dims [file]], optional
            labeled_videos : array[str; dims [file]], optional
            dimensions : array[uint, dims [file, [width, height]]], optional
            scorer : str, optional
            source_software : str, optional
            source_software__version : str, optional
            PoseEstimationSeries
            Skeleton, link
            Device, link
            source_video : ImageSeries, link, optional
            labeled_video : ImageSeries, link, optional
        }

        class Skeleton {
            <<NWBDataInterface>>
            name : str
            nodes : array[str; dims [body part]]
            edges : array[uint; dims [edge, [node, node]]]
        }

        class TrainingFrame {
            <<NWBDataInterface>>
            name : str
            annotator : str, optional
            source_video_frame_index : uint, optional
            skeleton_instances : SkeletonInstances
            source_video : ImageSeries, link, optional
            source_frame : Image, link, optional
        }

        class SkeletonInstance {
            <<NWBDataInterface>>
            id: uint, optional
            node_locations : array[float; dims [body part, [x, y]] or [body part, [x, y, z]]]
            node_visibility : array[bool; dims [body part]], optional
            Skeleton, link
        }

        class TrainingFrames {
            <<NWBDataInterface>>
            TrainingFrame
        }

        class SkeletonInstances {
            <<NWBDataInterface>>
            SkeletonInstance
        }

        class SourceVideos {
            <<NWBDataInterface>>
            ImageSeries
        }

        class Skeletons {
            <<NWBDataInterface>>
            Skeleton
        }

        class PoseTraining {
            <<NWBDataInterface>>>
            training_frames : TrainingFrames, optional
            source_videos : SourceVideos, optional
        }

    }

    class Device
    class ImageSeries
    class Image

    PoseEstimation --o PoseEstimationSeries : contains 0 or more
    PoseEstimation --> Skeleton : links to
    PoseEstimation --> Device : links to
    PoseEstimation --> ImageSeries : links to

    PoseTraining --o TrainingFrames : contains
    PoseTraining --o SourceVideos : contains

    TrainingFrames --o TrainingFrame : contains 0 or more

    TrainingFrame --o SkeletonInstances : contains
    TrainingFrame --> ImageSeries : links to
    TrainingFrame --> Image : links to

    SkeletonInstances --o SkeletonInstance : contains 0 or more
    SkeletonInstance --o Skeleton : links to

    SourceVideos --o ImageSeries : contains 0 or more

    Skeletons --o Skeleton : contains 0 or more

Contributors

  • @rly
  • @bendichter
  • @AlexEMG
  • @roomrys
  • @CBroz1
  • @h-mayorquin
  • @talmo
  • @eberrigan
  • @pauladkisson

This extension was created using ndx-template.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ndx_pose-0.3.0.tar.gz (101.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ndx_pose-0.3.0-py3-none-any.whl (16.0 kB view details)

Uploaded Python 3

File details

Details for the file ndx_pose-0.3.0.tar.gz.

File metadata

  • Download URL: ndx_pose-0.3.0.tar.gz
  • Upload date:
  • Size: 101.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.5

File hashes

Hashes for ndx_pose-0.3.0.tar.gz
Algorithm Hash digest
SHA256 4b356c730bda0d273b49e44576343162be26f42c292662d7358efebd252324cb
MD5 e321dedeb9c978e2f194b1a18243dda7
BLAKE2b-256 99015069add7735b754b543493d97c9d994b4b591d7a22f113388b63471b19ea

See more details on using hashes here.

File details

Details for the file ndx_pose-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: ndx_pose-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 16.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.5

File hashes

Hashes for ndx_pose-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9ba50c8869f8b7817ff7d83c9c97d40655c123f0f1273b4e65ce34367c12c20e
MD5 ec8c689b001fab0453be540d13adc4ed
BLAKE2b-256 6b41015b830d4816df0dedadf6d5e32dda648b0627f798f8099db568d5852f9f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page