Skip to content

Commit

Permalink
port tests for F.perspective and transforms.RandomPerspective (#7943)
Browse files Browse the repository at this point in the history
  • Loading branch information
pmeier authored Sep 8, 2023
1 parent 7253af5 commit d84aaae
Show file tree
Hide file tree
Showing 8 changed files with 252 additions and 266 deletions.
20 changes: 0 additions & 20 deletions test/test_transforms_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -418,26 +418,6 @@ def test__get_params(self, fill, side_range):
assert 0 <= params["padding"][3] <= (side_range[1] - 1) * h


class TestRandomPerspective:
def test_assertions(self):
with pytest.raises(ValueError, match="Argument distortion_scale value should be between 0 and 1"):
transforms.RandomPerspective(distortion_scale=-1.0)

with pytest.raises(TypeError, match="Got inappropriate fill arg"):
transforms.RandomPerspective(0.5, fill="abc")

def test__get_params(self):
dscale = 0.5
transform = transforms.RandomPerspective(dscale)

image = make_image((24, 32))

params = transform._get_params([image])

assert "coefficients" in params
assert len(params["coefficients"]) == 8


class TestElasticTransform:
def test_assertions(self):

Expand Down
16 changes: 0 additions & 16 deletions test/test_transforms_v2_consistency.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
from pathlib import Path

import numpy as np
import PIL.Image
import pytest

import torch
Expand Down Expand Up @@ -246,20 +245,6 @@ def __init__(
],
closeness_kwargs={"atol": 1e-5, "rtol": 1e-5},
),
ConsistencyConfig(
v2_transforms.RandomPerspective,
legacy_transforms.RandomPerspective,
[
ArgsKwargs(p=0),
ArgsKwargs(p=1),
ArgsKwargs(p=1, distortion_scale=0.3),
ArgsKwargs(p=1, distortion_scale=0.2, interpolation=v2_transforms.InterpolationMode.NEAREST),
ArgsKwargs(p=1, distortion_scale=0.2, interpolation=PIL.Image.NEAREST),
ArgsKwargs(p=1, distortion_scale=0.1, fill=1),
ArgsKwargs(p=1, distortion_scale=0.4, fill=(1, 2, 3)),
],
closeness_kwargs={"atol": None, "rtol": None},
),
ConsistencyConfig(
v2_transforms.PILToTensor,
legacy_transforms.PILToTensor,
Expand Down Expand Up @@ -478,7 +463,6 @@ def test_call_consistency(config, args_kwargs):
)
for transform_cls, get_params_args_kwargs in [
(v2_transforms.ColorJitter, ArgsKwargs(brightness=None, contrast=None, saturation=None, hue=None)),
(v2_transforms.RandomPerspective, ArgsKwargs(23, 17, 0.5)),
(v2_transforms.AutoAugment, ArgsKwargs(5)),
]
],
Expand Down
79 changes: 0 additions & 79 deletions test/test_transforms_v2_functional.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,8 @@
from common_utils import assert_close, cache, cpu_and_cuda, needs_cuda, set_rng_seed
from torch.utils._pytree import tree_map
from torchvision import tv_tensors
from torchvision.transforms.functional import _get_perspective_coeffs
from torchvision.transforms.v2 import functional as F
from torchvision.transforms.v2._utils import is_pure_tensor
from torchvision.transforms.v2.functional._meta import clamp_bounding_boxes, convert_bounding_box_format
from transforms_v2_dispatcher_infos import DISPATCHER_INFOS
from transforms_v2_kernel_infos import KERNEL_INFOS
from transforms_v2_legacy_utils import (
Expand Down Expand Up @@ -523,83 +521,6 @@ def test_tv_tensor_explicit_metadata(self, metadata):
# `transforms_v2_kernel_infos.py`


@pytest.mark.parametrize("device", cpu_and_cuda())
@pytest.mark.parametrize(
"startpoints, endpoints",
[
[[[0, 0], [33, 0], [33, 25], [0, 25]], [[3, 2], [32, 3], [30, 24], [2, 25]]],
[[[3, 2], [32, 3], [30, 24], [2, 25]], [[0, 0], [33, 0], [33, 25], [0, 25]]],
[[[3, 2], [32, 3], [30, 24], [2, 25]], [[5, 5], [30, 3], [33, 19], [4, 25]]],
],
)
def test_correctness_perspective_bounding_boxes(device, startpoints, endpoints):
def _compute_expected_bbox(bbox, format_, canvas_size_, pcoeffs_):
m1 = np.array(
[
[pcoeffs_[0], pcoeffs_[1], pcoeffs_[2]],
[pcoeffs_[3], pcoeffs_[4], pcoeffs_[5]],
]
)
m2 = np.array(
[
[pcoeffs_[6], pcoeffs_[7], 1.0],
[pcoeffs_[6], pcoeffs_[7], 1.0],
]
)

bbox_xyxy = convert_bounding_box_format(bbox, old_format=format_, new_format=tv_tensors.BoundingBoxFormat.XYXY)
points = np.array(
[
[bbox_xyxy[0].item(), bbox_xyxy[1].item(), 1.0],
[bbox_xyxy[2].item(), bbox_xyxy[1].item(), 1.0],
[bbox_xyxy[0].item(), bbox_xyxy[3].item(), 1.0],
[bbox_xyxy[2].item(), bbox_xyxy[3].item(), 1.0],
]
)
numer = np.matmul(points, m1.T)
denom = np.matmul(points, m2.T)
transformed_points = numer / denom
out_bbox = np.array(
[
np.min(transformed_points[:, 0]),
np.min(transformed_points[:, 1]),
np.max(transformed_points[:, 0]),
np.max(transformed_points[:, 1]),
]
)
out_bbox = torch.from_numpy(out_bbox)
out_bbox = convert_bounding_box_format(
out_bbox, old_format=tv_tensors.BoundingBoxFormat.XYXY, new_format=format_
)
return clamp_bounding_boxes(out_bbox, format=format_, canvas_size=canvas_size_).to(bbox)

canvas_size = (32, 38)

pcoeffs = _get_perspective_coeffs(startpoints, endpoints)
inv_pcoeffs = _get_perspective_coeffs(endpoints, startpoints)

for bboxes in make_multiple_bounding_boxes(spatial_size=canvas_size, extra_dims=((4,),)):
bboxes = bboxes.to(device)

output_bboxes = F.perspective_bounding_boxes(
bboxes.as_subclass(torch.Tensor),
format=bboxes.format,
canvas_size=bboxes.canvas_size,
startpoints=None,
endpoints=None,
coefficients=pcoeffs,
)

expected_bboxes = torch.stack(
[
_compute_expected_bbox(b, bboxes.format, bboxes.canvas_size, inv_pcoeffs)
for b in bboxes.reshape(-1, 4).unbind()
]
).reshape(bboxes.shape)

torch.testing.assert_close(output_bboxes, expected_bboxes, rtol=0, atol=1)


@pytest.mark.parametrize(
"inpt",
[
Expand Down
Loading

0 comments on commit d84aaae

Please sign in to comment.