[vtkusers] vtkImageReslice for tranforming images in a common space
Francesco Ponzio
fr.ponzio at gmail.com
Fri May 27 10:48:43 EDT 2016
Dear vtk users,
I need help with vtkImageReslice.
I'm performing image registration between US and MRI images (.nii) )with
itk. The first step is to roughly align the two images in the same
anatomical space in order to apply here the registration pipeline. In
particular I've a .mat file which is supposed to transform US into MR
space.
Here is my code
#include <vtkSmartPointer.h>
#include <vtkImageReslice.h>
#include <vtkMatrix4x4.h>
#include <vtkTransform.h>
#include <vtkNIFTIImageReader.h>
#include <vtkNIFTIImageWriter.h>
#include <stdio.h>
#include <vtkImageData.h>
using namespace std;
int main(int argc, char*argv[])
{
//Check input
if (argc<3)
{
std:cout<<"Usage:" << argv[0]
<<" img.nii transform.mat [reference.nii] [output.nii] "<<std::endl;
return EXIT_FAILURE;
}
std::string inputFilename = argv[1];
std::string matrix=argv[2];
static double mat[4][4];
ifstream dataInput(matrix.c_str());
int r=0;
while(r<4)
{
dataInput >> mat[r][0] >> mat[r][1] >> mat[r][2] >> mat[r][3];
r++;
}
dataInput.close();
//Matrix transform
static double t[16] = {
mat[0][0], mat[0][1], mat[0][2], mat[0][3],
mat[1][0], mat[1][1], mat[1][2], mat[1][3],
mat[2][0], mat[2][1], mat[2][2], mat[2][3],
mat[3][0], mat[3][1], mat[3][2], mat[3][3],};
vtkSmartPointer<vtkMatrix4x4> m = vtkSmartPointer<vtkMatrix4x4>::New();
m->DeepCopy(t);
cout << endl << "Applied 4x4 matrix:" << endl;
for (int i=0;i<4;i++){
cout << m->GetElement(i,0) << ' ' << m->GetElement(i,1) << ' ' <<
m->GetElement(i,2) << ' ' << m->GetElement(i,3) << endl;
}
//Reader
vtkSmartPointer<vtkNIFTIImageReader>
reader=vtkSmartPointer<vtkNIFTIImageReader>::New();
reader->SetFileName(inputFilename.c_str());
reader->Update();
//Reslicing
vtkSmartPointer<vtkImageReslice> reslice =
vtkSmartPointer<vtkImageReslice>::New();
reslice->SetInputConnection(reader->GetOutputPort());
if (argc > 3) {
vtkSmartPointer<vtkNIFTIImageReader>
reader1=vtkSmartPointer<vtkNIFTIImageReader>::New();
cout << "Applied reference image information" << endl;
reader1->SetFileName(argv[3]);
reader1->Update();
vtkSmartPointer<vtkImageData> imgReference =
vtkSmartPointer<vtkImageData>::New();
imgReference->ShallowCopy(reader1->GetOutput());
reslice->SetInformationInput(imgReference);
}
vtkSmartPointer<vtkTransform> transform =
vtkSmartPointer<vtkTransform>::New();
transform->SetMatrix(m);
transform->PreMultiply();
reslice->SetResliceTransform(transform);
reslice->AutoCropOutputOn();
reslice->SetInterpolationModeToNearestNeighbor();
reslice->Update();
//Save
vtkSmartPointer<vtkNIFTIImageWriter> out =
vtkSmartPointer<vtkNIFTIImageWriter>::New();
if (argc < 5) {
out->SetFileName("Resliced.nii");
}
else{
out->SetFileName(argv[4]);
}
out->SetInputConnection(reslice->GetOutputPort());
out->Write();
return EXIT_SUCCESS;
}
Here is the transformation matrix
-0.963857 -0.250682 0.090209 121.954769
-0.155085 0.803248 0.575101 47.195941
-0.216627 0.540326 -0.813093 102.646109
0 0 0 1
The results of the reslice step are not consistent: images don't look
aligned using paraview.
If I've well understood the problem, since I have two images obtained from
different devices, I need firstly to trasform each of them in the
corresponding scanner space (which is in mm) and the to transform the US
image, now rapresented in US scanner space, into the MRI scanner space.
My question is: can I apply directly this trasformation (with SetMatrix()
method) or do I need to keep in consideration some other aspects (such as
qform and sform)? And how to keep thme in consideration?
--
Francesco Ponzio
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/vtkusers/attachments/20160527/23d6dbe6/attachment.html>
More information about the vtkusers
mailing list