def on_cone_rotation(theta_image, normal_image, s):
    theta = theta_image.as_vector()
    nprime = normal_image.as_vector(keep_channels=True)

    # cross product and break in to row vectors
    C = np.cross(nprime, s)
    C = normalise_vector(C)
    
    u = C[:, 0]
    v = C[:, 1]
    w = C[:, 2]
    
    # expects |nprime| = |sec| = 1
    # represents intensity and can never be < 0
    d = np.squeeze(np.inner(nprime, s) / (row_norm(nprime) * row_norm(s)))
    d = np.nan_to_num(d)
    d[d < 0.0] = 0.0
    
    beta = np.arccos(d)
    # flip beta and theta so that it rotates along the correct axis
    alpha = beta - theta
    
    c = np.cos(alpha)
    cprime = 1.0 - c
    s = np.sin(alpha)
    
    # setup structures
    N = nprime.shape[0]
    phi = np.zeros([N, 3, 3])
    
    phi[:, 0, 0] = c + u ** 2 * cprime
    phi[:, 0, 1] = -w * s + u * v * cprime
    phi[:, 0, 2] = v * s + u * w * cprime
    
    phi[:, 1, 0] = w * s + u * v * cprime
    phi[:, 1, 1] = c + v ** 2 * cprime
    phi[:, 1, 2] = -u * s + v * w * cprime
    
    phi[:, 2, 0] = -v * s + u * w * cprime
    phi[:, 2, 1] = u * s + v * w * cprime
    phi[:, 2, 2] = c + w ** 2 * cprime
          
    n = np.einsum('kjl, klm -> kj', phi, nprime[..., None])

    # Normalize the result ??
    n = normalise_vector(n)
    return normal_image.from_vector(n)
Example #2
0
def on_cone_rotation(theta_image, normal_image, s):
    theta = theta_image.as_vector()
    nprime = normal_image.as_vector(keep_channels=True)

    # cross product and break in to row vectors
    C = np.cross(nprime, s)
    C = normalise_vector(C)
    
    u = C[:, 0]
    v = C[:, 1]
    w = C[:, 2]
    
    # expects |nprime| = |sec| = 1
    # represents intensity and can never be < 0
    d = np.squeeze(np.inner(nprime, s) / (row_norm(nprime) * row_norm(s)))
    d = np.nan_to_num(d)
    d[d < 0.0] = 0.0
    
    beta = np.arccos(d)
    # flip beta and theta so that it rotates along the correct axis
    alpha = beta - theta
    
    c = np.cos(alpha)
    cprime = 1.0 - c
    s = np.sin(alpha)
    
    # setup structures
    N = nprime.shape[0]
    phi = np.zeros([N, 3, 3])
    
    phi[:, 0, 0] = c + u ** 2 * cprime
    phi[:, 0, 1] = -w * s + u * v * cprime
    phi[:, 0, 2] = v * s + u * w * cprime
    
    phi[:, 1, 0] = w * s + u * v * cprime
    phi[:, 1, 1] = c + v ** 2 * cprime
    phi[:, 1, 2] = -u * s + v * w * cprime
    
    phi[:, 2, 0] = -v * s + u * w * cprime
    phi[:, 2, 1] = u * s + v * w * cprime
    phi[:, 2, 2] = c + w ** 2 * cprime
          
    n = np.einsum('kjl, klm -> kj', phi, nprime[..., None])

    # Normalize the result ??
    n = normalise_vector(n)
    return normal_image.from_vector(n)
Example #3
0
    def expmap(self, tangent_vectors):
        # If we've been passed a single vector to map, then add the extra axis
        # Number of sample first
        if len(tangent_vectors.shape) < 3:
            tangent_vectors = tangent_vectors[None, ...]

        # Expmap
        v1 = tangent_vectors[..., 0]
        v2 = tangent_vectors[..., 1]
        normv = row_norm(tangent_vectors)

        exp = np.concatenate([(v1 * np.sin(normv) / normv)[..., None],
                              (v2 * np.sin(normv) / normv)[..., None],
                              np.cos(normv)[..., None]], axis=2)
        near_zero_ind = normv < np.spacing(1)
        exp[near_zero_ind, :] = [0.0, 0.0, 1.0]

        # Rotate back to geodesic mean from north pole
        # Apply inverse rotation matrix due to data ordering
        ns = np.einsum('fvi, ijv -> fvj', exp, self.rotation_matrices)

        return ns
Example #4
0
    def expmap(self, tangent_vectors):
        # If we've been passed a single vector to map, then add the extra axis
        # Number of sample first
        if len(tangent_vectors.shape) < 3:
            tangent_vectors = tangent_vectors[None, ...]

        # Expmap
        v1 = tangent_vectors[..., 0]
        v2 = tangent_vectors[..., 1]
        normv = row_norm(tangent_vectors)

        exp = np.concatenate([(v1 * np.sin(normv) / normv)[..., None],
                              (v2 * np.sin(normv) / normv)[..., None],
                              np.cos(normv)[..., None]],
                             axis=2)
        near_zero_ind = normv < np.spacing(1)
        exp[near_zero_ind, :] = [0.0, 0.0, 1.0]

        # Rotate back to geodesic mean from north pole
        # Apply inverse rotation matrix due to data ordering
        ns = np.einsum('fvi, ijv -> fvj', exp, self.rotation_matrices)

        return ns