Skip to content

Add Optional Key-Point Visibility to draw_keypoints() #8203

@bmmtstb

Description

@bmmtstb

🚀 The feature

I propose an optional key-point visibility flag for ~torchvision.utils.draw_keypoints(), to be able to draw human skeletons with key-points that are not set / visible.
If a key point is marked as invisible, the "dot" and the corresponding connection(s) in the connectivity / skeleton will not be printed for this person on this image. Other people on the same image (num_instances>1) can still have the full skeleton or another set of visible joints.

The visibility input can either be a torch.BoolTensor (or any other Callable[bool]) with the same number of entries K as the keypoints tensor, describing the visibility of each respective key point. If num_instances is bigger than one, there should either be a tensor of shape [num_instances, K] describing every person individually, or one of shape [K] describing all instances within this image at once.

The visibility should be optional and therefore be True / torch.ones((num_instances, K)) by default.

Motivation, pitch

The current issue arises when key point coordinates are set to the origin, e.g., if they are not visible, not found, or otherwise not available.

Lets have a look at the example showing the possibilities of draw_keypoints() over at the docs.

Given the image of the skateboarder, let some (other) model predict the key-point- or joint-coordinates as (x, y, visibility), obtaining the following result:

>>> print(new_keypoints)
tensor([[[208.0176, 214.2409,   1.0000],
         [  0.0000,   0.0000,   0.0000],
         [197.8246, 210.6392,   1.0000],
         [  0.0000,   0.0000,   0.0000],
         [178.6378, 217.8425,   1.0000],
         [221.2086, 253.8591,   1.0000],
         [160.6502, 269.4662,   1.0000],
         [243.9929, 304.2822,   1.0000],
         [138.4654, 328.8935,   1.0000],
         [277.5698, 340.8990,   1.0000],
         [153.4551, 374.5145,   1.0000],
         [  0.0000,   0.0000,   0.0000],
         [226.0053, 370.3125,   1.0000],
         [221.8081, 455.5516,   1.0000],
         [273.9723, 448.9486,   1.0000],
         [193.6275, 546.1933,   1.0000],
         [273.3727, 545.5930,   1.0000]]])

This is the result of the example, just that the left_eye, left_ear, and left_hip are annotated as "not visible" with key point coordinates as (0, 0).

Plotting this result shows three lines connecting the skateboarder with the origin, which doesn't look good. On the left is the original image, on the right the one using new_keypoints which has invisible key points.

skeleton skeleton_issue

Now imagine how that looks for other skeleton structures, like Halpe-FullBody (136 key points) or COCO-WholeBody (133 key points)...

Alternatives

It is possible to remove the "invisible" key points from the the skeleton, by updating the skeleton for every image and using something like:

invisible_indices = torch.argwhere(new_keypoints[0,:,2] == 0)
custom_connect_skeleton = [
    link for link in custom_connect_skeleton if not any(idx in link for idx in invisible_indices)
]
draw_keypoints(person_int, new_keypoints, connectivity=custom_connect_skeleton, ...)

But the "dots" are still printed in the upper left corner (see below), and the whole process is fairly cumbersome. That's because now the skeleton of every human has to be analysed and drawn seperately, due to the fact that the skeletons of different persons might have different exclusions and draw_keypoints() only accepts one connectivity for all instances.

skeleton_issue_fix

Therefore, a second alternative would be to allow passing multiple connectivities, one for each instance. But that still doesn't solve the drawn "dot"s problem and feels less intuitive than the proposed approach.

Additional context

This image is taken from the PoseTrack21 dataset, and shows how a full body skeleton fails when only the upper body gets detected by the bounding box. These are the original annotated key points within the annotated bounding box of the dataset. (Image Source, not publically available: PoseTrack21/images/val/010516_mpii_test/000048.jpg)

example

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions