예제 #1
0
def calc_euler(evecs):
    """
    Calculate the Euler angles that rotate from the canonical coordinate frame
    to a coordinate frame defined by a set of eigenvectors.

    Parameters
    ----------
    evecs : 3-by-3 array

    """
    rot0 = np.eye(4)
    # What is the rotation from the first eigenvector to eye(3)?
    rot0[:3, :3] = vec2vec_rotmat(evecs[0], np.eye(3)[0])
    # Decompose (we only need the angles)
    scale, shear, angles0, translate, perspective = decompose_matrix(rot0)
    # Convert angles to Euler matrix:
    em = euler_matrix(*angles0)
    # Now, we need another rotation to bring the second eigenvector to the right
    # direction
    ang1 = np.arccos(
        np.dot(evecs[1], em[1, :3]) /
        (np.linalg.norm(evecs[1]) * np.linalg.norm(em[1, :3])))
    rar = np.eye(4)
    # The rar is a matrix that rotates for a given angle around a given
    # vector:
    rar[:3, :3] = rodrigues_axis_rotation(evecs[0], np.rad2deg(ang1))
    # We combine these two rotations and decompose the combined matrix to give
    # us three Euler angles, which will be our parameters
    scale, shear, angles, translate, perspective = decompose_matrix(em @ rar)
    return angles
예제 #2
0
def decompose_matrix44(mat, size=12):
    """ Given a 4x4 homogeneous matrix return the parameter vector

    Parameters
    -----------
    mat : array
        Homogeneous 4x4 transformation matrix
    size : int
        Size of output vector. 6 for rigid, 7 for similarity and 12
        for affine. Default is 12.

    Returns
    -------
    t : ndarray
        One dimensional ndarray of 6, 7 or 12 affine parameters.

    """
    scale, shear, angles, translate, _ = decompose_matrix(mat)

    t = np.zeros(12)
    t[:3] = translate
    t[3: 6] = np.rad2deg(angles)
    if size == 6:
        return t[:6]
    if size == 7:
        t[6] = np.mean(scale)
        return t[:7]
    if size == 12:
        t[6: 9] = scale
        t[9: 12] = shear
        return t

    raise ValueError('Size can be 6, 7 or 12')
예제 #3
0
def decompose_matrix44(mat, size=12):
    """ Given a 4x4 homogeneous matrix return the parameter vector

    Parameters
    -----------
    mat : array
        Homogeneous 4x4 transformation matrix
    size : int
        Size of output vector. 6 for rigid, 7 for similarity and 12
        for affine. Default is 12.

    Returns
    -------
    t : ndarray
        One dimensional ndarray of 6, 7 or 12 affine parameters.

    """
    scale, shear, angles, translate, _ = decompose_matrix(mat)

    t = np.zeros(12)
    t[:3] = translate
    t[3:6] = np.rad2deg(angles)
    if size == 6:
        return t[:6]
    if size == 7:
        t[6] = np.mean(scale)
        return t[:7]
    if size == 12:
        t[6:9] = scale
        t[9:12] = shear
        return t

    raise ValueError('Size can be 6, 7 or 12')
예제 #4
0
def itk_affine_to_rigid(transform_file, cwd):
    """uses c3d_affine_tool and FSL's aff2rigid to convert an itk linear
    transform from affine to rigid"""

    rigid_mat_file = cwd + "/6DOFrigid.mat"
    translation_mat_file = cwd + '/translation.mat'
    inverse_mat_file = cwd + '/6DOFinverse.mat'
    raw_transform = sitk.ReadTransform(transform_file)
    aff_transform = sitk.AffineTransform(3)
    aff_transform.SetFixedParameters(raw_transform.GetFixedParameters())
    aff_transform.SetParameters(raw_transform.GetParameters())

    full_matrix = np.eye(4)
    full_matrix[:3, :3] = np.array(aff_transform.GetMatrix()).reshape(
        (3, 3), order="C")
    _, _, angles, _, _ = geom.decompose_matrix(full_matrix)
    rot_mat = geom.euler_matrix(angles[0], angles[1], angles[2])

    rigid = sitk.Euler3DTransform()
    rigid.SetCenter(aff_transform.GetCenter())
    rigid.SetTranslation(aff_transform.GetTranslation())
    # Write a translation-only transform
    sitk.WriteTransform(rigid, translation_mat_file)
    # Write the full rigid (translation + rotation) transform
    rigid.SetMatrix(tuple(rot_mat[:3, :3].flatten(order="C")))
    sitk.WriteTransform(rigid, rigid_mat_file)
    # Write the inverse rigid transform
    sitk.WriteTransform(rigid.GetInverse(), inverse_mat_file)

    if False in (op.exists(rigid_mat_file), op.exists(translation_mat_file),
                 op.exists(inverse_mat_file)):
        raise Exception("unable to create rigid AC-PC transform")
    return rigid_mat_file, inverse_mat_file, translation_mat_file
예제 #5
0
def load_dwi_files_blinds(folder_name):
    from dipy.core.gradients import gradient_table
    from dipy.core.geometry import compose_matrix, decompose_matrix

    for file in os.listdir(folder_name):
        if file.endswith(".bvec"):
            bvec_file = os.path.join(folder_name, file)
        if file.endswith("labels.nii"):
            labels_file_name = os.path.join(folder_name, file)
        if file.endswith("WM.nii"):
            wm_file_name = os.path.join(folder_name, file)
    bval_file = bvec_file[:-4:]+'bval'
    nii_file = bvec_file[:-4:]+'nii'
    hardi_img = nib.load(nii_file)
    data = hardi_img.get_fdata()
    affine = hardi_img.affine
    scale, shear, ang, trans, pre = decompose_matrix(affine)
    shear = np.zeros(np.shape(shear))
    affine = compose_matrix(scale, shear, ang, trans, pre)
    gtab = gradient_table(bval_file, bvec_file)
    #voxel_size = nib.affines.voxel_sizes(affine)
    #data, affine1 = reslice(data, affine, voxel_size, (3., 3., 3.))

    labels_img = nib.load(labels_file_name)
    labels = labels_img.get_fdata()
    #labels,affine1=reslice(labels,affine,voxel_size,(3., 3., 3.))

    wm_img = nib.load(wm_file_name)
    white_matter = wm_img.get_fdata()
    #white_matter,affine1=reslice(white_matter,affine,voxel_size,(3., 3., 3.))

    return gtab,data,affine,labels,white_matter,nii_file,bvec_file
예제 #6
0
    def _run_interface(self, runtime):
        collected_motion = []
        output_fname = os.path.join(runtime.cwd, "motion_params.csv")
        output_spm_fname = os.path.join(runtime.cwd, "spm_movpar.txt")
        for motion_file in self.inputs.transform_files:
            if os.path.exists("output.txt"):
                os.remove("output.txt")
            # Convert to homogenous matrix
            os.system("ConvertTransformFile 3 %s output.txt --RAS --hm" %
                      (motion_file))
            affine = np.loadtxt("output.txt")
            scale, shear, angles, translate, persp = decompose_matrix(affine)
            collected_motion.append(
                np.concatenate([scale, shear,
                                np.array(angles), translate]))

        final_motion = np.row_stack(collected_motion)
        cols = [
            "scaleX", "scaleY", "scaleZ", "shearXY", "shearXZ", "shearYZ",
            "rotateX", "rotateY", "rotateZ", "shiftX", "shiftY", "shiftZ"
        ]
        motion_df = pd.DataFrame(data=final_motion, columns=cols)
        motion_df.to_csv(output_fname, index=False)
        self._results['motion_file'] = output_fname

        spmcols = motion_df[[
            'shiftX', 'shiftY', 'shiftZ', 'rotateX', 'rotateY', 'rotateZ'
        ]]
        self._results['spm_motion_file'] = output_spm_fname
        np.savetxt(output_spm_fname, spmcols.values)

        return runtime
예제 #7
0
def test_compose_decompose_matrix():

    for translate in permutations(40 * np.random.rand(3), 3):
        for angles in permutations(np.deg2rad(90 * np.random.rand(3)), 3):
            for shears in permutations(3 * np.random.rand(3), 3):
                for scale in permutations(3 * np.random.rand(3), 3):

                    mat = compose_matrix(translate=translate, angles=angles,
                                         shear=shears, scale=scale)
                    sc, sh, ang, trans, _ = decompose_matrix(mat)

                    assert_array_almost_equal(translate, trans)
                    assert_array_almost_equal(angles, ang)

                    assert_array_almost_equal(shears, sh)
                    assert_array_almost_equal(scale, sc)