Wraps (N, D) keypoints (D >= 2; first two columns x, y).
Extra columns (e.g. visibility / angle / scale) are carried through
geometric transforms unchanged; only the x, y coordinates move.
Parameters
dataTensor(N, D) with D >= 2; columns 0 and 1 are x and y.canvas_size(int, int)(H, W) of the image the points index into.Examples
Points move with the image, so they need the canvas they were
measured against:
>>> import lucid, lucid.utils.transforms as T
>>> points = T.Keypoints(lucid.tensor([[4.0, 4.0]]), canvas_size=(32, 32))
>>> sample = {"image": T.Image(lucid.rand(3, 32, 32)), "keypoints": points}
>>> moved = T.HorizontalFlip(p=1.0)(sample)
>>> tuple(moved["keypoints"].data.shape)
(1, 2)
They have to travel with the image. On their own a geometric
transform refuses them — "no image / mask in the sample to derive
transform parameters" — because a flip needs to know the width it is
flipping about, and the canvas size records where the points came
from rather than what they are being mapped into.