Unverified Commit 588f7ae7 authored by James Thewlis's avatar James Thewlis Committed by GitHub
Browse files

Negative padding for functional_pil #2381 (#2744)



* Negative padding for functional_pil #2381

* Tests for PIL negative padding #2381

* Move PIL vs tensor test inside test_pad

* Adapt test_pad from test_transforms_tensor.py
Co-authored-by: default avatarvfdev <vfdev.5@gmail.com>
parent a9a8220e
......@@ -380,6 +380,16 @@ class Tester(unittest.TestCase):
self.assertTrue(np.all(symmetric_middle_slice == np.asarray([0, 1, 200, 200, 1, 0])))
self.assertEqual(transforms.ToTensor()(symmetric_padded_img).size(), (3, 32, 34))
# Check negative padding explicitly for symmetric case, since it is not
# implemented for tensor case to compare to
# Crop 1 to left, pad 2 to top, pad 3 to right, crop 3 to bottom
symmetric_padded_img_neg = F.pad(img, (-1, 2, 3, -3), padding_mode='symmetric')
symmetric_neg_middle_left = np.asarray(symmetric_padded_img_neg).transpose(2, 0, 1)[0][17][:3]
symmetric_neg_middle_right = np.asarray(symmetric_padded_img_neg).transpose(2, 0, 1)[0][17][-4:]
self.assertTrue(np.all(symmetric_neg_middle_left == np.asarray([1, 0, 0])))
self.assertTrue(np.all(symmetric_neg_middle_right == np.asarray([200, 200, 0, 0])))
self.assertEqual(transforms.ToTensor()(symmetric_padded_img_neg).size(), (3, 28, 31))
def test_pad_raises_with_invalid_pad_sequence_len(self):
with self.assertRaises(ValueError):
transforms.Pad(())
......
......@@ -121,23 +121,27 @@ class Tester(TransformsTester):
)
def test_pad(self):
for m in ["constant", "edge", "reflect", "symmetric"]:
fill = 127 if m == "constant" else 0
# Negative pad currently unsupported for Tensor and symmetric
multipliers = [1] if m == "symmetric" else [1, -1]
for mul in multipliers:
# Test functional.pad (PIL and Tensor) with padding as single int
self._test_functional_op(
"pad", fn_kwargs={"padding": 2, "fill": 0, "padding_mode": "constant"}
"pad", fn_kwargs={"padding": mul * 2, "fill": fill, "padding_mode": m}
)
# Test functional.pad and transforms.Pad with padding as [int, ]
fn_kwargs = meth_kwargs = {"padding": [2, ], "fill": 0, "padding_mode": "constant"}
fn_kwargs = meth_kwargs = {"padding": [mul * 2, ], "fill": fill, "padding_mode": m}
self._test_op(
"pad", "Pad", fn_kwargs=fn_kwargs, meth_kwargs=meth_kwargs
)
# Test functional.pad and transforms.Pad with padding as list
fn_kwargs = meth_kwargs = {"padding": [4, 4], "fill": 0, "padding_mode": "constant"}
fn_kwargs = meth_kwargs = {"padding": [mul * 4, 4], "fill": fill, "padding_mode": m}
self._test_op(
"pad", "Pad", fn_kwargs=fn_kwargs, meth_kwargs=meth_kwargs
)
# Test functional.pad and transforms.Pad with padding as tuple
fn_kwargs = meth_kwargs = {"padding": (2, 2, 2, 2), "fill": 127, "padding_mode": "constant"}
fn_kwargs = meth_kwargs = {"padding": (mul * 2, 2, 2, mul * 2), "fill": fill, "padding_mode": m}
self._test_op(
"pad", "Pad", fn_kwargs=fn_kwargs, meth_kwargs=meth_kwargs
)
......
......@@ -330,6 +330,15 @@ def pad(img, padding, fill=0, padding_mode="constant"):
pad_right = padding[2]
pad_bottom = padding[3]
p = [pad_left, pad_top, pad_right, pad_bottom]
cropping = -np.minimum(p, 0)
if cropping.any():
crop_left, crop_top, crop_right, crop_bottom = cropping
img = img.crop((crop_left, crop_top, img.width - crop_right, img.height - crop_bottom))
pad_left, pad_top, pad_right, pad_bottom = np.maximum(p, 0)
if img.mode == 'P':
palette = img.getpalette()
img = np.asarray(img)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment