Exemplo n.º 1
0
def test_vf_identity_eulerian_ok_2d():
    expected_vf = np.zeros((10, 9, 1, 1, 2))
    for x in range(10):
        for y in range(9):
            expected_vf[x, y, 0, 0, :] = [x, y]

    assert_array_equal(gen_id.id_eulerian((10, 9)), expected_vf)
Exemplo n.º 2
0
def test_vf_identity_eulerian_ok_3d():
    expected_vf = np.zeros((10, 9, 8, 1, 3))
    for x in range(10):
        for y in range(9):
            for z in range(8):
                expected_vf[x, y, z, 0, :] = [x, y, z]

    assert_array_equal(gen_id.id_eulerian((10, 9, 8)), expected_vf)
Exemplo n.º 3
0
def generate_from_matrix(omega, input_matrix, t=1, structure='algebra'):
    """
    :param omega: domain of the vector field.
    :param input_matrix: matrix generating the transformation of the vector field representing elements form groups
    SE(3), SE(2) or algebras so(3) and so(2).
    :param t: timepoints.
    :param structure: can be 'algebra' or 'group'.
    :return: vector field with the given input parameters.
    """
    if t > 1:  # TODO
        raise IndexError('Random generator not defined (yet) for multiple time points')

    d = qr.check_omega(omega)
    v_shape = qr.shape_from_omega_and_timepoints(omega, t)
    vf = np.zeros(v_shape)

    if structure == 'algebra':
        pass
    elif structure == 'group':
        input_matrix = input_matrix - np.eye(input_matrix.shape[0])
    else:
        raise IOError

    if d == 2:

        if not np.alltrue(input_matrix.shape == (3, 3)):
            raise IOError('Omega dimension not compatible with the matrix dimension')

        vf = cs.affine_to_homogeneous(gen_id.id_eulerian(omega))

        x_intervals, y_intervals = omega
        for i in range(x_intervals):
            for j in range(y_intervals):
                vf[i, j, 0, 0, :] = input_matrix.dot(vf[i, j, 0, 0, :])

        vf = cs.homogeneous_to_affine(vf)

    elif d == 3:
        # If the matrix provides a 2d rototranslation, we consider the rotation axis perpendicular to the plane z=0.
        # this must be improved for 3d rotations in the space.
        x_intervals, y_intervals, z_intervals = omega

        if np.alltrue(input_matrix.shape == (3, 3)):

            # Create the slice at the ground of the domain (x,y,z) , z = 0, as a 2d rotation:
            base_slice = cs.affine_to_homogeneous(gen_id.id_eulerian(list(omega[:2])))

            for i in range(x_intervals):
                for j in range(y_intervals):
                    base_slice[i, j, 0, 0, :] = input_matrix.dot(base_slice[i, j, 0, 0, :])

            # Copy the slice at the ground on all the others:
            for k in range(z_intervals):
                vf[..., k, 0, :2] = base_slice[..., 0, 0, :2]

        # If the matrix is 3d the rotation axis is perpendicular to the plane z=0.
        elif np.alltrue(input_matrix.shape == (4, 4)):

            vf = cs.affine_to_homogeneous(gen_id.id_eulerian(omega))

            for i in range(x_intervals):
                for j in range(y_intervals):
                    for k in range(z_intervals):
                        vf[i, j, k, 0, :] = input_matrix.dot(vf[i, j, k, 0, :])

            vf = cs.homogeneous_to_affine(vf)
        else:
            raise IOError('Wrong input matrix shape. Must be 3x3 or 4x4.')

    return vf
Exemplo n.º 4
0
def test_vf_identity_eulerian_wrong_input():
    with assert_raises(IOError):
        gen_id.id_eulerian((3, 3, 3, 3, 3))
Exemplo n.º 5
0
def generate_from_projective_matrix(omega, input_h, t=1, structure='algebra'):
    """

    :param omega: domain of the vector field.
    :param input_h: matrix representing an element form the homography group.
    :param t: number of timepoints.
    :param structure: can be 'algebra' or 'group'.
    :return: vector field with the given input parameters.
    """

    if t > 1:  # TODO
        raise IndexError('Random generator not defined (yet) for multiple time points')

    d = qr.check_omega(omega)

    if structure == 'algebra':

        if d == 2:

            idd = gen_id.id_eulerian(omega)
            vf = gen_id.id_lagrangian(omega)

            idd = coord.affine_to_homogeneous(idd)

            x_intervals, y_intervals = omega
            for i in range(x_intervals):
                for j in range(y_intervals):
                    vf[i, j, 0, 0, 0] = input_h[0, :].dot(idd[i, j, 0, 0, :]) - i * input_h[2, :].dot(idd[i, j, 0, 0, :])
                    vf[i, j, 0, 0, 1] = input_h[1, :].dot(idd[i, j, 0, 0, :]) - j * input_h[2, :].dot(idd[i, j, 0, 0, :])

            return vf

        elif d == 3:

            idd = gen_id.id_eulerian(omega)
            vf = gen_id.id_lagrangian(omega)

            idd = coord.affine_to_homogeneous(idd)

            x_intervals, y_intervals, z_intervals = omega
            for i in range(x_intervals):
                for j in range(y_intervals):
                    for k in range(z_intervals):
                        vf[i, j, k, 0, 0] = input_h[0, :].dot(idd[i, j, k, 0, :]) - i * input_h[3, :].dot(idd[i, j, k, 0, :])
                        vf[i, j, k, 0, 1] = input_h[1, :].dot(idd[i, j, k, 0, :]) - j * input_h[3, :].dot(idd[i, j, k, 0, :])
                        vf[i, j, k, 0, 2] = input_h[2, :].dot(idd[i, j, k, 0, :]) - k * input_h[3, :].dot(idd[i, j, k, 0, :])

            return vf

    elif structure == 'group':

        if d == 2:

            vf = gen_id.id_lagrangian(omega)

            x_intervals, y_intervals = omega
            for i in range(x_intervals):
                for j in range(y_intervals):

                    s = input_h.dot(np.array([i, j, 1]))[:]
                    if abs(s[2]) > 1e-5:
                        # subtract the id to have the result in displacement coordinates
                        vf[i, j, 0, 0, :] = (s[0:2] / float(s[2])) - np.array([i, j])

            return vf

        elif d == 3:

            vf = gen_id.id_lagrangian(omega)

            x_intervals, y_intervals, z_intervals = omega
            for i in range(x_intervals):
                for j in range(y_intervals):
                    for k in range(z_intervals):

                        s = input_h.dot(np.array([i, j, k, 1]))[:]
                        if abs(s[3]) > 1e-5:
                            vf[i, j, k, 0, :] = (s[0:3] / float(s[3])) - np.array([i, j, k])

            return vf

    else:
        raise IOError("structure can be only 'algebra' or 'group' corresponding to the algebraic structure.")