| from functools import partial |
|
|
| import numpy as np |
| import pytest |
| import torch |
| from torch.autograd import gradcheck |
|
|
| import kornia |
| from kornia.geometry.conversions import QuaternionCoeffOrder |
| from kornia.testing import assert_close, create_eye_batch, tensor_to_gradcheck_var |
|
|
|
|
| @pytest.fixture |
| def atol(device, dtype): |
| """Lower tolerance for cuda-float16 only.""" |
| if 'cuda' in device.type and dtype == torch.float16: |
| return 1.0e-3 |
| return 1.0e-4 |
|
|
|
|
| @pytest.fixture |
| def rtol(device, dtype): |
| """Lower tolerance for cuda-float16 only.""" |
| if 'cuda' in device.type and dtype == torch.float16: |
| return 1.0e-3 |
| return 1.0e-4 |
|
|
|
|
| |
| |
|
|
|
|
| class TestAngleAxisToQuaternion: |
| def test_smoke_xyzw(self, device, dtype): |
| angle_axis = torch.zeros(3, dtype=dtype, device=device) |
| with pytest.warns(UserWarning): |
| quaternion = kornia.geometry.conversions.angle_axis_to_quaternion( |
| angle_axis, order=QuaternionCoeffOrder.XYZW |
| ) |
| assert quaternion.shape == (4,) |
|
|
| def test_smoke(self, device, dtype): |
| angle_axis = torch.zeros(3, dtype=dtype, device=device) |
| quaternion = kornia.geometry.conversions.angle_axis_to_quaternion(angle_axis, order=QuaternionCoeffOrder.WXYZ) |
| assert quaternion.shape == (4,) |
|
|
| @pytest.mark.parametrize("batch_size", (1, 3, 8)) |
| def test_smoke_batch_xyzw(self, batch_size, device, dtype): |
| angle_axis = torch.zeros(batch_size, 3, device=device, dtype=dtype) |
| with pytest.warns(UserWarning): |
| quaternion = kornia.geometry.conversions.angle_axis_to_quaternion( |
| angle_axis, order=QuaternionCoeffOrder.XYZW |
| ) |
| assert quaternion.shape == (batch_size, 4) |
|
|
| @pytest.mark.parametrize("batch_size", (1, 3, 8)) |
| def test_smoke_batch(self, batch_size, device, dtype): |
| angle_axis = torch.zeros(batch_size, 3, device=device, dtype=dtype) |
| quaternion = kornia.geometry.conversions.angle_axis_to_quaternion(angle_axis, order=QuaternionCoeffOrder.WXYZ) |
| assert quaternion.shape == (batch_size, 4) |
|
|
| def test_zero_angle_xyzw(self, device, dtype, atol, rtol): |
| angle_axis = torch.tensor((0.0, 0.0, 0.0), device=device, dtype=dtype) |
| expected = torch.tensor((0.0, 0.0, 0.0, 1.0), device=device, dtype=dtype) |
| with pytest.warns(UserWarning): |
| quaternion = kornia.geometry.conversions.angle_axis_to_quaternion( |
| angle_axis, order=QuaternionCoeffOrder.XYZW |
| ) |
| assert_close(quaternion, expected, atol=atol, rtol=rtol) |
|
|
| def test_zero_angle(self, device, dtype, atol, rtol): |
| angle_axis = torch.tensor((0.0, 0.0, 0.0), device=device, dtype=dtype) |
| expected = torch.tensor((1.0, 0.0, 0.0, 0.0), device=device, dtype=dtype) |
| quaternion = kornia.geometry.conversions.angle_axis_to_quaternion(angle_axis, order=QuaternionCoeffOrder.WXYZ) |
| assert_close(quaternion, expected, atol=atol, rtol=rtol) |
|
|
| def test_small_angle_x_xyzw(self, device, dtype, atol, rtol): |
| theta = 1.0e-2 |
| angle_axis = torch.tensor((theta, 0.0, 0.0), device=device, dtype=dtype) |
| expected = torch.tensor((np.sin(theta / 2.0), 0.0, 0.0, np.cos(theta / 2.0)), device=device, dtype=dtype) |
| with pytest.warns(UserWarning): |
| quaternion = kornia.geometry.conversions.angle_axis_to_quaternion( |
| angle_axis, order=QuaternionCoeffOrder.XYZW |
| ) |
| assert_close(quaternion, expected, atol=atol, rtol=rtol) |
|
|
| def test_small_angle_x(self, device, dtype, atol, rtol): |
| theta = 1.0e-2 |
| angle_axis = torch.tensor((theta, 0.0, 0.0), device=device, dtype=dtype) |
| expected = torch.tensor((np.cos(theta / 2.0), np.sin(theta / 2.0), 0.0, 0.0), device=device, dtype=dtype) |
| quaternion = kornia.geometry.conversions.angle_axis_to_quaternion(angle_axis, order=QuaternionCoeffOrder.WXYZ) |
| assert_close(quaternion, expected, atol=atol, rtol=rtol) |
|
|
| def test_small_angle_y_xyzw(self, device, dtype, atol, rtol): |
| theta = 1.0e-2 |
| angle_axis = torch.tensor((0.0, theta, 0.0), device=device, dtype=dtype) |
| expected = torch.tensor((0.0, np.sin(theta / 2.0), 0.0, np.cos(theta / 2.0)), device=device, dtype=dtype) |
| with pytest.warns(UserWarning): |
| quaternion = kornia.geometry.conversions.angle_axis_to_quaternion( |
| angle_axis, order=QuaternionCoeffOrder.XYZW |
| ) |
| assert_close(quaternion, expected, atol=atol, rtol=rtol) |
|
|
| def test_small_angle_y(self, device, dtype, atol, rtol): |
| theta = 1.0e-2 |
| angle_axis = torch.tensor((0.0, theta, 0.0), device=device, dtype=dtype) |
| expected = torch.tensor((np.cos(theta / 2.0), 0.0, np.sin(theta / 2.0), 0.0), device=device, dtype=dtype) |
| quaternion = kornia.geometry.conversions.angle_axis_to_quaternion(angle_axis, order=QuaternionCoeffOrder.WXYZ) |
| assert_close(quaternion, expected, atol=atol, rtol=rtol) |
|
|
| def test_small_angle_z_xyzw(self, device, dtype, atol, rtol): |
| theta = 1.0e-2 |
| angle_axis = torch.tensor((0.0, 0.0, theta), device=device, dtype=dtype) |
| expected = torch.tensor((0.0, 0.0, np.sin(theta / 2.0), np.cos(theta / 2.0)), device=device, dtype=dtype) |
| with pytest.warns(UserWarning): |
| quaternion = kornia.geometry.conversions.angle_axis_to_quaternion( |
| angle_axis, order=QuaternionCoeffOrder.XYZW |
| ) |
| assert_close(quaternion, expected, atol=atol, rtol=rtol) |
|
|
| def test_small_angle_z(self, device, dtype, atol, rtol): |
| theta = 1.0e-2 |
| angle_axis = torch.tensor((0.0, 0.0, theta), device=device, dtype=dtype) |
| expected = torch.tensor((np.cos(theta / 2.0), 0.0, 0.0, np.sin(theta / 2.0)), device=device, dtype=dtype) |
| quaternion = kornia.geometry.conversions.angle_axis_to_quaternion(angle_axis, order=QuaternionCoeffOrder.WXYZ) |
| assert_close(quaternion, expected, atol=atol, rtol=rtol) |
|
|
| def test_x_rotation_xyzw(self, device, dtype, atol, rtol): |
| half_sqrt2 = 0.5 * np.sqrt(2.0) |
| angle_axis = torch.tensor((kornia.pi / 2.0, 0.0, 0.0), device=device, dtype=dtype) |
| expected = torch.tensor((half_sqrt2, 0.0, 0.0, half_sqrt2), device=device, dtype=dtype) |
| with pytest.warns(UserWarning): |
| quaternion = kornia.geometry.conversions.angle_axis_to_quaternion( |
| angle_axis, order=QuaternionCoeffOrder.XYZW |
| ) |
| assert_close(quaternion, expected, atol=atol, rtol=rtol) |
|
|
| def test_x_rotation(self, device, dtype, atol, rtol): |
| half_sqrt2 = 0.5 * np.sqrt(2.0) |
| angle_axis = torch.tensor((kornia.pi / 2.0, 0.0, 0.0), device=device, dtype=dtype) |
| expected = torch.tensor((half_sqrt2, half_sqrt2, 0.0, 0.0), device=device, dtype=dtype) |
| quaternion = kornia.geometry.conversions.angle_axis_to_quaternion(angle_axis, order=QuaternionCoeffOrder.WXYZ) |
| assert_close(quaternion, expected, atol=atol, rtol=rtol) |
|
|
| def test_y_rotation_xyzw(self, device, dtype, atol, rtol): |
| half_sqrt2 = 0.5 * np.sqrt(2.0) |
| angle_axis = torch.tensor((0.0, kornia.pi / 2.0, 0.0), device=device, dtype=dtype) |
| expected = torch.tensor((0.0, half_sqrt2, 0.0, half_sqrt2), device=device, dtype=dtype) |
| with pytest.warns(UserWarning): |
| quaternion = kornia.geometry.conversions.angle_axis_to_quaternion( |
| angle_axis, order=QuaternionCoeffOrder.XYZW |
| ) |
| assert_close(quaternion, expected, atol=atol, rtol=rtol) |
|
|
| def test_y_rotation(self, device, dtype, atol, rtol): |
| half_sqrt2 = 0.5 * np.sqrt(2.0) |
| angle_axis = torch.tensor((0.0, kornia.pi / 2.0, 0.0), device=device, dtype=dtype) |
| expected = torch.tensor((half_sqrt2, 0.0, half_sqrt2, 0.0), device=device, dtype=dtype) |
| quaternion = kornia.geometry.conversions.angle_axis_to_quaternion(angle_axis, order=QuaternionCoeffOrder.WXYZ) |
| assert_close(quaternion, expected, atol=atol, rtol=rtol) |
|
|
| def test_z_rotation_xyzw(self, device, dtype, atol, rtol): |
| half_sqrt2 = 0.5 * np.sqrt(2.0) |
| angle_axis = torch.tensor((0.0, 0.0, kornia.pi / 2.0), device=device, dtype=dtype) |
| expected = torch.tensor((0.0, 0.0, half_sqrt2, half_sqrt2), device=device, dtype=dtype) |
| with pytest.warns(UserWarning): |
| quaternion = kornia.geometry.conversions.angle_axis_to_quaternion( |
| angle_axis, order=QuaternionCoeffOrder.XYZW |
| ) |
| assert_close(quaternion, expected, atol=atol, rtol=rtol) |
|
|
| def test_z_rotation(self, device, dtype, atol, rtol): |
| half_sqrt2 = 0.5 * np.sqrt(2.0) |
| angle_axis = torch.tensor((0.0, 0.0, kornia.pi / 2.0), device=device, dtype=dtype) |
| expected = torch.tensor((half_sqrt2, 0.0, 0.0, half_sqrt2), device=device, dtype=dtype) |
| quaternion = kornia.geometry.conversions.angle_axis_to_quaternion(angle_axis, order=QuaternionCoeffOrder.WXYZ) |
| assert_close(quaternion, expected, atol=atol, rtol=rtol) |
|
|
| def test_gradcheck_xyzw(self, device, dtype): |
| eps = torch.finfo(dtype).eps |
| angle_axis = torch.tensor((0.0, 0.0, 0.0), device=device, dtype=dtype) + eps |
| angle_axis = tensor_to_gradcheck_var(angle_axis) |
| |
| with pytest.warns(UserWarning): |
| assert gradcheck( |
| partial(kornia.geometry.conversions.angle_axis_to_quaternion, order=QuaternionCoeffOrder.XYZW), |
| (angle_axis,), |
| raise_exception=True, |
| ) |
|
|
| def test_gradcheck(self, device, dtype): |
| eps = torch.finfo(dtype).eps |
| angle_axis = torch.tensor((0.0, 0.0, 0.0), device=device, dtype=dtype) + eps |
| angle_axis = tensor_to_gradcheck_var(angle_axis) |
| |
| assert gradcheck( |
| partial(kornia.geometry.conversions.angle_axis_to_quaternion, order=QuaternionCoeffOrder.WXYZ), |
| (angle_axis,), |
| raise_exception=True, |
| ) |
|
|
|
|
| class TestQuaternionToAngleAxis: |
| def test_smoke_xyzw(self, device, dtype): |
| quaternion = torch.zeros(4, device=device, dtype=dtype) |
| with pytest.warns(UserWarning): |
| angle_axis = kornia.geometry.conversions.quaternion_to_angle_axis( |
| quaternion, order=QuaternionCoeffOrder.XYZW |
| ) |
| assert angle_axis.shape == (3,) |
|
|
| def test_smoke(self, device, dtype): |
| quaternion = torch.zeros(4, device=device, dtype=dtype) |
| angle_axis = kornia.geometry.conversions.quaternion_to_angle_axis(quaternion, order=QuaternionCoeffOrder.WXYZ) |
| assert angle_axis.shape == (3,) |
|
|
| @pytest.mark.parametrize("batch_size", (1, 3, 8)) |
| def test_smoke_batch_xyzw(self, batch_size, device, dtype): |
| quaternion = torch.zeros(batch_size, 4, device=device, dtype=dtype) |
| with pytest.warns(UserWarning): |
| angle_axis = kornia.geometry.conversions.quaternion_to_angle_axis( |
| quaternion, order=QuaternionCoeffOrder.XYZW |
| ) |
| assert angle_axis.shape == (batch_size, 3) |
|
|
| @pytest.mark.parametrize("batch_size", (1, 3, 8)) |
| def test_smoke_batch(self, batch_size, device, dtype): |
| quaternion = torch.zeros(batch_size, 4, device=device, dtype=dtype) |
| angle_axis = kornia.geometry.conversions.quaternion_to_angle_axis(quaternion, order=QuaternionCoeffOrder.WXYZ) |
| assert angle_axis.shape == (batch_size, 3) |
|
|
| def test_unit_quaternion_xyzw(self, device, dtype, atol, rtol): |
| quaternion = torch.tensor((0.0, 0.0, 0.0, 1.0), device=device, dtype=dtype) |
| expected = torch.tensor((0.0, 0.0, 0.0), device=device, dtype=dtype) |
| with pytest.warns(UserWarning): |
| angle_axis = kornia.geometry.conversions.quaternion_to_angle_axis( |
| quaternion, order=QuaternionCoeffOrder.XYZW |
| ) |
| assert_close(angle_axis, expected, atol=atol, rtol=rtol) |
|
|
| def test_unit_quaternion(self, device, dtype, atol, rtol): |
| quaternion = torch.tensor((1.0, 0.0, 0.0, 0.0), device=device, dtype=dtype) |
| expected = torch.tensor((0.0, 0.0, 0.0), device=device, dtype=dtype) |
| angle_axis = kornia.geometry.conversions.quaternion_to_angle_axis(quaternion, order=QuaternionCoeffOrder.WXYZ) |
| assert_close(angle_axis, expected, atol=atol, rtol=rtol) |
|
|
| def test_x_rotation_xyzw(self, device, dtype, atol, rtol): |
| quaternion = torch.tensor((1.0, 0.0, 0.0, 0.0), device=device, dtype=dtype) |
| expected = torch.tensor((kornia.pi, 0.0, 0.0), device=device, dtype=dtype) |
| with pytest.warns(UserWarning): |
| angle_axis = kornia.geometry.conversions.quaternion_to_angle_axis( |
| quaternion, order=QuaternionCoeffOrder.XYZW |
| ) |
| assert_close(angle_axis, expected, atol=atol, rtol=rtol) |
|
|
| def test_x_rotation(self, device, dtype, atol, rtol): |
| quaternion = torch.tensor((0.0, 1.0, 0.0, 0.0), device=device, dtype=dtype) |
| expected = torch.tensor((kornia.pi, 0.0, 0.0), device=device, dtype=dtype) |
| angle_axis = kornia.geometry.conversions.quaternion_to_angle_axis(quaternion, order=QuaternionCoeffOrder.WXYZ) |
| assert_close(angle_axis, expected, atol=atol, rtol=rtol) |
|
|
| def test_y_rotation_xyzw(self, device, dtype, atol, rtol): |
| quaternion = torch.tensor((0.0, 1.0, 0.0, 0.0), device=device, dtype=dtype) |
| expected = torch.tensor((0.0, kornia.pi, 0.0), device=device, dtype=dtype) |
| with pytest.warns(UserWarning): |
| angle_axis = kornia.geometry.conversions.quaternion_to_angle_axis( |
| quaternion, order=QuaternionCoeffOrder.XYZW |
| ) |
| assert_close(angle_axis, expected, atol=atol, rtol=rtol) |
|
|
| def test_y_rotation(self, device, dtype, atol, rtol): |
| quaternion = torch.tensor((0.0, 0.0, 1.0, 0.0), device=device, dtype=dtype) |
| expected = torch.tensor((0.0, kornia.pi, 0.0), device=device, dtype=dtype) |
| angle_axis = kornia.geometry.conversions.quaternion_to_angle_axis(quaternion, order=QuaternionCoeffOrder.WXYZ) |
| assert_close(angle_axis, expected, atol=atol, rtol=rtol) |
|
|
| def test_z_rotation_xyzw(self, device, dtype, atol, rtol): |
| quaternion = torch.tensor((0.0, 0.0, 0.5, np.sqrt(3.0) / 2.0), device=device, dtype=dtype) |
| expected = torch.tensor((0.0, 0.0, kornia.pi / 3.0), device=device, dtype=dtype) |
| with pytest.warns(UserWarning): |
| angle_axis = kornia.geometry.conversions.quaternion_to_angle_axis( |
| quaternion, order=QuaternionCoeffOrder.XYZW |
| ) |
| assert_close(angle_axis, expected, atol=atol, rtol=rtol) |
|
|
| def test_z_rotation(self, device, dtype, atol, rtol): |
| quaternion = torch.tensor((np.sqrt(3.0) / 2.0, 0.0, 0.0, 0.5), device=device, dtype=dtype) |
| expected = torch.tensor((0.0, 0.0, kornia.pi / 3.0), device=device, dtype=dtype) |
| angle_axis = kornia.geometry.conversions.quaternion_to_angle_axis(quaternion, order=QuaternionCoeffOrder.WXYZ) |
| assert_close(angle_axis, expected, atol=atol, rtol=rtol) |
|
|
| def test_small_angle_x_xyzw(self, device, dtype, atol, rtol): |
| theta = 1.0e-2 |
| quaternion = torch.tensor((np.sin(theta / 2.0), 0.0, 0.0, np.cos(theta / 2.0)), device=device, dtype=dtype) |
| expected = torch.tensor((theta, 0.0, 0.0), device=device, dtype=dtype) |
| with pytest.warns(UserWarning): |
| angle_axis = kornia.geometry.conversions.quaternion_to_angle_axis( |
| quaternion, order=QuaternionCoeffOrder.XYZW |
| ) |
| assert_close(angle_axis, expected, atol=atol, rtol=rtol) |
|
|
| def test_small_angle_x(self, device, dtype, atol, rtol): |
| theta = 1.0e-2 |
| quaternion = torch.tensor((np.cos(theta / 2.0), np.sin(theta / 2.0), 0.0, 0.0), device=device, dtype=dtype) |
| expected = torch.tensor((theta, 0.0, 0.0), device=device, dtype=dtype) |
| angle_axis = kornia.geometry.conversions.quaternion_to_angle_axis(quaternion, order=QuaternionCoeffOrder.WXYZ) |
| assert_close(angle_axis, expected, atol=atol, rtol=rtol) |
|
|
| def test_small_angle_y_xyzw(self, device, dtype, atol, rtol): |
| theta = 1.0e-2 |
| quaternion = torch.tensor((0.0, np.sin(theta / 2), 0.0, np.cos(theta / 2)), device=device, dtype=dtype) |
| expected = torch.tensor((0.0, theta, 0.0), device=device, dtype=dtype) |
| with pytest.warns(UserWarning): |
| angle_axis = kornia.geometry.conversions.quaternion_to_angle_axis( |
| quaternion, order=QuaternionCoeffOrder.XYZW |
| ) |
| assert_close(angle_axis, expected, atol=atol, rtol=rtol) |
|
|
| def test_small_angle_y(self, device, dtype, atol, rtol): |
| theta = 1.0e-2 |
| quaternion = torch.tensor((np.cos(theta / 2), 0.0, np.sin(theta / 2), 0.0), device=device, dtype=dtype) |
| expected = torch.tensor((0.0, theta, 0.0), device=device, dtype=dtype) |
| angle_axis = kornia.geometry.conversions.quaternion_to_angle_axis(quaternion, order=QuaternionCoeffOrder.WXYZ) |
| assert_close(angle_axis, expected, atol=atol, rtol=rtol) |
|
|
| def test_small_angle_z_xyzw(self, device, dtype, atol, rtol): |
| theta = 1.0e-2 |
| quaternion = torch.tensor((0.0, 0.0, np.sin(theta / 2), np.cos(theta / 2)), device=device, dtype=dtype) |
| expected = torch.tensor((0.0, 0.0, theta), device=device, dtype=dtype) |
| with pytest.warns(UserWarning): |
| angle_axis = kornia.geometry.conversions.quaternion_to_angle_axis( |
| quaternion, order=QuaternionCoeffOrder.XYZW |
| ) |
| assert_close(angle_axis, expected, atol=atol, rtol=rtol) |
|
|
| def test_small_angle_z(self, device, dtype, atol, rtol): |
| theta = 1.0e-2 |
| quaternion = torch.tensor((np.cos(theta / 2), 0.0, 0.0, np.sin(theta / 2)), device=device, dtype=dtype) |
| expected = torch.tensor((0.0, 0.0, theta), device=device, dtype=dtype) |
| angle_axis = kornia.geometry.conversions.quaternion_to_angle_axis(quaternion, order=QuaternionCoeffOrder.WXYZ) |
| assert_close(angle_axis, expected, atol=atol, rtol=rtol) |
|
|
| def test_gradcheck_xyzw(self, device, dtype): |
| eps = torch.finfo(dtype).eps |
| quaternion = torch.tensor((0.0, 0.0, 0.0, 1.0), device=device, dtype=dtype) + eps |
| quaternion = tensor_to_gradcheck_var(quaternion) |
| |
| with pytest.warns(UserWarning): |
| assert gradcheck( |
| partial(kornia.geometry.conversions.quaternion_to_angle_axis, order=QuaternionCoeffOrder.XYZW), |
| (quaternion,), |
| raise_exception=True, |
| ) |
|
|
| def test_gradcheck(self, device, dtype): |
| eps = torch.finfo(dtype).eps |
| quaternion = torch.tensor((1.0, 0.0, 0.0, 0.0), device=device, dtype=dtype) + eps |
| quaternion = tensor_to_gradcheck_var(quaternion) |
| |
| assert gradcheck( |
| partial(kornia.geometry.conversions.quaternion_to_angle_axis, order=QuaternionCoeffOrder.WXYZ), |
| (quaternion,), |
| raise_exception=True, |
| ) |
|
|
|
|
| class TestRotationMatrixToQuaternion: |
| @pytest.mark.parametrize("batch_size", (1, 3, 8)) |
| def test_smoke_batch_xyzw(self, batch_size, device, dtype): |
| matrix = torch.zeros(batch_size, 3, 3, device=device, dtype=dtype) |
| with pytest.warns(UserWarning): |
| quaternion = kornia.geometry.conversions.rotation_matrix_to_quaternion( |
| matrix, order=QuaternionCoeffOrder.XYZW |
| ) |
| assert quaternion.shape == (batch_size, 4) |
|
|
| @pytest.mark.parametrize("batch_size", (1, 3, 8)) |
| def test_smoke_batch(self, batch_size, device, dtype): |
| matrix = torch.zeros(batch_size, 3, 3, device=device, dtype=dtype) |
| quaternion = kornia.geometry.conversions.rotation_matrix_to_quaternion(matrix, order=QuaternionCoeffOrder.WXYZ) |
| assert quaternion.shape == (batch_size, 4) |
|
|
| def test_identity_xyzw(self, device, dtype, atol, rtol): |
| matrix = torch.tensor(((1.0, 0.0, 0.0), (0.0, 1.0, 0.0), (0.0, 0.0, 1.0)), device=device, dtype=dtype) |
| expected = torch.tensor((0.0, 0.0, 0.0, 1.0), device=device, dtype=dtype) |
| with pytest.warns(UserWarning): |
| quaternion = kornia.geometry.conversions.rotation_matrix_to_quaternion( |
| matrix, order=QuaternionCoeffOrder.XYZW |
| ) |
| assert_close(quaternion, expected, atol=atol, rtol=rtol) |
|
|
| def test_identity(self, device, dtype, atol, rtol): |
| matrix = torch.tensor(((1.0, 0.0, 0.0), (0.0, 1.0, 0.0), (0.0, 0.0, 1.0)), device=device, dtype=dtype) |
| expected = torch.tensor((1.0, 0.0, 0.0, 0.0), device=device, dtype=dtype) |
| quaternion = kornia.geometry.conversions.rotation_matrix_to_quaternion(matrix, order=QuaternionCoeffOrder.WXYZ) |
| assert_close(quaternion, expected, atol=atol, rtol=rtol) |
|
|
| def test_rot_x_45_xyzw(self, device, dtype, atol, rtol): |
| matrix = torch.tensor(((1.0, 0.0, 0.0), (0.0, 0.0, -1.0), (0.0, 1.0, 0.0)), device=device, dtype=dtype) |
| pi_half2 = torch.cos(kornia.pi / 4.0).to(device=device, dtype=dtype) |
| expected = torch.tensor((pi_half2, 0.0, 0.0, pi_half2), device=device, dtype=dtype) |
| with pytest.warns(UserWarning): |
| quaternion = kornia.geometry.conversions.rotation_matrix_to_quaternion( |
| matrix, order=QuaternionCoeffOrder.XYZW |
| ) |
| assert_close(quaternion, expected, atol=atol, rtol=rtol) |
|
|
| def test_rot_x_45(self, device, dtype, atol, rtol): |
| matrix = torch.tensor(((1.0, 0.0, 0.0), (0.0, 0.0, -1.0), (0.0, 1.0, 0.0)), device=device, dtype=dtype) |
| pi_half2 = torch.cos(kornia.pi / 4.0).to(device=device, dtype=dtype) |
| expected = torch.tensor((pi_half2, pi_half2, 0.0, 0.0), device=device, dtype=dtype) |
| quaternion = kornia.geometry.conversions.rotation_matrix_to_quaternion(matrix, order=QuaternionCoeffOrder.WXYZ) |
| assert_close(quaternion, expected, atol=atol, rtol=rtol) |
|
|
| def test_back_and_forth_xyzw(self, device, dtype, atol, rtol): |
| eps = torch.finfo(dtype).eps |
| matrix = torch.tensor(((1.0, 0.0, 0.0), (0.0, 0.0, -1.0), (0.0, 1.0, 0.0)), device=device, dtype=dtype) |
| with pytest.warns(UserWarning): |
| quaternion = kornia.geometry.conversions.rotation_matrix_to_quaternion( |
| matrix, eps=eps, order=QuaternionCoeffOrder.XYZW |
| ) |
| matrix_hat = kornia.geometry.conversions.quaternion_to_rotation_matrix( |
| quaternion, order=QuaternionCoeffOrder.XYZW |
| ) |
| assert_close(matrix, matrix_hat, atol=atol, rtol=rtol) |
|
|
| def test_back_and_forth(self, device, dtype, atol, rtol): |
| eps = torch.finfo(dtype).eps |
| matrix = torch.tensor(((1.0, 0.0, 0.0), (0.0, 0.0, -1.0), (0.0, 1.0, 0.0)), device=device, dtype=dtype) |
| quaternion = kornia.geometry.conversions.rotation_matrix_to_quaternion( |
| matrix, eps=eps, order=QuaternionCoeffOrder.WXYZ |
| ) |
| matrix_hat = kornia.geometry.conversions.quaternion_to_rotation_matrix( |
| quaternion, order=QuaternionCoeffOrder.WXYZ |
| ) |
| assert_close(matrix, matrix_hat, atol=atol, rtol=rtol) |
|
|
| def test_corner_case_xyzw(self, device, dtype, atol, rtol): |
| eps = torch.finfo(dtype).eps |
| matrix = torch.tensor( |
| ( |
| (-0.7799533010, -0.5432914495, 0.3106555045), |
| (0.0492402576, -0.5481169224, -0.8349509239), |
| (0.6238971353, -0.6359263659, 0.4542570710), |
| ), |
| device=device, |
| dtype=dtype, |
| ) |
| quaternion_true = torch.tensor( |
| (0.280136495828629, -0.440902262926102, 0.834015488624573, 0.177614107728004), device=device, dtype=dtype |
| ) |
| with pytest.warns(UserWarning): |
| quaternion = kornia.geometry.conversions.rotation_matrix_to_quaternion( |
| matrix, eps=eps, order=QuaternionCoeffOrder.XYZW |
| ) |
| torch.set_printoptions(precision=10) |
| assert_close(quaternion_true, quaternion, atol=atol, rtol=rtol) |
|
|
| def test_corner_case(self, device, dtype, atol, rtol): |
| eps = torch.finfo(dtype).eps |
| matrix = torch.tensor( |
| ( |
| (-0.7799533010, -0.5432914495, 0.3106555045), |
| (0.0492402576, -0.5481169224, -0.8349509239), |
| (0.6238971353, -0.6359263659, 0.4542570710), |
| ), |
| device=device, |
| dtype=dtype, |
| ) |
| quaternion_true = torch.tensor( |
| (0.177614107728004, 0.280136495828629, -0.440902262926102, 0.834015488624573), device=device, dtype=dtype |
| ) |
| quaternion = kornia.geometry.conversions.rotation_matrix_to_quaternion( |
| matrix, eps=eps, order=QuaternionCoeffOrder.WXYZ |
| ) |
| torch.set_printoptions(precision=10) |
| assert_close(quaternion_true, quaternion, atol=atol, rtol=rtol) |
|
|
| def test_gradcheck_xyzw(self, device, dtype): |
| eps = torch.finfo(dtype).eps |
| matrix = torch.eye(3, device=device, dtype=dtype) |
| matrix = tensor_to_gradcheck_var(matrix) |
| |
| with pytest.warns(UserWarning): |
| assert gradcheck( |
| partial( |
| kornia.geometry.conversions.rotation_matrix_to_quaternion, eps=eps, order=QuaternionCoeffOrder.XYZW |
| ), |
| (matrix,), |
| raise_exception=True, |
| ) |
|
|
| def test_gradcheck(self, device, dtype): |
| eps = torch.finfo(dtype).eps |
| matrix = torch.eye(3, device=device, dtype=dtype) |
| matrix = tensor_to_gradcheck_var(matrix) |
| |
| assert gradcheck( |
| partial( |
| kornia.geometry.conversions.rotation_matrix_to_quaternion, eps=eps, order=QuaternionCoeffOrder.WXYZ |
| ), |
| (matrix,), |
| raise_exception=True, |
| ) |
|
|
| @pytest.mark.skipif(torch.__version__.startswith('1.6'), reason='JIT Enum not handled.') |
| def test_jit_xyzw(self, device, dtype): |
| op = kornia.geometry.conversions.quaternion_log_to_exp |
| op_script = torch.jit.script(op) |
| quaternion = torch.tensor((0.0, 0.0, 1.0), device=device, dtype=dtype) |
| with pytest.warns(UserWarning): |
| actual = op_script(quaternion) |
| with pytest.warns(UserWarning): |
| expected = op(quaternion) |
| assert_close(actual, expected) |
|
|
| @pytest.mark.skipif(torch.__version__.startswith('1.6'), reason='JIT Enum not handled.') |
| def test_jit(self, device, dtype): |
| eps = torch.finfo(dtype).eps |
| op = kornia.geometry.conversions.quaternion_log_to_exp |
| op_script = torch.jit.script(op) |
| quaternion = torch.tensor((0.0, 0.0, 1.0), device=device, dtype=dtype) |
| actual = op_script(quaternion, eps=eps, order=QuaternionCoeffOrder.WXYZ) |
| expected = op(quaternion, eps=eps, order=QuaternionCoeffOrder.WXYZ) |
| assert_close(actual, expected) |
|
|
|
|
| class TestQuaternionToRotationMatrix: |
| @pytest.mark.parametrize("batch_size", (1, 3, 8)) |
| def test_smoke_batch_xyzw(self, batch_size, device, dtype): |
| quaternion = torch.zeros(batch_size, 4, device=device, dtype=dtype) |
| with pytest.warns(UserWarning): |
| matrix = kornia.geometry.conversions.quaternion_to_rotation_matrix( |
| quaternion, order=QuaternionCoeffOrder.XYZW |
| ) |
| assert matrix.shape == (batch_size, 3, 3) |
|
|
| @pytest.mark.parametrize("batch_size", (1, 3, 8)) |
| def test_smoke_batch(self, batch_size, device, dtype): |
| quaternion = torch.zeros(batch_size, 4, device=device, dtype=dtype) |
| matrix = kornia.geometry.conversions.quaternion_to_rotation_matrix(quaternion, order=QuaternionCoeffOrder.WXYZ) |
| assert matrix.shape == (batch_size, 3, 3) |
|
|
| def test_unit_quaternion_xyzw(self, device, dtype, atol, rtol): |
| quaternion = torch.tensor((0.0, 0.0, 0.0, 1.0), device=device, dtype=dtype) |
| expected = torch.tensor(((1.0, 0.0, 0.0), (0.0, 1.0, 0.0), (0.0, 0.0, 1.0)), device=device, dtype=dtype) |
| with pytest.warns(UserWarning): |
| matrix = kornia.geometry.conversions.quaternion_to_rotation_matrix( |
| quaternion, order=QuaternionCoeffOrder.XYZW |
| ) |
| assert_close(matrix, expected, atol=atol, rtol=rtol) |
|
|
| def test_unit_quaternion(self, device, dtype, atol, rtol): |
| quaternion = torch.tensor((1.0, 0.0, 0.0, 0.0), device=device, dtype=dtype) |
| expected = torch.tensor(((1.0, 0.0, 0.0), (0.0, 1.0, 0.0), (0.0, 0.0, 1.0)), device=device, dtype=dtype) |
| matrix = kornia.geometry.conversions.quaternion_to_rotation_matrix(quaternion, order=QuaternionCoeffOrder.WXYZ) |
| assert_close(matrix, expected, atol=atol, rtol=rtol) |
|
|
| def test_x_rotation_xyzw(self, device, dtype, atol, rtol): |
| quaternion = torch.tensor((1.0, 0.0, 0.0, 0.0), device=device, dtype=dtype) |
| expected = torch.tensor(((1.0, 0.0, 0.0), (0.0, -1.0, 0.0), (0.0, 0.0, -1.0)), device=device, dtype=dtype) |
| with pytest.warns(UserWarning): |
| matrix = kornia.geometry.conversions.quaternion_to_rotation_matrix( |
| quaternion, order=QuaternionCoeffOrder.XYZW |
| ) |
| assert_close(matrix, expected, atol=atol, rtol=rtol) |
|
|
| def test_x_rotation(self, device, dtype, atol, rtol): |
| quaternion = torch.tensor((0.0, 1.0, 0.0, 0.0), device=device, dtype=dtype) |
| expected = torch.tensor(((1.0, 0.0, 0.0), (0.0, -1.0, 0.0), (0.0, 0.0, -1.0)), device=device, dtype=dtype) |
| matrix = kornia.geometry.conversions.quaternion_to_rotation_matrix(quaternion, order=QuaternionCoeffOrder.WXYZ) |
| assert_close(matrix, expected, atol=atol, rtol=rtol) |
|
|
| def test_y_rotation_xyzw(self, device, dtype, atol, rtol): |
| quaternion = torch.tensor((0.0, 1.0, 0.0, 0.0), device=device, dtype=dtype) |
| expected = torch.tensor(((-1.0, 0.0, 0.0), (0.0, 1.0, 0.0), (0.0, 0.0, -1.0)), device=device, dtype=dtype) |
|
|
| with pytest.warns(UserWarning): |
| matrix = kornia.geometry.conversions.quaternion_to_rotation_matrix( |
| quaternion, order=QuaternionCoeffOrder.XYZW |
| ) |
| assert_close(matrix, expected, atol=atol, rtol=rtol) |
|
|
| def test_y_rotation(self, device, dtype, atol, rtol): |
| quaternion = torch.tensor((0.0, 0.0, 1.0, 0.0), device=device, dtype=dtype) |
| expected = torch.tensor(((-1.0, 0.0, 0.0), (0.0, 1.0, 0.0), (0.0, 0.0, -1.0)), device=device, dtype=dtype) |
| matrix = kornia.geometry.conversions.quaternion_to_rotation_matrix(quaternion, order=QuaternionCoeffOrder.WXYZ) |
| assert_close(matrix, expected, atol=atol, rtol=rtol) |
|
|
| def test_z_rotation_xyzw(self, device, dtype, atol, rtol): |
| quaternion = torch.tensor((0.0, 0.0, 1.0, 0.0), device=device, dtype=dtype) |
| expected = torch.tensor(((-1.0, 0.0, 0.0), (0.0, -1.0, 0.0), (0.0, 0.0, 1.0)), device=device, dtype=dtype) |
| with pytest.warns(UserWarning): |
| matrix = kornia.geometry.conversions.quaternion_to_rotation_matrix( |
| quaternion, order=QuaternionCoeffOrder.XYZW |
| ) |
| assert_close(matrix, expected, atol=atol, rtol=rtol) |
|
|
| def test_z_rotation(self, device, dtype, atol, rtol): |
| quaternion = torch.tensor((0.0, 0.0, 0.0, 1.0), device=device, dtype=dtype) |
| expected = torch.tensor(((-1.0, 0.0, 0.0), (0.0, -1.0, 0.0), (0.0, 0.0, 1.0)), device=device, dtype=dtype) |
| matrix = kornia.geometry.conversions.quaternion_to_rotation_matrix(quaternion, order=QuaternionCoeffOrder.WXYZ) |
| assert_close(matrix, expected, atol=atol, rtol=rtol) |
|
|
| def test_gradcheck_xyzw(self, device, dtype): |
| quaternion = torch.tensor((0.0, 0.0, 0.0, 1.0), device=device, dtype=dtype) |
| quaternion = tensor_to_gradcheck_var(quaternion) |
| |
| with pytest.warns(UserWarning): |
| assert gradcheck( |
| partial(kornia.geometry.conversions.quaternion_to_rotation_matrix, order=QuaternionCoeffOrder.XYZW), |
| (quaternion,), |
| raise_exception=True, |
| ) |
|
|
| def test_gradcheck(self, device, dtype): |
| quaternion = torch.tensor((0.0, 0.0, 0.0, 1.0), device=device, dtype=dtype) |
| quaternion = tensor_to_gradcheck_var(quaternion) |
| |
| assert gradcheck( |
| partial(kornia.geometry.conversions.quaternion_to_rotation_matrix, order=QuaternionCoeffOrder.WXYZ), |
| (quaternion,), |
| raise_exception=True, |
| ) |
|
|
| @pytest.mark.skipif(torch.__version__.startswith('1.6'), reason='JIT Enum not handled.') |
| def test_jit_xyzw(self, device, dtype): |
| op = kornia.geometry.conversions.quaternion_to_rotation_matrix |
| op_jit = torch.jit.script(op) |
| quaternion = torch.tensor((0.0, 0.0, 1.0, 0.0), device=device, dtype=dtype) |
| with pytest.warns(UserWarning): |
| assert_close(op(quaternion), op_jit(quaternion)) |
|
|
| @pytest.mark.skipif(torch.__version__.startswith('1.6'), reason='JIT Enum not handled.') |
| def test_jit(self, device, dtype): |
| op = kornia.geometry.conversions.quaternion_to_rotation_matrix |
| op_jit = torch.jit.script(op) |
| quaternion = torch.tensor((0.0, 0.0, 0.0, 1.0), device=device, dtype=dtype) |
| assert_close( |
| op(quaternion, order=QuaternionCoeffOrder.WXYZ), op_jit(quaternion, order=QuaternionCoeffOrder.WXYZ) |
| ) |
|
|
|
|
| class TestQuaternionLogToExp: |
| @pytest.mark.parametrize("batch_size", (1, 3, 8)) |
| def test_smoke_batch_xyzw(self, batch_size, device, dtype): |
| quaternion_log = torch.zeros(batch_size, 3, device=device, dtype=dtype) |
| with pytest.warns(UserWarning): |
| quaternion_exp = kornia.geometry.conversions.quaternion_log_to_exp( |
| quaternion_log, order=QuaternionCoeffOrder.XYZW |
| ) |
| assert quaternion_exp.shape == (batch_size, 4) |
|
|
| @pytest.mark.parametrize("batch_size", (1, 3, 8)) |
| def test_smoke_batch(self, batch_size, device, dtype): |
| quaternion_log = torch.zeros(batch_size, 3, device=device, dtype=dtype) |
| quaternion_exp = kornia.geometry.conversions.quaternion_log_to_exp( |
| quaternion_log, order=QuaternionCoeffOrder.WXYZ |
| ) |
| assert quaternion_exp.shape == (batch_size, 4) |
|
|
| def test_unit_quaternion_xyzw(self, device, dtype, atol, rtol): |
| eps = torch.finfo(dtype).eps |
| quaternion_log = torch.tensor((0.0, 0.0, 0.0), device=device, dtype=dtype) |
| expected = torch.tensor((0.0, 0.0, 0.0, 1.0), device=device, dtype=dtype) |
| with pytest.warns(UserWarning): |
| quaternion_exp = kornia.geometry.conversions.quaternion_log_to_exp( |
| quaternion_log, eps=eps, order=QuaternionCoeffOrder.XYZW |
| ) |
| assert_close(quaternion_exp, expected, atol=atol, rtol=rtol) |
|
|
| def test_unit_quaternion(self, device, dtype, atol, rtol): |
| eps = torch.finfo(dtype).eps |
| quaternion_log = torch.tensor((0.0, 0.0, 0.0), device=device, dtype=dtype) |
| expected = torch.tensor((1.0, 0.0, 0.0, 0.0), device=device, dtype=dtype) |
| quaternion_exp = kornia.geometry.conversions.quaternion_log_to_exp( |
| quaternion_log, eps=eps, order=QuaternionCoeffOrder.WXYZ |
| ) |
| assert_close(quaternion_exp, expected, atol=atol, rtol=rtol) |
|
|
| def test_pi_quaternion_x_xyzw(self, device, dtype, atol, rtol): |
| eps = torch.finfo(dtype).eps |
| one = torch.tensor(1.0, device=device, dtype=dtype) |
| quaternion_log = torch.tensor((1.0, 0.0, 0.0), device=device, dtype=dtype) |
| expected = torch.tensor((torch.sin(one), 0.0, 0.0, torch.cos(one)), device=device, dtype=dtype) |
| with pytest.warns(UserWarning): |
| quaternion_exp = kornia.geometry.conversions.quaternion_log_to_exp( |
| quaternion_log, eps=eps, order=QuaternionCoeffOrder.XYZW |
| ) |
| assert_close(quaternion_exp, expected, atol=atol, rtol=rtol) |
|
|
| def test_pi_quaternion_x(self, device, dtype, atol, rtol): |
| eps = torch.finfo(dtype).eps |
| one = torch.tensor(1.0, device=device, dtype=dtype) |
| quaternion_log = torch.tensor((1.0, 0.0, 0.0), device=device, dtype=dtype) |
| expected = torch.tensor((torch.cos(one), torch.sin(one), 0.0, 0.0), device=device, dtype=dtype) |
| quaternion_exp = kornia.geometry.conversions.quaternion_log_to_exp( |
| quaternion_log, eps=eps, order=QuaternionCoeffOrder.WXYZ |
| ) |
| assert_close(quaternion_exp, expected, atol=atol, rtol=rtol) |
|
|
| def test_pi_quaternion_y_xyzw(self, device, dtype, atol, rtol): |
| eps = torch.finfo(dtype).eps |
| one = torch.tensor(1.0, device=device, dtype=dtype) |
| quaternion_log = torch.tensor((0.0, 1.0, 0.0), device=device, dtype=dtype) |
| expected = torch.tensor((0.0, torch.sin(one), 0.0, torch.cos(one)), device=device, dtype=dtype) |
| with pytest.warns(UserWarning): |
| quaternion_exp = kornia.geometry.conversions.quaternion_log_to_exp( |
| quaternion_log, eps=eps, order=QuaternionCoeffOrder.XYZW |
| ) |
| assert_close(quaternion_exp, expected, atol=atol, rtol=rtol) |
|
|
| def test_pi_quaternion_y(self, device, dtype, atol, rtol): |
| eps = torch.finfo(dtype).eps |
| one = torch.tensor(1.0, device=device, dtype=dtype) |
| quaternion_log = torch.tensor((0.0, 1.0, 0.0), device=device, dtype=dtype) |
| expected = torch.tensor((torch.cos(one), 0.0, torch.sin(one), 0.0), device=device, dtype=dtype) |
| quaternion_exp = kornia.geometry.conversions.quaternion_log_to_exp( |
| quaternion_log, eps=eps, order=QuaternionCoeffOrder.WXYZ |
| ) |
| assert_close(quaternion_exp, expected, atol=atol, rtol=rtol) |
|
|
| def test_pi_quaternion_z_xyzw(self, device, dtype, atol, rtol): |
| eps = torch.finfo(dtype).eps |
| one = torch.tensor(1.0, device=device, dtype=dtype) |
| quaternion_log = torch.tensor((0.0, 0.0, 1.0), device=device, dtype=dtype) |
| expected = torch.tensor((0.0, 0.0, torch.sin(one), torch.cos(one)), device=device, dtype=dtype) |
|
|
| with pytest.warns(UserWarning): |
| quaternion_exp = kornia.geometry.conversions.quaternion_log_to_exp( |
| quaternion_log, eps=eps, order=QuaternionCoeffOrder.XYZW |
| ) |
| assert_close(quaternion_exp, expected, atol=atol, rtol=rtol) |
|
|
| def test_pi_quaternion_z(self, device, dtype, atol, rtol): |
| eps = torch.finfo(dtype).eps |
| one = torch.tensor(1.0, device=device, dtype=dtype) |
| quaternion_log = torch.tensor((0.0, 0.0, 1.0), device=device, dtype=dtype) |
| expected = torch.tensor((torch.cos(one), 0.0, 0.0, torch.sin(one)), device=device, dtype=dtype) |
| quaternion_exp = kornia.geometry.conversions.quaternion_log_to_exp( |
| quaternion_log, eps=eps, order=QuaternionCoeffOrder.WXYZ |
| ) |
| assert_close(quaternion_exp, expected, atol=atol, rtol=rtol) |
|
|
| def test_back_and_forth_xyzw(self, device, dtype, atol, rtol): |
| eps = torch.finfo(dtype).eps |
| quaternion_log = torch.tensor((1.0, 0.0, 0.0), device=device, dtype=dtype) |
|
|
| with pytest.warns(UserWarning): |
| quaternion_exp = kornia.geometry.conversions.quaternion_log_to_exp( |
| quaternion_log, eps=eps, order=QuaternionCoeffOrder.XYZW |
| ) |
| with pytest.warns(UserWarning): |
| quaternion_log_hat = kornia.geometry.conversions.quaternion_exp_to_log( |
| quaternion_exp, eps=eps, order=QuaternionCoeffOrder.XYZW |
| ) |
| assert_close(quaternion_log, quaternion_log_hat, atol=atol, rtol=rtol) |
|
|
| def test_back_and_forth(self, device, dtype, atol, rtol): |
| eps = torch.finfo(dtype).eps |
| quaternion_log = torch.tensor((1.0, 0.0, 0.0), device=device, dtype=dtype) |
|
|
| quaternion_exp = kornia.geometry.conversions.quaternion_log_to_exp( |
| quaternion_log, eps=eps, order=QuaternionCoeffOrder.WXYZ |
| ) |
| quaternion_log_hat = kornia.geometry.conversions.quaternion_exp_to_log( |
| quaternion_exp, eps=eps, order=QuaternionCoeffOrder.WXYZ |
| ) |
| assert_close(quaternion_log, quaternion_log_hat, atol=atol, rtol=rtol) |
|
|
| def test_gradcheck_xyzw(self, device, dtype): |
| eps = torch.finfo(dtype).eps |
| quaternion = torch.tensor((0.0, 0.0, 1.0), device=device, dtype=dtype) |
| quaternion = tensor_to_gradcheck_var(quaternion) |
| |
| with pytest.warns(UserWarning): |
| assert gradcheck( |
| partial(kornia.geometry.conversions.quaternion_log_to_exp, eps=eps, order=QuaternionCoeffOrder.XYZW), |
| (quaternion,), |
| raise_exception=True, |
| ) |
|
|
| def test_gradcheck(self, device, dtype): |
| eps = torch.finfo(dtype).eps |
| quaternion = torch.tensor((0.0, 0.0, 1.0), device=device, dtype=dtype) |
| quaternion = tensor_to_gradcheck_var(quaternion) |
| |
| assert gradcheck( |
| partial(kornia.geometry.conversions.quaternion_log_to_exp, eps=eps, order=QuaternionCoeffOrder.WXYZ), |
| (quaternion,), |
| raise_exception=True, |
| ) |
|
|
| @pytest.mark.skipif(torch.__version__.startswith('1.6'), reason='JIT Enum not handled.') |
| def test_jit_xyzw(self, device, dtype): |
| op = kornia.geometry.conversions.quaternion_log_to_exp |
| op_jit = torch.jit.script(op) |
| quaternion = torch.tensor((0.0, 0.0, 1.0), device=device, dtype=dtype) |
| with pytest.warns(UserWarning): |
| assert_close( |
| op(quaternion, order=QuaternionCoeffOrder.XYZW), op_jit(quaternion, order=QuaternionCoeffOrder.XYZW) |
| ) |
|
|
| @pytest.mark.skipif(torch.__version__.startswith('1.6'), reason='JIT Enum not handled.') |
| def test_jit(self, device, dtype): |
| op = kornia.geometry.conversions.quaternion_log_to_exp |
| op_jit = torch.jit.script(op) |
| quaternion = torch.tensor((0.0, 0.0, 1.0), device=device, dtype=dtype) |
| assert_close( |
| op(quaternion, order=QuaternionCoeffOrder.WXYZ), op_jit(quaternion, order=QuaternionCoeffOrder.WXYZ) |
| ) |
|
|
|
|
| class TestQuaternionExpToLog: |
| @pytest.mark.parametrize("batch_size", (1, 3, 8)) |
| def test_smoke_batch_xyzw(self, batch_size, device, dtype): |
| eps = torch.finfo(dtype).eps |
| quaternion_exp = torch.zeros(batch_size, 4, device=device, dtype=dtype) |
| with pytest.warns(UserWarning): |
| quaternion_log = kornia.geometry.conversions.quaternion_exp_to_log( |
| quaternion_exp, eps=eps, order=QuaternionCoeffOrder.XYZW |
| ) |
| assert quaternion_log.shape == (batch_size, 3) |
|
|
| @pytest.mark.parametrize("batch_size", (1, 3, 8)) |
| def test_smoke_batch(self, batch_size, device, dtype): |
| eps = torch.finfo(dtype).eps |
| quaternion_exp = torch.zeros(batch_size, 4, device=device, dtype=dtype) |
| quaternion_log = kornia.geometry.conversions.quaternion_exp_to_log( |
| quaternion_exp, eps=eps, order=QuaternionCoeffOrder.WXYZ |
| ) |
| assert quaternion_log.shape == (batch_size, 3) |
|
|
| def test_unit_quaternion_xyzw(self, device, dtype, atol, rtol): |
| eps = torch.finfo(dtype).eps |
| quaternion_exp = torch.tensor((0.0, 0.0, 0.0, 1.0), device=device, dtype=dtype) |
| expected = torch.tensor((0.0, 0.0, 0.0), device=device, dtype=dtype) |
| with pytest.warns(UserWarning): |
| quaternion_log = kornia.geometry.conversions.quaternion_exp_to_log( |
| quaternion_exp, eps=eps, order=QuaternionCoeffOrder.XYZW |
| ) |
| assert_close(quaternion_log, expected, atol=atol, rtol=rtol) |
|
|
| def test_unit_quaternion(self, device, dtype, atol, rtol): |
| eps = torch.finfo(dtype).eps |
| quaternion_exp = torch.tensor((1.0, 0.0, 0.0, 0.0), device=device, dtype=dtype) |
| expected = torch.tensor((0.0, 0.0, 0.0), device=device, dtype=dtype) |
| quaternion_log = kornia.geometry.conversions.quaternion_exp_to_log( |
| quaternion_exp, eps=eps, order=QuaternionCoeffOrder.WXYZ |
| ) |
| assert_close(quaternion_log, expected, atol=atol, rtol=rtol) |
|
|
| def test_pi_quaternion_x_xyzw(self, device, dtype, atol, rtol): |
| eps = torch.finfo(dtype).eps |
| quaternion_exp = torch.tensor((1.0, 0.0, 0.0, 0.0), device=device, dtype=dtype) |
| expected = torch.tensor((kornia.pi / 2.0, 0.0, 0.0), device=device, dtype=dtype) |
| with pytest.warns(UserWarning): |
| quaternion_log = kornia.geometry.conversions.quaternion_exp_to_log( |
| quaternion_exp, eps=eps, order=QuaternionCoeffOrder.XYZW |
| ) |
| assert_close(quaternion_log, expected, atol=atol, rtol=rtol) |
|
|
| def test_pi_quaternion_x(self, device, dtype, atol, rtol): |
| eps = torch.finfo(dtype).eps |
| quaternion_exp = torch.tensor((0.0, 1.0, 0.0, 0.0), device=device, dtype=dtype) |
| expected = torch.tensor((kornia.pi / 2.0, 0.0, 0.0), device=device, dtype=dtype) |
| quaternion_log = kornia.geometry.conversions.quaternion_exp_to_log( |
| quaternion_exp, eps=eps, order=QuaternionCoeffOrder.WXYZ |
| ) |
| assert_close(quaternion_log, expected, atol=atol, rtol=rtol) |
|
|
| def test_pi_quaternion_y_xyzw(self, device, dtype, atol, rtol): |
| eps = torch.finfo(dtype).eps |
| quaternion_exp = torch.tensor((0.0, 1.0, 0.0, 0.0), device=device, dtype=dtype) |
| expected = torch.tensor((0.0, kornia.pi / 2.0, 0.0), device=device, dtype=dtype) |
| with pytest.warns(UserWarning): |
| quaternion_log = kornia.geometry.conversions.quaternion_exp_to_log( |
| quaternion_exp, eps=eps, order=QuaternionCoeffOrder.XYZW |
| ) |
| assert_close(quaternion_log, expected, atol=atol, rtol=rtol) |
|
|
| def test_pi_quaternion_y(self, device, dtype, atol, rtol): |
| eps = torch.finfo(dtype).eps |
| quaternion_exp = torch.tensor((0.0, 0.0, 1.0, 0.0), device=device, dtype=dtype) |
| expected = torch.tensor((0.0, kornia.pi / 2.0, 0.0), device=device, dtype=dtype) |
| quaternion_log = kornia.geometry.conversions.quaternion_exp_to_log( |
| quaternion_exp, eps=eps, order=QuaternionCoeffOrder.WXYZ |
| ) |
| assert_close(quaternion_log, expected, atol=atol, rtol=rtol) |
|
|
| def test_pi_quaternion_z_xyzw(self, device, dtype, atol, rtol): |
| eps = torch.finfo(dtype).eps |
| quaternion_exp = torch.tensor((0.0, 0.0, 1.0, 0.0), device=device, dtype=dtype) |
| expected = torch.tensor((0.0, 0.0, kornia.pi / 2.0), device=device, dtype=dtype) |
| with pytest.warns(UserWarning): |
| quaternion_log = kornia.geometry.conversions.quaternion_exp_to_log( |
| quaternion_exp, eps=eps, order=QuaternionCoeffOrder.XYZW |
| ) |
| assert_close(quaternion_log, expected, atol=atol, rtol=rtol) |
|
|
| def test_pi_quaternion_z(self, device, dtype, atol, rtol): |
| eps = torch.finfo(dtype).eps |
| quaternion_exp = torch.tensor((0.0, 0.0, 0.0, 1.0), device=device, dtype=dtype) |
| expected = torch.tensor((0.0, 0.0, kornia.pi / 2.0), device=device, dtype=dtype) |
| quaternion_log = kornia.geometry.conversions.quaternion_exp_to_log( |
| quaternion_exp, eps=eps, order=QuaternionCoeffOrder.WXYZ |
| ) |
| assert_close(quaternion_log, expected, atol=atol, rtol=rtol) |
|
|
| def test_back_and_forth_xyzw(self, device, dtype, atol, rtol): |
| eps = torch.finfo(dtype).eps |
| quaternion_exp = torch.tensor((1.0, 0.0, 0.0, 0.0), device=device, dtype=dtype) |
|
|
| with pytest.warns(UserWarning): |
| quaternion_log = kornia.geometry.conversions.quaternion_exp_to_log( |
| quaternion_exp, eps=eps, order=QuaternionCoeffOrder.XYZW |
| ) |
| with pytest.warns(UserWarning): |
| quaternion_exp_hat = kornia.geometry.conversions.quaternion_log_to_exp( |
| quaternion_log, eps=eps, order=QuaternionCoeffOrder.XYZW |
| ) |
| assert_close(quaternion_exp, quaternion_exp_hat, atol=atol, rtol=rtol) |
|
|
| def test_back_and_forth(self, device, dtype, atol, rtol): |
| eps = torch.finfo(dtype).eps |
| quaternion_exp = torch.tensor((0.0, 1.0, 0.0, 0.0), device=device, dtype=dtype) |
| quaternion_log = kornia.geometry.conversions.quaternion_exp_to_log( |
| quaternion_exp, eps=eps, order=QuaternionCoeffOrder.WXYZ |
| ) |
| quaternion_exp_hat = kornia.geometry.conversions.quaternion_log_to_exp( |
| quaternion_log, eps=eps, order=QuaternionCoeffOrder.WXYZ |
| ) |
| assert_close(quaternion_exp, quaternion_exp_hat, atol=atol, rtol=rtol) |
|
|
| def test_gradcheck_xyzw(self, device, dtype): |
| eps = torch.finfo(dtype).eps |
| quaternion = torch.tensor((1.0, 0.0, 0.0, 0.0), device=device, dtype=dtype) |
| quaternion = tensor_to_gradcheck_var(quaternion) |
| |
| with pytest.warns(UserWarning): |
| assert gradcheck( |
| partial(kornia.geometry.conversions.quaternion_exp_to_log, eps=eps, order=QuaternionCoeffOrder.XYZW), |
| (quaternion,), |
| raise_exception=True, |
| ) |
|
|
| def test_gradcheck(self, device, dtype): |
| eps = torch.finfo(dtype).eps |
| quaternion = torch.tensor((0.0, 1.0, 0.0, 0.0), device=device, dtype=dtype) |
| quaternion = tensor_to_gradcheck_var(quaternion) |
| |
| assert gradcheck( |
| partial(kornia.geometry.conversions.quaternion_exp_to_log, eps=eps, order=QuaternionCoeffOrder.WXYZ), |
| (quaternion,), |
| raise_exception=True, |
| ) |
|
|
| @pytest.mark.skipif(torch.__version__.startswith('1.6'), reason='JIT Enum not handled.') |
| def test_jit_xyzw(self, device, dtype, atol, rtol): |
| op = kornia.geometry.conversions.quaternion_exp_to_log |
| op_jit = torch.jit.script(op) |
| quaternion = torch.tensor((0.0, 0.0, 1.0, 0.0), device=device, dtype=dtype) |
| with pytest.warns(UserWarning): |
| assert_close(op(quaternion), op_jit(quaternion), atol=atol, rtol=rtol) |
|
|
| @pytest.mark.skipif(torch.__version__.startswith('1.6'), reason='JIT Enum not handled.') |
| def test_jit(self, device, dtype, atol, rtol): |
| op = kornia.geometry.conversions.quaternion_exp_to_log |
| op_script = torch.jit.script(op) |
|
|
| quaternion = torch.tensor((0.0, 0.0, 0.0, 1.0), device=device, dtype=dtype) |
| actual = op_script(quaternion, eps=torch.finfo(dtype).eps, order=QuaternionCoeffOrder.WXYZ) |
| expected = op(quaternion, eps=torch.finfo(dtype).eps, order=QuaternionCoeffOrder.WXYZ) |
| assert_close(actual, expected, atol=atol, rtol=rtol) |
|
|
|
|
| class TestAngleAxisToRotationMatrix: |
| @pytest.mark.parametrize("batch_size", (1, 2, 5)) |
| def test_rand_angle_axis_gradcheck(self, batch_size, device, dtype, atol, rtol): |
| |
| angle_axis = torch.rand(batch_size, 3, device=device, dtype=dtype) |
| eye_batch = create_eye_batch(batch_size, 3, device=device, dtype=dtype) |
|
|
| |
| rotation_matrix = kornia.geometry.conversions.angle_axis_to_rotation_matrix(angle_axis) |
|
|
| rotation_matrix_eye = torch.matmul(rotation_matrix, rotation_matrix.transpose(-2, -1)) |
| assert_close(rotation_matrix_eye, eye_batch, atol=atol, rtol=rtol) |
|
|
| |
| angle_axis = tensor_to_gradcheck_var(angle_axis) |
| assert gradcheck(kornia.geometry.conversions.angle_axis_to_rotation_matrix, (angle_axis,), raise_exception=True) |
|
|
| def test_angle_axis_to_rotation_matrix(self, device, dtype, atol, rtol): |
| rmat_1 = torch.tensor( |
| ( |
| (-0.30382753, -0.95095137, -0.05814062), |
| (-0.71581715, 0.26812278, -0.64476041), |
| (0.62872461, -0.15427791, -0.76217038), |
| ), |
| device=device, |
| dtype=dtype, |
| ) |
| rvec_1 = torch.tensor((1.50485376, -2.10737739, 0.7214174), device=device, dtype=dtype) |
|
|
| rmat_2 = torch.tensor( |
| ( |
| (0.6027768, -0.79275544, -0.09054801), |
| (-0.67915707, -0.56931658, 0.46327563), |
| (-0.41881476, -0.21775548, -0.88157628), |
| ), |
| device=device, |
| dtype=dtype, |
| ) |
| rvec_2 = torch.tensor((-2.44916812, 1.18053411, 0.4085298), device=device, dtype=dtype) |
| rmat = torch.stack((rmat_2, rmat_1), dim=0) |
| rvec = torch.stack((rvec_2, rvec_1), dim=0) |
|
|
| assert_close(kornia.geometry.conversions.angle_axis_to_rotation_matrix(rvec), rmat, atol=atol, rtol=rtol) |
|
|
|
|
| class TestRotationMatrixToAngleAxis: |
| @pytest.mark.parametrize("batch_size", (1, 2, 5)) |
| def test_rand_quaternion_gradcheck(self, batch_size, device, dtype, atol, rtol): |
| |
| quaternion = torch.rand(batch_size, 4, device=device, dtype=dtype) |
| quaternion = kornia.geometry.conversions.normalize_quaternion(quaternion + 1e-6) |
| rotation_matrix = kornia.geometry.conversions.quaternion_to_rotation_matrix( |
| quaternion=quaternion, order=QuaternionCoeffOrder.WXYZ |
| ) |
|
|
| eye_batch = create_eye_batch(batch_size, 3, device=device, dtype=dtype) |
| rotation_matrix_eye = torch.matmul(rotation_matrix, rotation_matrix.transpose(-2, -1)) |
| |
| assert_close(rotation_matrix_eye, eye_batch, atol=atol * 10.0, rtol=rtol * 10.0) |
|
|
| |
| rotation_matrix = tensor_to_gradcheck_var(rotation_matrix) |
| assert gradcheck( |
| kornia.geometry.conversions.rotation_matrix_to_angle_axis, (rotation_matrix,), raise_exception=True |
| ) |
|
|
| def test_rotation_matrix_to_angle_axis(self, device, dtype, atol, rtol): |
| rmat_1 = torch.tensor( |
| ( |
| (-0.30382753, -0.95095137, -0.05814062), |
| (-0.71581715, 0.26812278, -0.64476041), |
| (0.62872461, -0.15427791, -0.76217038), |
| ), |
| device=device, |
| dtype=dtype, |
| ) |
| rvec_1 = torch.tensor((1.50485376, -2.10737739, 0.7214174), device=device, dtype=dtype) |
|
|
| rmat_2 = torch.tensor( |
| ( |
| (0.6027768, -0.79275544, -0.09054801), |
| (-0.67915707, -0.56931658, 0.46327563), |
| (-0.41881476, -0.21775548, -0.88157628), |
| ), |
| device=device, |
| dtype=dtype, |
| ) |
| rvec_2 = torch.tensor((-2.44916812, 1.18053411, 0.4085298), device=device, dtype=dtype) |
| rmat = torch.stack((rmat_2, rmat_1), dim=0) |
| rvec = torch.stack((rvec_2, rvec_1), dim=0) |
|
|
| assert_close(kornia.geometry.conversions.rotation_matrix_to_angle_axis(rmat), rvec, atol=atol, rtol=rtol) |
|
|
|
|
| def test_pi(): |
| assert_close(kornia.constants.pi.item(), 3.141592) |
|
|
|
|
| @pytest.mark.parametrize("batch_shape", [(2, 3), (1, 2, 3), (2, 3, 3), (5, 5, 3)]) |
| def test_rad2deg(batch_shape, device, dtype): |
| |
| x_rad = kornia.constants.pi * torch.rand(batch_shape, device=device, dtype=dtype) |
|
|
| |
| x_deg = kornia.geometry.conversions.rad2deg(x_rad) |
| x_deg_to_rad = kornia.geometry.conversions.deg2rad(x_deg) |
|
|
| |
| assert_close(x_rad, x_deg_to_rad) |
|
|
| |
| assert gradcheck(kornia.geometry.conversions.rad2deg, (tensor_to_gradcheck_var(x_rad),), raise_exception=True) |
|
|
|
|
| @pytest.mark.parametrize("batch_shape", [(2, 3), (1, 2, 3), (2, 3, 3), (5, 5, 3)]) |
| def test_deg2rad(batch_shape, device, dtype, atol, rtol): |
| |
| x_deg = 180.0 * torch.rand(batch_shape, device=device, dtype=dtype) |
|
|
| |
| x_rad = kornia.geometry.conversions.deg2rad(x_deg) |
| x_rad_to_deg = kornia.geometry.conversions.rad2deg(x_rad) |
|
|
| assert_close(x_deg, x_rad_to_deg, atol=atol, rtol=rtol) |
|
|
| assert gradcheck(kornia.geometry.conversions.deg2rad, (tensor_to_gradcheck_var(x_deg),), raise_exception=True) |
|
|
|
|
| class TestPolCartConversions: |
| def test_smoke(self, device, dtype): |
| x = torch.ones(1, 1, 1, 1, device=device, dtype=dtype) |
| assert kornia.geometry.conversions.pol2cart(x, x) is not None |
| assert kornia.geometry.conversions.cart2pol(x, x) is not None |
|
|
| @pytest.mark.parametrize("batch_shape", [(2, 3), (1, 2, 3), (2, 3, 3), (5, 5, 3)]) |
| def test_pol2cart(self, batch_shape, device, dtype): |
| |
| rho = torch.rand(batch_shape, dtype=dtype) |
| phi = kornia.constants.pi * torch.rand(batch_shape, dtype=dtype) |
| rho = rho.to(device) |
| phi = phi.to(device) |
|
|
| |
| x_pol2cart, y_pol2cart = kornia.geometry.conversions.pol2cart(rho, phi) |
| rho_pol2cart, phi_pol2cart = kornia.geometry.conversions.cart2pol(x_pol2cart, y_pol2cart, 0) |
|
|
| assert_close(rho, rho_pol2cart) |
| assert_close(phi, phi_pol2cart) |
|
|
| assert gradcheck( |
| kornia.geometry.conversions.pol2cart, |
| (tensor_to_gradcheck_var(rho), tensor_to_gradcheck_var(phi)), |
| raise_exception=True, |
| ) |
|
|
| @pytest.mark.parametrize("batch_shape", [(2, 3), (1, 2, 3), (2, 3, 3), (5, 5, 3)]) |
| def test_cart2pol(self, batch_shape, device, dtype): |
| |
| x = torch.rand(batch_shape, dtype=dtype) |
| y = torch.rand(batch_shape, dtype=dtype) |
| x = x.to(device) |
| y = y.to(device) |
|
|
| |
| rho_cart2pol, phi_cart2pol = kornia.geometry.conversions.cart2pol(x, y, 0) |
| x_cart2pol, y_cart2pol = kornia.geometry.conversions.pol2cart(rho_cart2pol, phi_cart2pol) |
|
|
| assert_close(x, x_cart2pol) |
| assert_close(y, y_cart2pol) |
|
|
| assert gradcheck( |
| kornia.geometry.conversions.cart2pol, |
| (tensor_to_gradcheck_var(x), tensor_to_gradcheck_var(y)), |
| raise_exception=True, |
| ) |
|
|
|
|
| class TestConvertPointsToHomogeneous: |
| def test_convert_points(self, device, dtype): |
| |
| points_h = torch.tensor( |
| [[1.0, 2.0, 1.0], [0.0, 1.0, 2.0], [2.0, 1.0, 0.0], [-1.0, -2.0, -1.0], [0.0, 1.0, -2.0]], |
| device=device, |
| dtype=dtype, |
| ) |
|
|
| expected = torch.tensor( |
| [ |
| [1.0, 2.0, 1.0, 1.0], |
| [0.0, 1.0, 2.0, 1.0], |
| [2.0, 1.0, 0.0, 1.0], |
| [-1.0, -2.0, -1.0, 1.0], |
| [0.0, 1.0, -2.0, 1.0], |
| ], |
| device=device, |
| dtype=dtype, |
| ) |
|
|
| |
| points = kornia.geometry.conversions.convert_points_to_homogeneous(points_h) |
| assert_close(points, expected, atol=1e-4, rtol=1e-4) |
|
|
| def test_convert_points_batch(self, device, dtype): |
| |
| points_h = torch.tensor([[[2.0, 1.0, 0.0]], [[0.0, 1.0, 2.0]], [[0.0, 1.0, -2.0]]], device=device, dtype=dtype) |
|
|
| expected = torch.tensor( |
| [[[2.0, 1.0, 0.0, 1.0]], [[0.0, 1.0, 2.0, 1.0]], [[0.0, 1.0, -2.0, 1.0]]], device=device, dtype=dtype |
| ) |
|
|
| |
| points = kornia.geometry.conversions.convert_points_to_homogeneous(points_h) |
| assert_close(points, expected, atol=1e-4, rtol=1e-4) |
|
|
| @pytest.mark.parametrize("batch_shape", [(2, 3), (1, 2, 3), (2, 3, 3), (5, 5, 3)]) |
| def test_gradcheck(self, batch_shape, device, dtype): |
| points_h = torch.rand(batch_shape, device=device, dtype=dtype) |
|
|
| |
| points_h = tensor_to_gradcheck_var(points_h) |
| assert gradcheck(kornia.geometry.conversions.convert_points_to_homogeneous, (points_h,), raise_exception=True) |
|
|
| def test_jit(self, device, dtype): |
| op = kornia.geometry.conversions.convert_points_to_homogeneous |
| op_jit = torch.jit.script(op) |
| points_h = torch.zeros(1, 2, 3, device=device, dtype=dtype) |
| assert_close(op(points_h), op_jit(points_h)) |
|
|
|
|
| class TestConvertAtoH: |
| def test_convert_points(self, device, dtype): |
| |
| A = torch.tensor([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]], device=device, dtype=dtype).view(1, 2, 3) |
|
|
| expected = torch.tensor([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]], device=device, dtype=dtype).view( |
| 1, 3, 3 |
| ) |
|
|
| |
| H = kornia.geometry.conversions.convert_affinematrix_to_homography(A) |
| assert_close(H, expected) |
|
|
| @pytest.mark.parametrize("batch_shape", [(10, 2, 3), (16, 2, 3)]) |
| def test_gradcheck(self, batch_shape, device, dtype): |
| points_h = torch.rand(batch_shape, device=device, dtype=dtype) |
|
|
| |
| points_h = tensor_to_gradcheck_var(points_h) |
| assert gradcheck( |
| kornia.geometry.conversions.convert_affinematrix_to_homography, (points_h,), raise_exception=True |
| ) |
|
|
| def test_jit(self, device, dtype): |
| op = kornia.geometry.conversions.convert_affinematrix_to_homography |
| op_jit = torch.jit.script(op) |
| points_h = torch.zeros(1, 2, 3, device=device, dtype=dtype) |
| assert_close(op(points_h), op_jit(points_h)) |
|
|
|
|
| class TestConvertPointsFromHomogeneous: |
| @pytest.mark.parametrize("batch_shape", [(2, 3), (1, 2, 3), (2, 3, 3), (5, 5, 3)]) |
| def test_cardinality(self, device, dtype, batch_shape): |
| points_h = torch.rand(batch_shape, device=device, dtype=dtype) |
| points = kornia.geometry.conversions.convert_points_from_homogeneous(points_h) |
| assert points.shape == points.shape[:-1] + (2,) |
|
|
| def test_points(self, device, dtype): |
| |
| points_h = torch.tensor( |
| [[1.0, 2.0, 1.0], [0.0, 1.0, 2.0], [2.0, 1.0, 0.0], [-1.0, -2.0, -1.0], [0.0, 1.0, -2.0]], |
| device=device, |
| dtype=dtype, |
| ) |
|
|
| expected = torch.tensor( |
| [[1.0, 2.0], [0.0, 0.5], [2.0, 1.0], [1.0, 2.0], [0.0, -0.5]], device=device, dtype=dtype |
| ) |
|
|
| |
| points = kornia.geometry.conversions.convert_points_from_homogeneous(points_h) |
| assert_close(points, expected, atol=1e-4, rtol=1e-4) |
|
|
| def test_points_batch(self, device, dtype): |
| |
| points_h = torch.tensor([[[2.0, 1.0, 0.0]], [[0.0, 1.0, 2.0]], [[0.0, 1.0, -2.0]]], device=device, dtype=dtype) |
|
|
| expected = torch.tensor([[[2.0, 1.0]], [[0.0, 0.5]], [[0.0, -0.5]]], device=device, dtype=dtype) |
|
|
| |
| points = kornia.geometry.conversions.convert_points_from_homogeneous(points_h) |
| assert_close(points, expected, atol=1e-4, rtol=1e-4) |
|
|
| def test_gradcheck(self, device, dtype): |
| points_h = torch.ones(1, 10, 3, device=device, dtype=dtype) |
|
|
| |
| points_h = tensor_to_gradcheck_var(points_h) |
| assert gradcheck(kornia.geometry.conversions.convert_points_from_homogeneous, (points_h,), raise_exception=True) |
|
|
| @pytest.mark.skip("RuntimeError: Jacobian mismatch for output 0 with respect to input 0,") |
| def test_gradcheck_zvec_zeros(self, device, dtype): |
| |
| points_h = torch.tensor([[1.0, 2.0, 0.0], [0.0, 1.0, 0.1], [2.0, 1.0, 0.1]], device=device, dtype=dtype) |
|
|
| |
| points_h = tensor_to_gradcheck_var(points_h) |
| assert gradcheck(kornia.geometry.conversions.convert_points_from_homogeneous, (points_h,), raise_exception=True) |
|
|
| def test_jit(self, device, dtype): |
| op = kornia.geometry.conversions.convert_points_from_homogeneous |
| op_jit = torch.jit.script(op) |
| points_h = torch.zeros(1, 2, 3, device=device, dtype=dtype) |
| assert_close(op(points_h), op_jit(points_h)) |
|
|
|
|
| class TestNormalizePixelCoordinates: |
| def test_tensor_bhw2(self, device, dtype, atol, rtol): |
| eps = torch.finfo(dtype).eps |
| height, width = 3, 4 |
| grid = kornia.utils.create_meshgrid(height, width, normalized_coordinates=False, device=device).to(dtype=dtype) |
|
|
| expected = kornia.utils.create_meshgrid(height, width, normalized_coordinates=True, device=device).to( |
| dtype=dtype |
| ) |
|
|
| grid_norm = kornia.geometry.conversions.normalize_pixel_coordinates(grid, height, width, eps=eps) |
|
|
| assert_close(grid_norm, expected, atol=atol, rtol=rtol) |
|
|
| def test_list(self, device, dtype, atol, rtol): |
| eps = torch.finfo(dtype).eps |
| height, width = 3, 4 |
| grid = kornia.utils.create_meshgrid(height, width, normalized_coordinates=False, device=device).to(dtype=dtype) |
| grid = grid.contiguous().view(-1, 2) |
|
|
| expected = kornia.utils.create_meshgrid(height, width, normalized_coordinates=True, device=device).to( |
| dtype=dtype |
| ) |
| expected = expected.contiguous().view(-1, 2) |
|
|
| grid_norm = kornia.geometry.conversions.normalize_pixel_coordinates(grid, height, width, eps=eps) |
|
|
| assert_close(grid_norm, expected, atol=atol, rtol=rtol) |
|
|
| def test_jit(self, device, dtype): |
| op = kornia.geometry.conversions.normalize_pixel_coordinates |
| op_script = torch.jit.script(op) |
|
|
| height, width = 3, 4 |
| grid = kornia.utils.create_meshgrid(height, width, normalized_coordinates=True, device=device).to(dtype=dtype) |
|
|
| actual = op_script(grid, height, width) |
| expected = op(grid, height, width) |
| assert_close(actual, expected) |
|
|
|
|
| class TestDenormalizePixelCoordinates: |
| def test_tensor_bhw2(self, device, dtype): |
| height, width = 3, 4 |
| grid = kornia.utils.create_meshgrid(height, width, normalized_coordinates=True, device=device).to(dtype=dtype) |
|
|
| expected = kornia.utils.create_meshgrid(height, width, normalized_coordinates=False, device=device).to( |
| dtype=dtype |
| ) |
|
|
| grid_norm = kornia.geometry.conversions.denormalize_pixel_coordinates(grid, height, width) |
|
|
| assert_close(grid_norm, expected, atol=1e-4, rtol=1e-4) |
|
|
| def test_list(self, device, dtype): |
| height, width = 3, 4 |
| grid = kornia.utils.create_meshgrid(height, width, normalized_coordinates=True, device=device).to(dtype=dtype) |
| grid = grid.contiguous().view(-1, 2) |
|
|
| expected = kornia.utils.create_meshgrid(height, width, normalized_coordinates=False, device=device).to( |
| dtype=dtype |
| ) |
| expected = expected.contiguous().view(-1, 2) |
|
|
| grid_norm = kornia.geometry.conversions.denormalize_pixel_coordinates(grid, height, width) |
|
|
| assert_close(grid_norm, expected, atol=1e-4, rtol=1e-4) |
|
|
| def test_jit(self, device, dtype): |
| op = kornia.geometry.conversions.denormalize_pixel_coordinates |
| op_script = torch.jit.script(op) |
|
|
| height, width = 3, 4 |
| grid = kornia.utils.create_meshgrid(height, width, normalized_coordinates=True, device=device).to(dtype=dtype) |
|
|
| actual = op_script(grid, height, width) |
| expected = op(grid, height, width) |
|
|
| assert_close(actual, expected) |
|
|