Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkDiffusionDICOMFileReaderHelper.h
Go to the documentation of this file.
1 #ifndef MITKDIFFUSIONDICOMFILEREADERHELPER_H
2 #define MITKDIFFUSIONDICOMFILEREADERHELPER_H
3 
4 #include "itkImageSeriesReader.h"
5 #include "itkVectorImage.h"
6 
7 #include "itkImageRegionIteratorWithIndex.h"
8 
9 namespace mitk
10 {
11 
17 {
18  unsigned int nimages;
20 
21  itk::ImageBase<3>::SpacingType spacing;
22  itk::ImageBase<3>::DirectionType direction;
23  float origin[3];
24 };
25 
27 {
28 public:
29  typedef std::vector< std::string > StringContainer;
30 
31  typedef std::vector< StringContainer > VolumeFileNamesContainer;
32 
33  std::string GetOutputName(const VolumeFileNamesContainer& filenames)
34  {
35  typedef itk::Image< short, 3> InputImageType;
36  typedef itk::ImageSeriesReader< InputImageType > SeriesReaderType;
37 
39  probe_reader->SetFileNames( filenames.at(0) );
40  probe_reader->GenerateOutputInformation();
41  probe_reader->Update();
42 
43  std::string seriesDescTag, seriesNumberTag, patientName;
44  SeriesReaderType::DictionaryArrayRawPointer inputDict = probe_reader->GetMetaDataDictionaryArray();
45 
46  if( ! itk::ExposeMetaData< std::string > ( *(*inputDict)[0], "0008|103e", seriesDescTag ) )
47  seriesDescTag = "UNSeries";
48 
49  if( ! itk::ExposeMetaData< std::string > ( *(*inputDict)[0], "0020|0011", seriesNumberTag ) )
50  seriesNumberTag = "00000";
51 
52  if( ! itk::ExposeMetaData< std::string > ( *(*inputDict)[0], "0010|0010", patientName ) )
53  patientName = "UnknownName";
54 
55  std::stringstream ss;
56  ss << seriesDescTag << "_" << seriesNumberTag << "_" << patientName;
57 
58  return ss.str();
59 
60  }
61 
62  template< typename PixelType, unsigned int VecImageDimension>
64  const VolumeFileNamesContainer& filenames
65  //const itk::ImageBase<3>::RegionType requestedRegion
66  )
67  {
68  typedef itk::Image< PixelType, 3> InputImageType;
69  typedef itk::ImageSeriesReader< InputImageType > SeriesReaderType;
70 
71  typename SeriesReaderType::Pointer probe_reader = SeriesReaderType::New();
72  probe_reader->SetFileNames( filenames.at(0) );
73  probe_reader->GenerateOutputInformation();
74  const itk::ImageBase<3>::RegionType requestedRegion = probe_reader->GetOutput()->GetLargestPossibleRegion();
75 
76  MITK_INFO << " --- Probe reader : \n" <<
77  " Retrieved LPR " << requestedRegion;
78 
79  typedef itk::VectorImage< PixelType, 3 > VectorImageType;
80 
81  typename VectorImageType::Pointer output_image = VectorImageType::New();
82  output_image->SetNumberOfComponentsPerPixel( filenames.size() );
83  output_image->SetSpacing( probe_reader->GetOutput()->GetSpacing() );
84  output_image->SetOrigin( probe_reader->GetOutput()->GetOrigin() );
85  output_image->SetDirection( probe_reader->GetOutput()->GetDirection() );
86  output_image->SetLargestPossibleRegion( probe_reader->GetOutput()->GetLargestPossibleRegion() );
87  output_image->SetBufferedRegion( requestedRegion );
88  output_image->Allocate();
89 
90  itk::ImageRegionIterator< VectorImageType > vecIter(
91  output_image, requestedRegion );
92 
93  auto volumesFileNamesIter = filenames.begin();
94 
95  // iterate over the given volumes
96  unsigned int component = 0;
97  while( volumesFileNamesIter != filenames.end() )
98  {
99 
100  MITK_INFO << " ======== Loading volume " << component+1 << " of " << filenames.size();
101 
102  typename SeriesReaderType::Pointer volume_reader = SeriesReaderType::New();
103  volume_reader->SetFileNames( *volumesFileNamesIter );
104 
105  try
106  {
107  volume_reader->UpdateLargestPossibleRegion();
108  }
109  catch( const itk::ExceptionObject &e)
110  {
111  mitkThrow() << " ITK Series reader failed : "<< e.what();
112  }
113 
114  itk::ImageRegionConstIterator< InputImageType > iRCIter (
115  volume_reader->GetOutput(),
116  volume_reader->GetOutput()->GetLargestPossibleRegion() );
117 
118  // transfer to vector image
119  iRCIter.GoToBegin();
120  vecIter.GoToBegin();
121 
122 
123 
124  while( !iRCIter.IsAtEnd() )
125  {
126  typename VectorImageType::PixelType vector_pixel = vecIter.Get();
127  vector_pixel.SetElement( component, iRCIter.Get() );
128  vecIter.Set( vector_pixel );
129 
130  ++vecIter;
131  ++iRCIter;
132  }
133 
134  ++volumesFileNamesIter;
135  component++;
136  }
137 
138  return output_image;
139 
140  }
141 
142 
148  template< typename PixelType, unsigned int VecImageDimension>
150  const VolumeFileNamesContainer& filenames,
151  const MosaicDescriptor& mosaicInfo )
152  {
153  typedef itk::Image< PixelType, 3> MosaicImageType;
154  typedef itk::ImageFileReader< MosaicImageType > SingleImageReaderType;
155 
156  // generate output
157  typedef itk::VectorImage< PixelType, 3 > VectorImageType;
158 
159  auto volumesFileNamesIter = filenames.begin();
160 
161  // probe the first file to retrieve the size of the 2d image
162  // we need this information to compute the index relation between mosaic and resulting 3d position
163  // but we need it only once
165  mosaic_probe->SetFileName( (*volumesFileNamesIter).at(0) );
166  try
167  {
168  mosaic_probe->UpdateLargestPossibleRegion();
169  }
170  catch( const itk::ExceptionObject &e)
171  {
172  mitkThrow() << " ITK Image file reader failed : "<< e.what();
173  }
174 
175  typename MosaicImageType::RegionType mosaic_lpr = mosaic_probe->GetOutput()->GetLargestPossibleRegion();
176  MITK_INFO << " == MOSAIC: " << mosaic_lpr;
177 
178  itk::ImageBase<3>::SizeValueType images_per_row = ceil( sqrt( (float) mosaicInfo.nimages ) );
179 
180  itk::ImageBase<3>::RegionType requestedRegion;
181  requestedRegion.SetSize( 0, mosaic_lpr.GetSize()[0]/images_per_row);
182  requestedRegion.SetSize( 1, mosaic_lpr.GetSize()[1]/images_per_row);
183  requestedRegion.SetSize( 2, mosaicInfo.nimages);
184 
185  typename VectorImageType::Pointer output_image = VectorImageType::New();
186  output_image->SetNumberOfComponentsPerPixel( filenames.size() );
187 
188  typename VectorImageType::DirectionType dmatrix;
189  dmatrix.SetIdentity();
190 
191  std::vector<double> dirx = mosaic_probe->GetImageIO()->GetDirection(0);
192  std::vector<double> diry = mosaic_probe->GetImageIO()->GetDirection(1);
193  std::vector<double> dirz = mosaic_probe->GetImageIO()->GetDirection(2);
194 
195  dmatrix.GetVnlMatrix().set_column( 0, &dirx[0] );
196  dmatrix.GetVnlMatrix().set_column( 1, &diry[0] );
197  dmatrix.GetVnlMatrix().set_column( 2, &dirz[0] );
198 
199 
200  /*
201  FIXME!!! The struct currently does not provide the geometry information
202  the loading works as required*/
203  output_image->SetSpacing( mosaicInfo.spacing );
204  output_image->SetOrigin( mosaic_probe->GetOutput()->GetOrigin() );
205  output_image->SetDirection( dmatrix );
206  output_image->SetLargestPossibleRegion( requestedRegion );
207  output_image->SetBufferedRegion( requestedRegion );
208  output_image->Allocate();
209 
210  itk::ImageRegionIteratorWithIndex< VectorImageType > vecIter(
211  output_image, requestedRegion );
212 
213  // hold the image sizes in an extra variable ( used very often )
214  typename MosaicImageType::SizeValueType dx = requestedRegion.GetSize()[0];
215  typename MosaicImageType::SizeValueType dy = requestedRegion.GetSize()[1];
216 
217  // iterate over the given volumes
218  unsigned int component = 0;
219  while( volumesFileNamesIter != filenames.end() )
220  {
221 
222  MITK_INFO << " ======== Loading volume " << component+1 << " of " << filenames.size();
223 
225  mosaic_reader->SetFileName( (*volumesFileNamesIter).at(0) );
226 
227  try
228  {
229  mosaic_reader->UpdateLargestPossibleRegion();
230  }
231  catch( const itk::ExceptionObject &e)
232  {
233  mitkThrow() << " ITK Image file reader failed : "<< e.what();
234  }
235 
236  typename MosaicImageType::Pointer current_mosaic = mosaic_reader->GetOutput();
237 
238  vecIter.GoToBegin();
239  while( !vecIter.IsAtEnd() )
240  {
241  typename VectorImageType::PixelType vector_pixel = vecIter.Get();
242  typename VectorImageType::IndexType threeD_index = vecIter.GetIndex();
243 
244  typename MosaicImageType::IndexType mosaic_index;
245 
246  mosaic_index[2] = 0;
247 
248  // first find the corresponding tile in the mosaic
249  // this is defined by the z-position of the vector (3D) image iterator
250  // in x : z_index % #images_in_grid
251  // in y : z_index / #images_in_grid
252  //
253  // the remaining is just computing the correct position in the mosaic, done by
254  // --------- index of (0,0,z) ----- + --- current 2d position ---
255  mosaic_index[0] = (threeD_index[2] % images_per_row) * dx + threeD_index[0];
256  mosaic_index[1] = (threeD_index[2] / images_per_row) * dy + threeD_index[1];
257 
258  typename MosaicImageType::PixelType mosaic_pixel = current_mosaic->GetPixel( mosaic_index );
259 
260  vector_pixel.SetElement( component, mosaic_pixel );
261 
262  vecIter.Set( vector_pixel );
263 
264  ++vecIter;
265  }
266 
267  ++volumesFileNamesIter;
268  component++;
269 
270  }
271 
272  return output_image;
273 
274  }
275 
276 };
277 
278 
279 }
280 
281 #endif // MITKDIFFUSIONDICOMFILEREADERHELPER_H
itk::ImageBase< 3 >::DirectionType direction
itk::SmartPointer< Self > Pointer
The MosaicDescriptor struct is a help struct holding the necessary information for loading a mosaic D...
#define MITK_INFO
Definition: mitkLogMacros.h:22
DataCollection - Class to facilitate loading/accessing structured data.
itk::VectorImage< float, 3 > VectorImageType
itk::Image< double, 3 > InputImageType
std::string GetOutputName(const VolumeFileNamesContainer &filenames)
#define mitkThrow()
itk::VectorImage< PixelType, VecImageDimension >::Pointer LoadMosaicToVector(const VolumeFileNamesContainer &filenames, const MosaicDescriptor &mosaicInfo)
unsigned short PixelType
itk::ImageBase< 3 >::SpacingType spacing
itk::VectorImage< PixelType, VecImageDimension >::Pointer LoadToVector(const VolumeFileNamesContainer &filenames)
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.