]> Creatis software - clitk.git/blob - vv/vvImageReader.cxx
Resample tool now use new resampleImage class (use the right number of thread)
[clitk.git] / vv / vvImageReader.cxx
1 /*=========================================================================
2   Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
3
4   Authors belong to:
5   - University of LYON              http://www.universite-lyon.fr/
6   - Léon Bérard cancer center       http://oncora1.lyon.fnclcc.fr
7   - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
8
9   This software is distributed WITHOUT ANY WARRANTY; without even
10   the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11   PURPOSE.  See the copyright notices for more information.
12
13   It is distributed under dual licence
14
15   - BSD        See included LICENSE.txt file
16   - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
17   ======================================================================-====*/
18 #ifndef VVIMAGEREADER_CXX
19 #define VVIMAGEREADER_CXX
20
21 #include <QApplication>
22 #include <itkImageFileReader.h>
23 #include "vvImageReader.h"
24 #include "vvImageReader.txx"
25 #include "clitkTransformUtilities.h"
26
27 //------------------------------------------------------------------------------
28 vvImageReader::vvImageReader()
29 {
30   mImage = NULL;
31   mInputFilenames.resize(0);
32   mLastError = "";
33   mType = UNDEFINEDIMAGETYPE;
34   mSlice = 0;
35 }
36 //------------------------------------------------------------------------------
37
38
39 //------------------------------------------------------------------------------
40 vvImageReader::~vvImageReader() { }
41 //------------------------------------------------------------------------------
42
43
44 //------------------------------------------------------------------------------
45 void vvImageReader::Update()
46 {
47   Update(mType);
48 }
49 //------------------------------------------------------------------------------
50
51
52 //------------------------------------------------------------------------------
53 void vvImageReader::Update(LoadedImageType type)
54 {
55   itk::ImageIOBase::Pointer reader = itk::ImageIOFactory::CreateImageIO(mInputFilenames[0].c_str(), itk::ImageIOFactory::ReadMode);
56   if (!reader) {
57     mLastError="Unable to read file.";
58   } else {
59     reader->SetFileName(mInputFilenames[0]);
60     reader->ReadImageInformation();
61     if (mInputFilenames.size() > 1)
62       Update(reader->GetNumberOfDimensions()+1,reader->GetComponentTypeAsString(reader->GetComponentType()),type);
63     else
64       Update(reader->GetNumberOfDimensions(),reader->GetComponentTypeAsString(reader->GetComponentType()),type);
65   }
66 }
67 //------------------------------------------------------------------------------
68
69
70 //------------------------------------------------------------------------------
71 void vvImageReader::Update(int dim,std::string inputPixelType, LoadedImageType type)
72 {
73   //CALL_FOR_ALL_DIMS(dim,UpdateWithDim,inputPixelType);
74   mType = type;
75   mDim = dim;
76   mInputPixelType=inputPixelType;
77   this->start(); //Start heavy read operation in a separate thread
78   while (this->isRunning()) {
79     qApp->processEvents();
80     this->wait(50);
81   }
82 }
83 //------------------------------------------------------------------------------
84
85
86 //------------------------------------------------------------------------------
87 void vvImageReader::run()
88 {
89   switch(mDim)     {
90   case 2:
91     UpdateWithDim<2>(mInputPixelType);
92     break;;
93   case 3:
94     UpdateWithDim<3>(mInputPixelType);
95     break;;
96   case 4:
97     UpdateWithDim<4>(mInputPixelType);
98     break;;
99   default:
100     std::cerr << "dimension unknown in Update ! " << std::endl;
101   }
102 }
103 //------------------------------------------------------------------------------
104
105
106 //------------------------------------------------------------------------------
107 void vvImageReader::SetInputFilename(const std::string & filename)
108 {
109   mInputFilenames.resize(0);
110   mInputFilenames.push_back(filename);
111 }
112 //------------------------------------------------------------------------------
113
114
115 //------------------------------------------------------------------------------
116 void vvImageReader::SetInputFilenames(const std::vector<std::string> & filenames)
117 {
118   mInputFilenames = filenames;
119 }
120 //------------------------------------------------------------------------------
121
122
123 //------------------------------------------------------------------------------
124 //Read transformation in NKI format (Xdr, transposed, cm)
125 void vvImageReader::ReadNkiImageTransform()
126 {
127   bool bRead=false;
128   std::string filename = mInputFilenames[0]+".MACHINEORIENTATION";
129   if(itksys::SystemTools::FileExists(filename.c_str())){
130     typedef itk::ImageFileReader< itk::Image< double, 2 > > MatrixReaderType;
131     MatrixReaderType::Pointer readerTransfo = MatrixReaderType::New();
132     readerTransfo->SetFileName(filename);
133     try {
134       bRead = true;
135       readerTransfo->Update();
136     } catch( itk::ExceptionObject & err ) {
137       bRead=false;
138       std::cerr << "Cannot read " << filename << std::endl
139                 << "The error is: " << err << std::endl;
140     }
141
142     if (bRead) {
143       //Transpose matrix (NKI format)
144       for(int j=0; j<4; j++)
145         for(int i=0; i<4; i++)
146           mImage->GetTransform()->GetMatrix()->SetElement(j,i,readerTransfo->GetOutput()->GetBufferPointer()[4*i+j]);
147
148       //From cm to mm
149       for(int i=0; i<3; i++)
150         mImage->GetTransform()->GetMatrix()->SetElement(i,3,10*mImage->GetTransform()->GetMatrix()->GetElement(i,3));
151
152       mImage->GetTransform()->Inverse();
153     }
154   }
155 }
156 //------------------------------------------------------------------------------
157
158
159 //------------------------------------------------------------------------------
160 //Read transformation in ASCII format
161 void vvImageReader::ReadMatImageTransform()
162 {
163   std::string filename(mInputFilenames[0]+".mat");
164   std::ifstream f(filename.c_str());
165   if(f.is_open()) {
166     f.close();
167     
168     itk::Matrix<double, 4, 4> itkMat = clitk::ReadMatrix3D(filename);
169     
170     vtkSmartPointer<vtkMatrix4x4> matrix = vtkSmartPointer<vtkMatrix4x4>::New();
171     matrix->Identity();
172     for(int j=0; j<4; j++)
173       for(int i=0; i<4; i++)
174         matrix->SetElement(j,i,itkMat[j][i]);
175
176     // RP: 14/03/2011
177     //  For some reason, the transformation matrix given in the MHD
178     // file is inverted wrt the transformation given in the MAT file.
179     // We don't really know where the inversion takes place inside
180     // VTK or ITK. For what we could see in VV, the transformation
181     // given in the MHD file seems "more correct" than that given in 
182     // the MAT file. For this reason, we invert the matrix read from
183     // the MAT file before concatenating it to the current transformation.
184     // Still, it would be nice to find out what happens exactly between
185     // VTK and ITK...
186     //
187     vtkSmartPointer<vtkMatrix4x4> inv_matrix = vtkSmartPointer<vtkMatrix4x4>::New();
188     if (matrix->Determinant() == 0)
189     {
190       vtkGenericWarningMacro("Matrix in " << filename.c_str() << " cannot be inverted (determinant = 0)");
191     }
192     else
193       matrix->Invert(*matrix, *inv_matrix);
194     
195     mImage->GetTransform()->PostMultiply();
196     mImage->GetTransform()->Concatenate(inv_matrix);
197     mImage->GetTransform()->Update();
198   }
199 }
200 //------------------------------------------------------------------------------
201 #endif
202