]> Creatis software - clitk.git/blob - common/vvImageReader.txx
e15e6d7688ff4a6a202e8f9e62bd42d133128ca5
[clitk.git] / common / vvImageReader.txx
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://www.centreleonberard.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
19 #ifndef VVIMAGEREADER_TXX
20 #define VVIMAGEREADER_TXX
21
22 #include <string>
23 #include <itkImageFileReader.h>
24 #include <itkImageSeriesReader.h>
25 #include <itkImageToVTKImageFilter.h>
26 #include <itkAnalyzeImageIO.h>
27 #include <itkVectorCastImageFilter.h>
28
29 #include <vtkTransform.h>
30
31 #include "clitkCommon.h"
32 #include "clitkConfiguration.h"
33 #include "vvFromITK.h"
34 //----------------------------------------------------------------------------
35 template<unsigned int VImageDimension>
36 void vvImageReader::UpdateWithDim(std::string InputPixelType)
37 {
38   if (mType == VECTORFIELD || mType == VECTORFIELDWITHTIME)
39     UpdateWithDimAndInputVectorPixelType<itk::Vector<float,VImageDimension>,VImageDimension>();
40   else if (InputPixelType == "short")
41     UpdateWithDimAndInputPixelType<short,VImageDimension>();
42   else if (InputPixelType == "unsigned_short")
43     UpdateWithDimAndInputPixelType<unsigned short,VImageDimension>();
44   else if (InputPixelType == "char")
45     UpdateWithDimAndInputPixelType<char,VImageDimension>();
46   else if (InputPixelType == "unsigned_char")
47     UpdateWithDimAndInputPixelType<unsigned char,VImageDimension>();
48   else if (InputPixelType == "int")
49     UpdateWithDimAndInputPixelType<int,VImageDimension>();
50   else if (InputPixelType == "unsigned_int")
51     UpdateWithDimAndInputPixelType<unsigned int,VImageDimension>();
52   else if (InputPixelType == "double")
53     UpdateWithDimAndInputPixelType<double,VImageDimension>();
54   else if (InputPixelType == "float")
55     UpdateWithDimAndInputPixelType<float,VImageDimension>();
56   else
57     std::cerr << "Error, input pixel type : " << InputPixelType << " unknown !" << std::endl;
58
59   if (CLITK_EXPERIMENTAL && mLastError.size()==0) {
60     //ReadNkiImageTransform();
61     ReadMatImageTransform();
62   }
63 }
64 //----------------------------------------------------------------------------
65
66
67 //----------------------------------------------------------------------------
68 template<class InputPixelType, unsigned int VImageDimension>
69 void vvImageReader::UpdateWithDimAndInputPixelType()
70 {
71   itk::AnalyzeImageIO *analyzeImageIO = NULL;
72
73   if (mType == MERGEDWITHTIME)   // In this case we can load the images
74     // one at the time to avoid excessive
75     // memory use
76   {
77     mImage=vvImage::New();
78
79     for (std::vector<std::string>::const_iterator i=mInputFilenames.begin(); i!=mInputFilenames.end(); i++) {
80       typedef itk::Image< InputPixelType, VImageDimension-1 > InputImageType;
81       typedef itk::ImageFileReader<InputImageType> ReaderType;
82       typename ReaderType::Pointer reader = ReaderType::New();
83       reader->ReleaseDataFlagOn();
84       reader->SetFileName(*i);
85       try {
86         mImage->AddItkImage<InputImageType>(reader->GetOutput());
87       } catch ( itk::ExceptionObject & err ) {
88         std::cerr << "Error while reading " << mInputFilenames[0].c_str()
89                   << " " << err << std::endl;
90         std::stringstream error;
91         error << err;
92         mLastError = error.str();
93         return;
94       }
95       analyzeImageIO = dynamic_cast<itk::AnalyzeImageIO*>( reader->GetImageIO() );
96     }
97   } else if (mType == SLICED) {
98     mImage=vvImage::New();
99     typedef itk::Image< InputPixelType, VImageDimension > InputImageType;
100     typedef itk::ImageFileReader<InputImageType> ReaderType;
101     typename ReaderType::Pointer reader = ReaderType::New();
102     reader->SetFileName(mInputFilenames[0]);
103     reader->UpdateOutputInformation();
104
105     typedef itk::Image< InputPixelType, VImageDimension-1 > SlicedImageType;
106     typedef itk::ExtractImageFilter<InputImageType, SlicedImageType> FilterType;
107
108     typename InputImageType::RegionType inputRegion = reader->GetOutput()->GetLargestPossibleRegion();
109     typename InputImageType::SizeType inputSize = inputRegion.GetSize();
110     typename InputImageType::IndexType start = inputRegion.GetIndex();
111     typename InputImageType::SizeType extractedRegionSize = inputSize;
112     typename InputImageType::RegionType extractedRegion;
113     extractedRegionSize[VImageDimension - 1] = 0;
114     extractedRegion.SetSize(extractedRegionSize);
115     start[VImageDimension - 1] = mSlice;
116     extractedRegion.SetIndex(start);
117
118     typename FilterType::Pointer filter = FilterType::New();
119     filter->SetExtractionRegion(extractedRegion);
120     filter->SetInput(reader->GetOutput());
121     filter->ReleaseDataFlagOn();
122 #if ITK_VERSION_MAJOR == 4
123     filter->SetDirectionCollapseToSubmatrix();
124 #endif
125     try {
126       mImage->AddItkImage<SlicedImageType>(filter->GetOutput());
127     } catch ( itk::ExceptionObject & err ) {
128       std::cerr << "Error while slicing " << mInputFilenames[0].c_str()
129                 << "(slice #" << mSlice << ") " << err << std::endl;
130       return;
131     }
132     analyzeImageIO = dynamic_cast<itk::AnalyzeImageIO*>( reader->GetImageIO() );
133   } else {
134     if (mInputFilenames.size() > 1) {
135       typedef itk::Image< InputPixelType, VImageDimension > InputImageType;
136       typedef itk::ImageSeriesReader<InputImageType> ReaderType;
137       typename ReaderType::Pointer reader = ReaderType::New();
138       reader->SetFileNames(mInputFilenames);
139       reader->ReleaseDataFlagOn();
140
141       try {
142         if (mType == IMAGEWITHTIME)
143         {
144           std::cerr << "We should never come here:" << std::endl
145             << "  Calling vvImageReader with multiple images and IMAGEWITHTIME is undefined." << std::endl
146             << "  You are probably looking for MERGEDWITHTIME Type." << std::endl;
147           return;
148         }
149         else
150           mImage=vvImageFromITK<VImageDimension,InputPixelType>(reader->GetOutput());
151       } catch ( itk::ExceptionObject & err ) {
152         std::cerr << "Error while reading image series:" << err << std::endl;
153         std::stringstream error;
154         error << err;
155         mLastError = error.str();
156         return;
157       }
158     } else {
159       typedef itk::Image< InputPixelType, VImageDimension > InputImageType;
160       typedef itk::ImageFileReader<InputImageType> ReaderType;
161       typename ReaderType::Pointer reader = ReaderType::New();
162       reader->SetFileName(mInputFilenames[0]);
163       reader->ReleaseDataFlagOn();
164
165       try {
166         mImage = vvImageFromITK<VImageDimension,InputPixelType>(reader->GetOutput(), mType == IMAGEWITHTIME || mType == VECTORFIELDWITHTIME);
167       } catch ( itk::ExceptionObject & err ) {
168         std::cerr << "Error while reading " << mInputFilenames[0].c_str()
169                   << " " << err << std::endl;
170         std::stringstream error;
171         error << err;
172         mLastError = error.str();
173         return;
174       }
175       analyzeImageIO = dynamic_cast<itk::AnalyzeImageIO*>( reader->GetImageIO() );
176     }
177   }
178
179   // For unknown analyze orientations, we set identity
180   if(analyzeImageIO) {
181     const double m[16] = {1.,0.,0.,0.,
182                           0.,0.,1.,0.,
183                           0.,-1.,0.,0.,
184                           0.,0.,0.,1.};
185     int i;
186     for(i=0; i<16 && m[i]==mImage->GetTransform()->GetMatrix()->GetElement(i%4, i/4); i++);
187     if(i==16) {
188       itkWarningMacro(<< "Analyze image file format detected with unknown orientation. "
189                       << "Forcing identity orientation, use other file format if not ok.");
190       mImage->GetTransform()->Identity();
191     }
192   }
193 }
194 //----------------------------------------------------------------------------
195
196 //----------------------------------------------------------------------------
197 template<class InputPixelType, unsigned int VImageDimension>
198 void vvImageReader::UpdateWithDimAndInputVectorPixelType()
199 {
200   itk::AnalyzeImageIO *analyzeImageIO = NULL;
201
202   typedef itk::Image< InputPixelType, VImageDimension > InputImageType;
203   typename InputImageType::Pointer input;
204
205   if (mInputFilenames.size() > 1) {
206     typedef itk::ImageSeriesReader<InputImageType> ReaderType;
207     typename ReaderType::Pointer reader = ReaderType::New();
208     reader->SetFileNames(mInputFilenames);
209     reader->ReleaseDataFlagOn();
210     try {
211       reader->Update();
212       input = reader->GetOutput();
213     } catch ( itk::ExceptionObject & err ) {
214       std::cerr << "Error while reading image series:" << err << std::endl;
215       std::stringstream error;
216       error << err;
217       mLastError = error.str();
218       return;
219     }
220   } else {
221     typedef itk::ImageFileReader<InputImageType> ReaderType;
222     typename ReaderType::Pointer reader = ReaderType::New();
223     reader->SetFileName(mInputFilenames[0]);
224     reader->ReleaseDataFlagOn();
225     try {
226       reader->Update();
227       input = reader->GetOutput();
228     } catch ( itk::ExceptionObject & err ) {
229       std::cerr << "Error while reading " << mInputFilenames[0].c_str()
230         << " " << err << std::endl;
231       std::stringstream error;
232       error << err;
233       mLastError = error.str();
234       return;
235     }
236     analyzeImageIO = dynamic_cast<itk::AnalyzeImageIO*>( reader->GetImageIO() );
237   }
238
239   typedef itk::Image< itk::Vector<float , 3>, VImageDimension > VectorImageType;
240   typedef itk::VectorCastImageFilter<InputImageType, VectorImageType> CasterType;
241   typename VectorImageType::Pointer casted_input;
242   typename CasterType::Pointer caster = CasterType::New();
243   caster->SetInput(input);
244   casted_input = caster->GetOutput();
245
246   mImage = vvImageFromITK<VImageDimension, itk::Vector<float, 3> >(casted_input, mType == IMAGEWITHTIME || mType == VECTORFIELDWITHTIME);
247
248   // For unknown analyze orientations, we set identity
249   if (analyzeImageIO)
250   {
251     const double m[16] = {1.,0.,0.,0.,
252                           0.,0.,1.,0.,
253                           0.,-1.,0.,0.,
254                           0.,0.,0.,1.};
255     int i;
256     for (i = 0; i < 16 && m[i] == mImage->GetTransform()->GetMatrix()->GetElement(i % 4, i / 4); i++)
257       ;
258     if (i == 16)
259     {
260       itkWarningMacro(<< "Analyze image file format detected with unknown orientation. "
261                       << "Forcing identity orientation, use other file format if not ok.");
262       mImage->GetTransform()->Identity();
263     }
264   }
265 }
266 //----------------------------------------------------------------------------
267
268 #endif /* end #define vvImageReader_TXX */
269