Keypoint transform
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 17.9k
- Forks
- 7.3k
- Avg merge
- 1d 15h
- Merged PRs (30d)
- 13
Description
Hi Pytorch community 😄
I started working on keypoint transformation (as was requested in #523).
I worked on it in the context of data augmentation for object detection tasks.
I submitted a proposal in PR #1118, but as @fmassa pointed out, that's not something we can merge without reviewing the design choices.
I've implemented the functionality by changing the signature of the transform.call() method from: def __call__(self, img): to def run(self, img, keypoints): so that every transform can work on a list of keypoints in addition to the image itself.
I've been with keypoints as a point is the most basic element, bounding boxes are defined as points, segmentation mask can be defined as points, facial landmarks are keypoints ...
If we have the ability to transform a point, we have the ability to transform anything.
My goal with that design was to make the data augmentation as straitforward as possible.
I added a wrapper class to transform the XML annotaion from VOCDetection to a keypoint list and fed then to the transform pipeline.
class TransformWrapper(object):
def __init__(self, transforms):
super(TransformWrapper, self).__init__()
self.transforms = transforms
pass
def __call__(self, img, anno):
print(img, anno)
keypoints = []
objs = anno['annotation']['object']
if not isinstance(objs, list):
objs = [objs]
for o in objs:
b = o['bndbox']
x1 = int(b['xmin'])
x2 = int(b['xmax'])
y1 = int(b['ymin'])
y2 = int(b['ymax'])
keypoints.append([x1, x2])
keypoints.append([y1, y2])
img, keypoints = self.transforms(img, keypoints)
for o in objs:
b = o['bndbox']
x = keypoints.pop(0)
b['xmin'] = str(int(x[0]))
b['xmax'] = str(int(x[1]))
y = keypoints.pop(0)
b['ymin'] = str(int(y[0]))
b['ymax'] = str(int(y[1]))
return img, anno
This allows for an usage as simple as
transform = transformWrapper.TransformWrapper(torchvision.transforms.Compose([torchvision.transforms.Resize(600), torchvision.transforms.ToTensor()]))
vocloader = torchvision.datasets.voc.VOCDetection("/home/wilmot_p/DATA/", transforms=transform)
And the annotations comes out with values corresponding to the resized image.
The aim of this thread is to bring up other usecases of keypoint transformation that I may not have though of and that may be imcompatible with this design, so that we can make a sensible design decision that works for everyone. So if you have an oppinion on this matter, please share 😄
Curently, one of the drawbacks of my design is that I broke the interface for Lambda, it use to take only the image as input parameter, it now takes the image and the keypoint list, and that break retro-compatibility.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading PR #1118 and the transform.call interface described in the issue, then inspect torchvision.transforms.Compose and datasets.voc.VOCDetection. Compare the proposed keypoint flow with Lambda's existing image-only interface. Done means reaching an agreed design that supports keypoint annotations without leaving the compatibility concern unresolved.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- computer-vision
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100