| | |
| | |
| |
|
| | |
| |
|
| | import os |
| |
|
| | import numpy as np |
| | import unittest |
| |
|
| | from . import test_data_folder |
| | from unittest.case import skipUnless |
| |
|
| | try: |
| | import cv2 |
| | has_cv2 = True |
| | except ImportError: |
| | has_cv2 = False |
| |
|
| |
|
| | class TestGeometry(unittest.TestCase): |
| |
|
| | @skipUnless(has_cv2, 'skipping tests requiring OpenCV') |
| | def test_rodrigues(self): |
| | from psbody.mesh.geometry.rodrigues import rodrigues |
| |
|
| | test_data = ( |
| | np.array([0, 0, 0], dtype=np.double), |
| | np.array([1, -1, 0.5], dtype=np.double), |
| | np.array([[1, -1, 0.5]], dtype=np.double), |
| | np.array([[1, -1, 0.5]], dtype=np.double).T, |
| | np.eye(3, dtype=np.double), |
| | np.array([[1, 0, 0], [0, -1, 0], [0, 0, -1]], dtype=np.double), |
| | np.array([[0.22629564, 0.95671228, -0.18300792], |
| | [-0.18300792, 0.22629564, 0.95671228], |
| | [0.95671228, -0.18300792, 0.22629564]], dtype=np.double), |
| | ) |
| | for r_in in test_data: |
| | true_r, true_dr = cv2.Rodrigues(r_in) |
| | our_r, our_dr = rodrigues(r_in) |
| | np.testing.assert_array_almost_equal(our_r, true_r, verbose=True) |
| | np.testing.assert_array_almost_equal(our_dr, true_dr, verbose=True) |
| |
|
| | def test_cross_product(self): |
| | from psbody.mesh.geometry.cross_product import CrossProduct |
| |
|
| | npts = 6 |
| | a = np.random.randn(3 * npts) |
| | b = np.random.randn(3 * npts) |
| |
|
| | c = CrossProduct(a, b) |
| |
|
| | |
| | our_answer = c.flatten() |
| | numpy_answer = np.cross(a.reshape(-1, 3), b.reshape(-1, 3)).flatten() |
| |
|
| | self.assertTrue(max(abs(our_answer - numpy_answer)) < 1e-15) |
| |
|
| | def test_vert_normals(self): |
| | from psbody.mesh.geometry.vert_normals import VertNormals |
| | from psbody.mesh.mesh import Mesh |
| | mesh = Mesh(filename=os.path.join(test_data_folder, 'sphere.ply')) |
| | pred = VertNormals(mesh.v, mesh.f) |
| |
|
| | vn_obs = mesh.estimate_vertex_normals().reshape((-1, 3)) |
| | vn_pred = pred.reshape((-1, 3)) |
| |
|
| | self.assertTrue(np.max(np.abs(vn_pred.flatten() - vn_obs.flatten())) < 1e-15) |
| |
|
| | def test_barycentric_coordinates_of_projection(self): |
| | """Tests backwards compatibility with old matlab |
| | function of the same name.""" |
| | from psbody.mesh.geometry.barycentric_coordinates_of_projection import barycentric_coordinates_of_projection |
| |
|
| | p = np.array([[-120, 48, -30, 88, -80], |
| | [71, 102, 29, -114, -291], |
| | [161, 72, -78, -106, 142]]).T |
| |
|
| | q = np.array([[32, -169, 32, -3, 108], |
| | [-75, -10, 31, -16, 110], |
| | [136, -24, -86, 62, -86]]).T |
| |
|
| | u = np.array([[8, -1, 37, -108, 109], |
| | [-120, 152, -22, 3, 153], |
| | [-110, -76, 111, 55, 9]]).T |
| |
|
| | v = np.array([[-148, 233, -19, -139, -18], |
| | [-73, -61, 88, -141, -19], |
| | [-105, 74, -76, 48, 141]]).T |
| |
|
| | b = np.array([[1.5266, -0.8601, 1.3245, 2.4450, 1.3452], |
| | [-1.5346, 0.8556, -0.1963, -2.1865, -2.0794], |
| | [1.0080, 1.0046, -0.1282, 0.7415, 1.7342]]).T |
| |
|
| | b_est = barycentric_coordinates_of_projection(p, q, u, v) |
| | self.assertTrue(np.max(np.abs(b_est.flatten('F') - b.flatten('F'))) < 1e-3) |
| |
|
| | p = p[0, :] |
| | q = q[0, :] |
| | u = u[0, :] |
| | v = v[0, :] |
| | b = b[0, :] |
| |
|
| | b_est = barycentric_coordinates_of_projection(p, q, u, v) |
| | self.assertTrue(np.max(np.abs(b_est.flatten('F') - b.flatten('F'))) < 1e-3) |
| |
|
| | @unittest.skipIf( |
| | not os.path.isfile(os.path.join(test_data_folder, 'female_template.ply')), |
| | 'No data file.') |
| | def test_trinormal(self): |
| |
|
| | from psbody.mesh.mesh import Mesh |
| | from psbody.mesh.geometry.tri_normals import TriNormals, TriToScaledNormal, TriNormalsScaled, NormalizeRows |
| |
|
| | m = Mesh(filename=os.path.join(test_data_folder, 'female_template.ply')) |
| |
|
| | |
| | tn = TriNormals(m.v, m.f) |
| | tn2 = NormalizeRows(TriToScaledNormal(m.v, m.f)) |
| |
|
| | eps = 1e-8 |
| | mvc = m.v.copy() |
| | mvc[0] += eps |
| | tn_b = TriNormals(mvc, m.f) |
| | tn2_b = NormalizeRows(TriToScaledNormal(mvc, m.f)) |
| | |
| | |
| |
|
| | |
| | |
| | |
| | np.testing.assert_almost_equal(tn_b.flatten() - tn.flatten(), |
| | tn2_b.flatten() - tn2.flatten()) |
| |
|
| | tn = TriNormalsScaled(m.v, m.f) |
| | tn2 = TriToScaledNormal(m.v, m.f) |
| | eps = 1e-8 |
| | mvc = m.v.copy() |
| | mvc[0] += eps |
| |
|
| | tn_b = TriNormalsScaled(mvc, m.f) |
| | tn2_b = TriToScaledNormal(mvc, m.f) |
| |
|
| | np.testing.assert_almost_equal(tn_b.flatten() - tn.flatten(), |
| | tn2_b.flatten() - tn2.flatten()) |
| |
|