Skip to content

Commit 016c6e0

Browse files
NicolasHugfacebook-github-bot
authored andcommitted
[fbsync] allow float fill for integer images in F.pad (#7950)
Reviewed By: matteobettini Differential Revision: D49600774 fbshipit-source-id: 3671923921f6da913ce94c327e075e4304f2e964
1 parent 5c02cf7 commit 016c6e0

File tree

2 files changed

+23
-8
lines changed

2 files changed

+23
-8
lines changed

test/test_transforms_v2_refactored.py

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -312,11 +312,12 @@ def adapt_fill(value, *, dtype):
312312
return value
313313

314314
max_value = get_max_value(dtype)
315+
value_type = float if dtype.is_floating_point else int
315316

316317
if isinstance(value, (int, float)):
317-
return type(value)(value * max_value)
318+
return value_type(value * max_value)
318319
elif isinstance(value, (list, tuple)):
319-
return type(value)(type(v)(v * max_value) for v in value)
320+
return type(value)(value_type(v * max_value) for v in value)
320321
else:
321322
raise ValueError(f"fill should be an int or float, or a list or tuple of the former, but got '{value}'.")
322323

@@ -417,6 +418,10 @@ def affine_bounding_boxes(bounding_boxes):
417418
)
418419

419420

421+
# turns all warnings into errors for this module
422+
pytestmark = pytest.mark.filterwarnings("error")
423+
424+
420425
class TestResize:
421426
INPUT_SIZE = (17, 11)
422427
OUTPUT_SIZES = [17, [17], (17,), [12, 13], (12, 13)]
@@ -2577,15 +2582,19 @@ def test_functional_image_correctness(self, kwargs):
25772582
def test_transform(self, param, value, make_input):
25782583
input = make_input(self.INPUT_SIZE)
25792584

2580-
kwargs = {param: value}
25812585
if param == "fill":
2582-
# 1. size is required
2583-
# 2. the fill parameter only has an affect if we need padding
2584-
kwargs["size"] = [s + 4 for s in self.INPUT_SIZE]
2585-
25862586
if isinstance(input, tv_tensors.Mask) and isinstance(value, (tuple, list)):
25872587
pytest.skip("F.pad_mask doesn't support non-scalar fill.")
25882588

2589+
kwargs = dict(
2590+
# 1. size is required
2591+
# 2. the fill parameter only has an affect if we need padding
2592+
size=[s + 4 for s in self.INPUT_SIZE],
2593+
fill=adapt_fill(value, dtype=input.dtype if isinstance(input, torch.Tensor) else torch.uint8),
2594+
)
2595+
else:
2596+
kwargs = {param: value}
2597+
25892598
check_transform(
25902599
transforms.RandomCrop(**kwargs, pad_if_needed=True),
25912600
input,
@@ -3478,6 +3487,8 @@ def test_transform_errors(self):
34783487
def test_image_correctness(self, padding, padding_mode, fill, fn):
34793488
image = make_image(dtype=torch.uint8, device="cpu")
34803489

3490+
fill = adapt_fill(fill, dtype=torch.uint8)
3491+
34813492
actual = fn(image, padding=padding, padding_mode=padding_mode, fill=fill)
34823493
expected = F.to_image(F.pad(F.to_pil_image(image), padding=padding, padding_mode=padding_mode, fill=fill))
34833494

torchvision/transforms/v2/functional/_geometry.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1235,7 +1235,11 @@ def _pad_with_vector_fill(
12351235

12361236
output = _pad_with_scalar_fill(image, torch_padding, fill=0, padding_mode="constant")
12371237
left, right, top, bottom = torch_padding
1238-
fill = torch.tensor(fill, dtype=image.dtype, device=image.device).reshape(-1, 1, 1)
1238+
1239+
# We are creating the tensor in the autodetected dtype first and convert to the right one after to avoid an implicit
1240+
# float -> int conversion. That happens for example for the valid input of a uint8 image with floating point fill
1241+
# value.
1242+
fill = torch.tensor(fill, device=image.device).to(dtype=image.dtype).reshape(-1, 1, 1)
12391243

12401244
if top > 0:
12411245
output[..., :top, :] = fill

0 commit comments

Comments
 (0)