nipy / nipy/nitransforms

ITK Euler3D rotation matrix not supported

Open
#295 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
35
Forks
18
Avg merge
21h 48m
Merged PRs (30d)
1

Description

I've generated a rigid transform using ANTs AI. When I try to load the .mat file using nitransforms, it throws an "unsupported transform" error during the Matlab dict load function linked below. https://github.com/nipy/nitransforms/blob/9486757ea21f78e960220f2bb9ba2eaed960c176/nitransforms/io/itk.py#L141

Doing a bit of digging, my transform has 6 parameters vs the usual 12. When I load it using scipy.io.loadmat, the dict has two keys, "Euler3DTransform_double_3_3" and "fixed". A typical ANTs affine has "AffineTransform_double_3_3" and "fixed". I've given the details of each transform below.

According to chatgpt the Euler3D params are expressed as [rotx, roty, rotz, tx, ty, tz]. Its proposed the following code to convert the Euler3D into a full Affine transformation and it seems to work on my simple test cases.

I'd be happy to incorporate this into the existing from_matlab_dict function but am not expert enough in this area to fully test it or consider where it may break. Does anyone have any comment to make? Is there a reason why Euler3D isn't supported; does this solution look sensible?

Euler3D rigid transform:

{'Euler3DTransform_double_3_3': array([[ 1.34468616e-04],
        [ 1.03066786e-02],
        [ 5.49512615e-03],
        [-1.88564745e+00],
        [-1.93042799e+00],
        [ 4.81095387e+00]]),
 'fixed': array([[-3.4070487 ],
        [33.00756454],
        [-3.60144258],
        [ 0.        ]])}

Affine transform:

{'AffineTransform_double_3_3': array([[ 1.03404642],
        [-0.04273591],
        [ 0.01717928],
        [ 0.03782461],
        [ 0.99473991],
        [-0.01715351],
        [-0.00832061],
        [ 0.00896228],
        [ 0.92373895],
        [-3.23504401],
        [-1.28125352],
        [ 4.6121046 ]]),
 'fixed': array([[-3.4070487 ],
        [33.00756454],
        [-3.60144258]])}

Code to convert Euler3D into standard affine matrix

    # 1. Parse Euler angles and translation
    # input params: [angX, angY, angZ, tx, ty, tz]
    orig_params = data["Euler3DTransform_double_3_3"].flatten()
    angles = orig_params[:3]
    translation = orig_params[3:]

    # 2. Parse Fixed Parameters (Center of Rotation)
    # Euler3D has 4 fixed params; generic Affine has 3.
    orig_fixed = data["fixed"].flatten()
    center = orig_fixed[:3]

    # 3. Compute 3x3 Rotation Matrix
    # ITK Euler3D uses 'xyz' sequence
    rot_matrix = R.from_euler("xyz", angles).as_matrix()

    # 4. Flatten the matrix and append translation
    # Flattening must be row-major (m11, m12, m13...)
    new_params = np.concatenate([rot_matrix.flatten(), translation])

    # 5. Prepare data for .mat file
    # We use 'double' precision as ANTs expects this
    new_data = {
        "AffineTransform_double_3_3": new_params.reshape(-1, 1).astype(np.float64),
        "fixed": center.reshape(-1, 1).astype(np.float64),
    }

    # 6. Save
    savemat(output_mat, new_data)
    print(f"Successfully converted to generic affine: {output_mat}")

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in nitransforms/io/itk.py at the linked from_matlab_dict implementation and compare its existing AffineTransform handling with the Euler3DTransform data shown in the issue. Verify the rotation, translation, and fixed-parameter semantics against representative MATLAB transform dictionaries. Done means valid Euler3D .mat files load without the unsupported-transform error and existing affine loading remains unaffected.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.