-
Notifications
You must be signed in to change notification settings - Fork 7.1k
Refactor of transforms #240
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
(cherry picked from commit 71afec427baca8e37cd9e10d98812bc586e9a4ac)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This overall looks good.
I think though that it might be better to make the random parameter generation as standalone functions, what do you think?
Also, it might be good to add some extra type checks to verify that the user passed the right type to the functions, as they can either be PILImage objects or torch Tensors.
torchvision/transforms.py
Outdated
return img.crop((x, y, x + w, y + h)) | ||
|
||
|
||
def scaled_crop(img, x, y, w, h, size, interpolation=Image.BILINEAR): |
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
torchvision/transforms.py
Outdated
@@ -214,6 +254,13 @@ def __init__(self, size): | |||
else: | |||
self.size = size | |||
|
|||
def get_params(self, img): |
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
torchvision/transforms.py
Outdated
@@ -298,6 +342,16 @@ def __init__(self, size, padding=0): | |||
self.size = size | |||
self.padding = padding | |||
|
|||
def get_params(self, img): |
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
torchvision/transforms.py
Outdated
@@ -352,7 +401,7 @@ def __init__(self, size, interpolation=Image.BILINEAR): | |||
self.size = size | |||
self.interpolation = interpolation | |||
|
|||
def __call__(self, img): | |||
def get_params(self, img): |
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
torchvision/transforms.py
Outdated
|
||
def __call__(self, img): | ||
x, y, w, h = self.get_params(img) | ||
return scaled_crop(img, x, y, w, h, self.size, self.interpolation) |
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
torchvision/transforms.py
Outdated
|
||
|
||
def crop(img, x, y, w, h): | ||
return img.crop((x, y, x + w, y + h)) |
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
torchvision/transforms.py
Outdated
|
||
|
||
def normalize(tensor, mean, std): | ||
# TODO: make efficient |
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @chsasank this looks very good. I've left some inline comments.
I also agree with @fmassa about having standalone functions to genterate random crop params, as if we want to allow the users to use purely the functional interface (to generate complex transform graphs), they will need a way to generate these params (without creating an object)
torchvision/transforms.py
Outdated
return img | ||
|
||
|
||
def to_pilimage(pic): |
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
torchvision/transforms.py
Outdated
y1 = int(round((h - th) / 2.)) | ||
return img.crop((x1, y1, x1 + tw, y1 + th)) | ||
x1, y1, tw, th = self.get_params(img) | ||
return crop(img, x1, y1, tw, th) |
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
@@ -260,7 +344,7 @@ def __call__(self, img): | |||
Returns: | |||
PIL.Image: Padded image. | |||
""" | |||
return ImageOps.expand(img, border=self.padding, fill=self.fill) | |||
return pad(img, self.padding, self.fill) | |||
|
|||
|
|||
class Lambda(object): |
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
torchvision/transforms.py
Outdated
|
||
def __call__(self, img): | ||
x, y, w, h = self.get_params(img) | ||
return scaled_crop(img, x, y, w, h, self.size, self.interpolation) |
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
reminder @alykhantejani @fmassa. |
Hi @chsasank from my side this looks pretty good although I think we should address the following before merging:
Option 2 The objects would then call a combination of
|
Sorry for the delay in reviewing. I think this is almost ready to go. About @alykhantejani last comments, I'd go with a variant of option 2. Given that one of the goals of this refactoring is to be able to extend random transforms to many inputs, I think it's better not to add randomness in the operations (so I'd avoid What about letting the Thoughts? |
I like this idea too. I will go ahead with it, I guess. |
Most of the requested changes are done. Also added documentation. Do you want the new functions in a separate namespace? If so, any name suggestion? |
torchvision/transforms.py
Outdated
Args: | ||
img (PIL.Image): Image to be scaled. | ||
size (sequence or int): Desired output size. If size is a sequence like | ||
(w, h), output size will be matched to this. If size is an int, |
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
Hi @chsasank this looks good to go once the merge conflicts are resolved. As for namespace, I don't like that we can now do |
Oh no. That means I've to change whole lot of things. Like parameters order in scale, crop functions etc. |
@chsasank Just the params in |
torchvision/transforms.py
Outdated
return ImageOps.expand(img, border=padding, fill=fill) | ||
|
||
|
||
def crop(img, x, y, w, h): |
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @chsasank looks good - just a few final small things to change and I think we're good to merge.
torchvision/transforms.py
Outdated
return ImageOps.expand(img, border=padding, fill=fill) | ||
|
||
|
||
def crop(img, x, y, w, h): |
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
torchvision/transforms.py
Outdated
return img.crop((x, y, x + w, y + h)) | ||
|
||
|
||
def scaled_crop(img, x, y, w, h, size, interpolation=Image.BILINEAR): |
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
torchvision/transforms.py
Outdated
y: Upper pixel coordinate. | ||
w: Width of the cropped image. | ||
h: Height of the cropped image. | ||
size (sequence or int): Desired output size. Same semantics as ``scale``. |
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
torchvision/transforms.py
Outdated
PIL.Image: Cropped image. | ||
""" | ||
assert _is_pil_image(img), 'img should be PIL Image' | ||
img = crop(img, x, y, w, h) |
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
@chsasank once you change the |
Sorry, got a bit late. Let me know if I have to change anything else. |
🍾 🎆 |
Thanks a lot @chsasank and sorry for the delay in finishing reviewing the PR! |
Thanks a lot @chsasank! 🎉 |
VerticalFlip converted to follow refactor #240
* Delete Caffe2 object_detection * Added new pytorch-based object_detection * object_detection: removed unused configs; deleted misleading code * object_detection Dockerfile now based on public image and specifies exact library versions
To allow easy subclassing to extend to joint transforms.
See #230.
First cut implementation. Needs polish, I guess.
Lot of things are missing, like docs etc.