DGtal  0.9.2
DicomReader.ih
1 /**
2  * This program is free software: you can redistribute it and/or modify
3  * it under the terms of the GNU Lesser General Public License as
4  * published by the Free Software Foundation, either version 3 of the
5  * License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program. If not, see <http://www.gnu.org/licenses/>.
14  *
15  **/
16 
17 /**
18  * @file DicomReader.ih
19  * @author Adrien Krähenbühl (\c adrien.krahenbuhl@loria.fr )
20  * LORIA (CNRS, UMR 7503), Université de Lorraine, France
21  *
22  * @date 2013/10/10
23  *
24  * Implementation of inline methods defined in DicomReader.h
25  *
26  * This file is part of the DGtal library.
27  */
28 
29 ///////////////////////////////////////////////////////////////////////////////
30 // IMPLEMENTATION of inline methods.
31 ///////////////////////////////////////////////////////////////////////////////
32 
33 //////////////////////////////////////////////////////////////////////////////
34 #include <cstdlib>
35 #include <iostream>
36 #include <fstream>
37 #include <sstream>
38 
39 #include "DGtal/io/Color.h"
40 
41 // Required ITK files to read serie DICOM files
42 // DGtal must be compiled with "-DWITH_ITK=true" option
43 #if defined(__GNUG__)
44 #pragma GCC diagnostic push
45 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
46 #endif
47 #if defined(__clang__)
48 #pragma clang diagnostic push
49 #pragma clang diagnostic ignored "-Wdocumentation"
50 #endif
51 #include <itkImage.h>
52 #include <itkImageSeriesReader.h>
53 #include <itkGDCMImageIO.h>
54 #include <itkGDCMSeriesFileNames.h>
55 #if defined(__clang__)
56 #pragma clang diagnostic pop
57 #endif
58 #if defined(__GNUG__)
59 #endif
60 #pragma GCC diagnostic pop
61 //////////////////////////////////////////////////////////////////////////////
62 
63 
64 
65 ///////////////////////////////////////////////////////////////////////////////
66 // Implementation of inline methods //
67 
68 
69 ///////////////////////////////////////////////////////////////////////////////
70 // Implementation of inline functions and external operators //
71 
72 template <typename TImageContainer, typename TFunctor>
73 inline
74 TImageContainer
75 DGtal::DicomReader<TImageContainer, TFunctor>::importDicom(const std::string & aFilename,
76  const TFunctor &aFunctor) throw(DGtal::IOException)
77 {
78  DGtal::IOException dgtalio;
79 
80  std::string directory = aFilename.substr(0,aFilename.find_last_of("/"));
81 
82  // Définition of image type
83  const unsigned int Dimension = ImageContainer::Domain::dimension;
84  typedef itk::Image<PixelType,Dimension> ItkImage;
85  typedef itk::ImageSeriesReader<ItkImage> ItkReader;
86  typename ItkReader::Pointer reader = ItkReader::New();
87 
88  // Définition of ITK Dicom reader
89  typedef itk::GDCMImageIO ItkImageIO;
90  ItkImageIO::Pointer dicomIO = ItkImageIO::New();
91  reader->SetImageIO(dicomIO);
92 
93  // Series reader
94  typedef itk::GDCMSeriesFileNames ItkNamesGenerator;
95  ItkNamesGenerator::Pointer nameGenerator = ItkNamesGenerator::New();
96  nameGenerator->SetDirectory(directory);
97  reader->SetFileNames(nameGenerator->GetInputFileNames());
98 
99  // Image reading
100  try
101  {
102  reader->Update();
103  }
104  catch( ... )
105  {
106  trace.error() << "DicomReader: can't read " << aFilename << std::endl;
107  trace.error() << "(from directory: " << directory << ")" << std::endl;
108  throw dgtalio;
109  }
110 
111  const typename ItkImage::SizeType& inputSize = reader->GetOutput()->GetLargestPossibleRegion().GetSize();
112  const unsigned int width = inputSize[0];
113  const unsigned int height = inputSize[1];
114  const unsigned int depth = inputSize[2];
115  if ( !height || !width || !depth )
116  {
117  trace.error() << "DicomReader: one dimension is null (w=" << width << ", h=" << height << ", d=" << depth << ")" << std::endl;
118  throw dgtalio;
119  }
120 
121  // Itk Image pointer
122  const typename ItkImage::Pointer &itkImage = reader->GetOutput();
123  itk::ImageRegionConstIterator< ItkImage > in( itkImage,itkImage->GetBufferedRegion() );
124 
125  // DGtal image
126  typename ImageContainer::Point firstPoint( 0, 0, 0 );
127  typename ImageContainer::Point lastPoint( width-1, height-1, depth-1 );
128 
129  typename ImageContainer::Domain domain(firstPoint,lastPoint);
130  typename ImageContainer::Domain::ConstIterator itDomain = domain.begin();
131  typename ImageContainer::Domain::ConstIterator endDomain = domain.end();
132 
133  ImageContainer image(domain);
134 
135  // DGtal image filling
136  long int total = width * height * depth;
137  long count = 0;
138  while ( itDomain != endDomain )
139  {
140  const PixelType &value = in.Value();
141  image.setValue( *itDomain , aFunctor(value) );
142  ++in;
143  ++itDomain;
144  ++count;
145  }
146 
147  if ( count != total )
148  {
149  trace.error() << "DicomReader: can't read file (raw data) !\n";
150  throw dgtalio;
151  }
152 
153  return image;
154 }
155 
156 
157 // //
158 ///////////////////////////////////////////////////////////////////////////////
159 
160