Skip to content

Commit 6397190

Browse files
jaesunydatumbox
andauthored
Make crop work the same for pil and tensor (#3770)
* Make crop work the same for pil and tensor * Only call pad if needed in functional_tensor.crop * Fix top-left functional_tensor.crop * Update document for functional.crop * Add other test cases of functional.crop * Fix bug * Fixing formattter * Fix stylings Co-authored-by: Vasilis Vryniotis <[email protected]>
1 parent 11bf27e commit 6397190

File tree

3 files changed

+26
-2
lines changed

3 files changed

+26
-2
lines changed

test/test_transforms_tensor.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,22 @@ def test_crop(self):
188188
'crop', 'RandomCrop', fn_kwargs=fn_kwargs, meth_kwargs=meth_kwargs
189189
)
190190

191+
# Test transforms.functional.crop including outside the image area
192+
fn_kwargs = {"top": -2, "left": 3, "height": 4, "width": 5} # top
193+
self._test_functional_op('crop', fn_kwargs=fn_kwargs)
194+
195+
fn_kwargs = {"top": 1, "left": -3, "height": 4, "width": 5} # left
196+
self._test_functional_op('crop', fn_kwargs=fn_kwargs)
197+
198+
fn_kwargs = {"top": 7, "left": 3, "height": 4, "width": 5} # bottom
199+
self._test_functional_op('crop', fn_kwargs=fn_kwargs)
200+
201+
fn_kwargs = {"top": 3, "left": 8, "height": 4, "width": 5} # right
202+
self._test_functional_op('crop', fn_kwargs=fn_kwargs)
203+
204+
fn_kwargs = {"top": -3, "left": -3, "height": 15, "width": 15} # all
205+
self._test_functional_op('crop', fn_kwargs=fn_kwargs)
206+
191207
sizes = [5, [5, ], [6, 6]]
192208
padding_configs = [
193209
{"padding_mode": "constant", "fill": 0},

torchvision/transforms/functional.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -463,7 +463,8 @@ def pad(img: Tensor, padding: List[int], fill: int = 0, padding_mode: str = "con
463463
def crop(img: Tensor, top: int, left: int, height: int, width: int) -> Tensor:
464464
"""Crop the given image at specified location and output size.
465465
If the image is torch Tensor, it is expected
466-
to have [..., H, W] shape, where ... means an arbitrary number of leading dimensions
466+
to have [..., H, W] shape, where ... means an arbitrary number of leading dimensions.
467+
If image size is smaller than output size along any edge, image is padded with 0 and then cropped.
467468
468469
Args:
469470
img (PIL Image or Tensor): Image to be cropped. (0,0) denotes the top left corner of the image.

torchvision/transforms/functional_tensor.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,14 @@ def hflip(img: Tensor) -> Tensor:
122122
def crop(img: Tensor, top: int, left: int, height: int, width: int) -> Tensor:
123123
_assert_image_tensor(img)
124124

125-
return img[..., top:top + height, left:left + width]
125+
w, h = _get_image_size(img)
126+
right = left + width
127+
bottom = top + height
128+
129+
if left < 0 or top < 0 or right > w or bottom > h:
130+
padding_ltrb = [max(-left, 0), max(-top, 0), max(right - w, 0), max(bottom - h, 0)]
131+
return pad(img[..., max(top, 0):bottom, max(left, 0):right], padding_ltrb, fill=0)
132+
return img[..., top:bottom, left:right]
126133

127134

128135
def rgb_to_grayscale(img: Tensor, num_output_channels: int = 1) -> Tensor:

0 commit comments

Comments
 (0)