Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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.