compvis / test /filters /test_canny.py
Dexter's picture
Upload folder using huggingface_hub
36c95ba verified
import pytest
import torch
from torch.autograd import gradcheck
import kornia
import kornia.testing as utils # test utils
from kornia.testing import assert_close
class TestCanny:
def test_shape(self, device, dtype):
inp = torch.zeros(1, 3, 4, 4, device=device, dtype=dtype)
canny = kornia.filters.Canny()
magnitude, edges = canny(inp)
assert magnitude.shape == (1, 1, 4, 4)
assert edges.shape == (1, 1, 4, 4)
def test_shape_batch(self, device, dtype):
batch_size = 2
inp = torch.zeros(batch_size, 3, 4, 4, device=device, dtype=dtype)
canny = kornia.filters.Canny()
magnitude, edges = canny(inp)
assert magnitude.shape == (batch_size, 1, 4, 4)
assert edges.shape == (batch_size, 1, 4, 4)
def test_noncontiguous(self, device, dtype):
batch_size = 3
inp = torch.rand(3, 5, 5, device=device, dtype=dtype).expand(batch_size, -1, -1, -1)
magnitude, edges = kornia.filters.canny(inp)
assert inp.is_contiguous() is False
assert magnitude.is_contiguous()
assert edges.is_contiguous()
assert magnitude.shape == (batch_size, 1, 5, 5)
assert edges.shape == (batch_size, 1, 5, 5)
def test_magnitude(self, device, dtype):
inp = torch.tensor(
[
[
[
[0.0, 0.0, 0.0, 0.0, 0.0],
[0.0, 0.0, 1.0, 0.0, 0.0],
[0.0, 1.0, 1.0, 1.0, 0.0],
[0.0, 0.0, 1.0, 0.0, 0.0],
[0.0, 0.0, 0.0, 0.0, 0.0],
]
]
],
device=device,
dtype=dtype,
)
expected_magnitude = torch.tensor(
[
[
[
[0.0, 0.0, 0.0, 0.0, 0.0],
[0.0, 1.2458, 0.9672, 1.2458, 0.0],
[0.0, 0.9672, 0.0, 0.9672, 0.0],
[0.0, 1.2458, 0.9672, 1.2458, 0.0],
[0.0, 0.0, 0.0, 0.0, 0.0],
]
]
],
device=device,
dtype=dtype,
)
expected_edges = torch.tensor(
[
[
[
[0.0, 0.0, 0.0, 0.0, 0.0],
[0.0, 1.0, 1.0, 1.0, 0.0],
[0.0, 1.0, 0.0, 1.0, 0.0],
[0.0, 1.0, 1.0, 1.0, 0.0],
[0.0, 0.0, 0.0, 0.0, 0.0],
]
]
],
device=device,
dtype=dtype,
)
magnitude, edges = kornia.filters.canny(inp)
tol_val: float = utils._get_precision(device, dtype)
assert_close(magnitude, expected_magnitude, rtol=tol_val, atol=tol_val)
assert_close(edges, expected_edges, rtol=tol_val, atol=tol_val)
def test_magnitude_hyst(self, device, dtype):
inp = torch.tensor(
[
[
[
[0.5, 0.4, 0.5, 0.45, 0.1],
[0.3, 0.2, 0.3, 0.0, 0.3],
[0.5, 1.0, 1.0, 0.6, 0.75],
[0.2, 0.4, 0.6, 0.0, 0.5],
[0.1, 0.35, 0.35, 0.26, 0.1],
]
]
],
device=device,
dtype=dtype,
)
expected_magnitude = torch.tensor(
[
[
[
[0.0000, 0.0000, 0.0000, 0.0000, 0.0000],
[0.4858, 0.5594, 0.6878, 0.6977, 0.5602],
[0.1129, 0.0000, 0.0000, 0.4531, 0.0000],
[0.6115, 0.5859, 0.6110, 0.6766, 0.5160],
[0.0000, 0.0000, 0.0000, 0.0000, 0.0000],
]
]
],
device=device,
dtype=dtype,
)
expected_edges = torch.tensor(
[
[
[
[0.0000, 0.0000, 0.0000, 0.0000, 0.0000],
[1.0000, 1.0000, 1.0000, 1.0000, 1.0000],
[1.0000, 0.0000, 0.0000, 1.0000, 0.0000],
[1.0000, 1.0000, 1.0000, 1.0000, 1.0000],
[0.0000, 0.0000, 0.0000, 0.0000, 0.0000],
]
]
],
device=device,
dtype=dtype,
)
magnitude, edges = kornia.filters.canny(inp, hysteresis=True)
tol_val: float = utils._get_precision(device, dtype)
assert_close(magnitude, expected_magnitude, rtol=tol_val, atol=tol_val)
assert_close(edges, expected_edges, rtol=tol_val, atol=tol_val)
def test_magnitude_hyst_false(self, device, dtype):
inp = torch.tensor(
[
[
[
[0.5, 0.4, 0.5, 0.45, 0.1],
[0.3, 0.2, 0.3, 0.0, 0.3],
[0.5, 1.0, 1.0, 0.6, 0.75],
[0.2, 0.4, 0.6, 0.0, 0.5],
[0.1, 0.35, 0.35, 0.26, 0.1],
]
]
],
device=device,
dtype=dtype,
)
expected_magnitude = torch.tensor(
[
[
[
[0.0000, 0.0000, 0.0000, 0.0000, 0.0000],
[0.4858, 0.5594, 0.6878, 0.6977, 0.5602],
[0.1129, 0.0000, 0.0000, 0.4531, 0.0000],
[0.6115, 0.5859, 0.6110, 0.6766, 0.5160],
[0.0000, 0.0000, 0.0000, 0.0000, 0.0000],
]
]
],
device=device,
dtype=dtype,
)
expected_edges = torch.tensor(
[
[
[
[0.0000, 0.0000, 0.0000, 0.0000, 0.0000],
[1.0000, 1.0000, 1.0000, 1.0000, 1.0000],
[0.5000, 0.0000, 0.0000, 1.0000, 0.0000],
[1.0000, 1.0000, 1.0000, 1.0000, 1.0000],
[0.0000, 0.0000, 0.0000, 0.0000, 0.0000],
]
]
],
device=device,
dtype=dtype,
)
magnitude, edges = kornia.filters.canny(inp, hysteresis=False)
tol_val: float = utils._get_precision(device, dtype)
assert_close(magnitude, expected_magnitude, rtol=tol_val, atol=tol_val)
assert_close(edges, expected_edges, rtol=tol_val, atol=tol_val)
def test_magnitude_threshold(self, device, dtype):
inp = torch.tensor(
[
[
[
[0.5, 0.4, 0.5, 0.45, 0.1],
[0.3, 0.2, 0.3, 0.0, 0.3],
[0.5, 1.0, 1.0, 0.6, 0.75],
[0.2, 0.4, 0.6, 0.0, 0.5],
[0.1, 0.35, 0.35, 0.26, 0.1],
]
]
],
device=device,
dtype=dtype,
)
expected_magnitude = torch.tensor(
[
[
[
[0.0000, 0.0000, 0.0000, 0.0000, 0.0000],
[0.4858, 0.5594, 0.6878, 0.6977, 0.5602],
[0.1129, 0.0000, 0.0000, 0.4531, 0.0000],
[0.6115, 0.5859, 0.6110, 0.6766, 0.5160],
[0.0000, 0.0000, 0.0000, 0.0000, 0.0000],
]
]
],
device=device,
dtype=dtype,
)
expected_edges = torch.tensor(
[
[
[
[0.0000, 0.0000, 0.0000, 0.0000, 0.0000],
[0.0000, 0.0000, 0.0000, 0.0000, 0.0000],
[0.0000, 0.0000, 0.0000, 0.0000, 0.0000],
[0.0000, 0.0000, 0.0000, 0.0000, 0.0000],
[0.0000, 0.0000, 0.0000, 0.0000, 0.0000],
]
]
],
device=device,
dtype=dtype,
)
magnitude, edges = kornia.filters.canny(inp, low_threshold=0.3, high_threshold=0.9)
tol_val: float = utils._get_precision(device, dtype)
assert_close(magnitude, expected_magnitude, rtol=tol_val, atol=tol_val)
assert_close(edges, expected_edges, rtol=tol_val, atol=tol_val)
def test_gradcheck(self, device, dtype):
if "cuda" in str(device):
pytest.skip("RuntimeError: Backward is not reentrant, i.e., running backward,")
batch_size, channels, height, width = 1, 1, 3, 4
img = torch.rand(batch_size, channels, height, width, device=device, dtype=dtype)
img = utils.tensor_to_gradcheck_var(img) # to var
assert gradcheck(kornia.filters.canny, img, raise_exception=True)
def test_jit(self, device, dtype):
img = torch.rand(2, 3, 4, 5, device=device, dtype=dtype)
op = kornia.filters.sobel
op_script = torch.jit.script(op)
expected_magnitude, expected_edges = op(img)
actual_magnitude, actual_edges = op_script(img)
assert_close(actual_magnitude, expected_magnitude)
assert_close(actual_edges, expected_edges)
def test_module(self, device, dtype):
img = torch.rand(2, 3, 4, 5, device=device, dtype=dtype)
op = kornia.filters.canny
op_module = kornia.filters.Canny()
expected_magnitude, expected_edges = op(img)
actual_magnitude, actual_edges = op_module(img)
assert_close(actual_magnitude, expected_magnitude)
assert_close(actual_edges, expected_edges)