DGtal  1.0.0
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 #pragma GCC diagnostic ignored "-Wpedantic"
47 #endif
48 #if defined(__clang__)
49 #pragma clang diagnostic push
50 #pragma clang diagnostic ignored "-Wdocumentation"
51 #endif
52 #include <itkImage.h>
53 #include <itkImageSeriesReader.h>
54 #include <itkGDCMImageIO.h>
55 #include <itkGDCMSeriesFileNames.h>
56 #if defined(__clang__)
57 #pragma clang diagnostic pop
58 #endif
59 #if defined(__GNUG__)
60 #pragma GCC diagnostic pop
61 #endif
62 //////////////////////////////////////////////////////////////////////////////
63 
64 
65 
66 ///////////////////////////////////////////////////////////////////////////////
67 // Implementation of inline methods //
68 
69 
70 ///////////////////////////////////////////////////////////////////////////////
71 // Implementation of inline functions and external operators //
72 
73 template <typename TImageContainer, typename TFunctor>
74 inline
75 TImageContainer
76 DGtal::DicomReader<TImageContainer, TFunctor>::importDicom(const std::string & aFilename,
77  const TFunctor &aFunctor)
78 {
79  DGtal::IOException dgtalio;
80 
81  std::string directory = aFilename.substr(0,aFilename.find_last_of("/"));
82 
83  // Définition of image type
84  const unsigned int Dimension = ImageContainer::Domain::dimension;
85  typedef itk::Image<PixelType,Dimension> ItkImage;
86  typedef itk::ImageSeriesReader<ItkImage> ItkReader;
87  typename ItkReader::Pointer reader = ItkReader::New();
88 
89  // Définition of ITK Dicom reader
90  typedef itk::GDCMImageIO ItkImageIO;
91  ItkImageIO::Pointer dicomIO = ItkImageIO::New();
92  reader->SetImageIO(dicomIO);
93 
94  // Series reader
95  typedef itk::GDCMSeriesFileNames ItkNamesGenerator;
96  ItkNamesGenerator::Pointer nameGenerator = ItkNamesGenerator::New();
97  nameGenerator->SetDirectory(directory);
98  reader->SetFileNames(nameGenerator->GetInputFileNames());
99 
100  // Image reading
101  try
102  {
103  reader->Update();
104  }
105  catch( ... )
106  {
107  trace.error() << "DicomReader: can't read " << aFilename << std::endl;
108  trace.error() << "(from directory: " << directory << ")" << std::endl;
109  throw dgtalio;
110  }
111 
112  const typename ItkImage::SizeType& inputSize = reader->GetOutput()->GetLargestPossibleRegion().GetSize();
113  const unsigned int width = inputSize[0];
114  const unsigned int height = inputSize[1];
115  const unsigned int depth = inputSize[2];
116  if ( !height || !width || !depth )
117  {
118  trace.error() << "DicomReader: one dimension is null (w=" << width << ", h=" << height << ", d=" << depth << ")" << std::endl;
119  throw dgtalio;
120  }
121 
122  // Itk Image pointer
123  const typename ItkImage::Pointer &itkImage = reader->GetOutput();
124  itk::ImageRegionConstIterator< ItkImage > in( itkImage,itkImage->GetBufferedRegion() );
125 
126  // DGtal image
127  typename ImageContainer::Point firstPoint( 0, 0, 0 );
128  typename ImageContainer::Point lastPoint( width-1, height-1, depth-1 );
129 
130  typename ImageContainer::Domain domain(firstPoint,lastPoint);
131  typename ImageContainer::Domain::ConstIterator itDomain = domain.begin();
132  typename ImageContainer::Domain::ConstIterator endDomain = domain.end();
133 
134  ImageContainer image(domain);
135 
136  // DGtal image filling
137  long int total = width * height * depth;
138  long count = 0;
139  while ( itDomain != endDomain )
140  {
141  const PixelType &value = in.Value();
142  image.setValue( *itDomain , aFunctor(value) );
143  ++in;
144  ++itDomain;
145  ++count;
146  }
147 
148  if ( count != total )
149  {
150  trace.error() << "DicomReader: can't read file (raw data) !\n";
151  throw dgtalio;
152  }
153 
154  return image;
155 }
156 
157 
158 // //
159 ///////////////////////////////////////////////////////////////////////////////
160 
161