Slicer transformation result is different from my vtk codes

Recently I used the Transform module in Slicer to apply a linear transformation. Let’s say the translation is [10, 20, 30]. And the model moved to the correct position.

However, when I used my own vtk codes below, the result is not correct.

vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New();
transform->Translate(10, 20, 30);
vtkSmartPointer<vtkTransformPolyDataFilter> transformFilter = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
transformFilter->SetInputData(mesh);
transformFilter->SetTransform(transform);
transformFilter->Update();

First I was thinking it is because of the coordinate system difference (RAS and LPS), so I flipped the two axes:

translationMatrix->SetElement(0, 0, -1.0); 
translationMatrix->SetElement(1, 1, -1.0);

However, it is still not correct. Did I miss some steps used in Slicer? Thanks for any suggestions!

You would actually need to change the values of the translations, not just the main diagonal. But in general you should be applying a matrix to do the transform, something like this:

Hi pieper, thanks for the reply!
Can I ask what do you mean by “not just the diagonal”?

I have tried to apply the two matrix below but the error still exists:

| 1 | 0 | 0 | 10 |
| 0 | 1 | 0 | 20 |
| 0 | 0 | 1 | 30 |
| 0 | 0 | 0 | 1 |

and

| -1 | 0 | 0 | 10 |
| 0 | -1 | 0 | 20 |
| 0 | 0 | 1 | 30 |
| 0 | 0 | 0 | 1 |

This operation from your post only changes the two elements on the diagonal:

What you need to do is multiply your translation matrix by a matrix that is identity but with -1 in the 0,0 and 1,1 locations. The effect in this case will be to negate the first two translation values.

1 Like

Hi pieper, I have multiplied the two matrix:

the first is [1, 0, 0, 10; 0, 1, 0, 20; 0, 0, 1, 30; 0, 0, 0, 1]
the second is [-1, 0, 0, 0; 0, -1, 0, 0; 0, 0, 1, 0; 0, 0, 0, 1]
the result is [-1, 0, 0, 10; 0, -1, 0, 20; 0, 0, 1, 30; 0, 0, 0, 1]

But the error still exists.

I was thinking if it is because my mesh model is not in the center of the bounding box. So I output the center coordinates of the mesh before and after the transformation. It’s weird that the coordinates after transformation are not (-10, -20, 30).

My codes below:

vtkSmartPointer<vtkMatrix4x4> translationMatrix = vtkSmartPointer<vtkMatrix4x4>::New();
translationMatrix->SetElement(0, 3, 10); 
translationMatrix->SetElement(1, 3, 20); 
translationMatrix->SetElement(2, 3, 30); 
translationMatrix->SetElement(0, 0, -1.0); 
translationMatrix->SetElement(1, 1, -1.0); 
transform->SetMatrix(translationMatrix);
vtkSmartPointer<vtkTransformPolyDataFilter> transformFilter = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
transformFilter->SetInputData(mesh);

transformFilter->GetOutput()->GetCenter(center); // the center is (0, 0, 0)

transformFilter->SetTransform(transform);
transformFilter->Update();

transformFilter->GetOutput()->GetCenter(center2); // the center is not (-10, -20, 30)

There’s more information here: Coordinate systems - Slicer Wiki

You can also search google for LPS and RAS to get more examples.

1 Like

You may also find this script useful that shows how to convert ITK transform file to Slicer transform.

1 Like

Indeed, even in python image direction/coordinates are different. I tried this code and worked. you may have a look and find out how to convert coordinates in c++:
image=sitk.ReadImage(image)
dirs = np.zeros([3,3])
image.GetIJKToRASDirections(dirs)
dirs=np.multiply(dirs,np.array([[-1,-1,-1],[-1,-1,-1],[1,1,1]]))
new_dirctions=np.reshape(dirs,(1,9)).tolist()
new_origin=label.GetOrigin()

1 Like

This worked! Thank you!