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.
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.
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/>.
18 * @file DicomReader.ih
19 * @author Adrien Krähenbühl (\c adrien.krahenbuhl@loria.fr )
20 * LORIA (CNRS, UMR 7503), Université de Lorraine, France
24 * Implementation of inline methods defined in DicomReader.h
26 * This file is part of the DGtal library.
29///////////////////////////////////////////////////////////////////////////////
30// IMPLEMENTATION of inline methods.
31///////////////////////////////////////////////////////////////////////////////
33//////////////////////////////////////////////////////////////////////////////
39#include "DGtal/io/Color.h"
40#include "DGtal/images/ConstImageAdapter.h"
42// Required ITK files to read serie DICOM files
43// DGtal must be compiled with "-DWITH_ITK=true" option
45#pragma GCC diagnostic push
46#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
47#pragma GCC diagnostic ignored "-Wpedantic"
49#pragma GCC diagnostic ignored "-Wdeprecated-copy"
53#pragma clang diagnostic push
54#pragma clang diagnostic ignored "-Wdocumentation"
57#include <itkImageSeriesReader.h>
58#include <itkGDCMImageIO.h>
59#include <itkGDCMSeriesFileNames.h>
61#pragma clang diagnostic pop
64#pragma GCC diagnostic pop
66//////////////////////////////////////////////////////////////////////////////
70///////////////////////////////////////////////////////////////////////////////
71// Implementation of inline methods //
74///////////////////////////////////////////////////////////////////////////////
75// Implementation of inline functions and external operators //
80template <typename TImageContainer, typename TFunctor>
81template <typename Domain, typename PixelType>
83ImageContainerByITKImage<Domain, PixelType>
84DicomReader<TImageContainer, TFunctor>::
85importDicomFiles_( const std::vector<std::string> & filenames )
87 // Definition of image type
88 const unsigned int dimension = Domain::dimension;
89 typedef itk::Image<PixelType, dimension> ItkImage;
90 typedef itk::ImageSeriesReader<ItkImage> ItkReader;
91 typename ItkReader::Pointer reader = ItkReader::New();
93 // Definition of ITK Dicom reader
94 //typedef itk::GDCMImageIO ItkImageIO;
95 //ItkImageIO::Pointer dicomIO = ItkImageIO::New();
96 //reader->SetImageIO( dicomIO );
99 reader->SetFileNames( filenames );
101 typedef ImageContainerByITKImage<Domain, PixelType> TypeDGtalImage;
102 typedef typename TypeDGtalImage::ITKImagePointer ITKImagePointer;
103 ITKImagePointer itkImage = nullptr;
112 trace.error() << "DicomReader: can't read " << filenames.size()
113 << " files"<<std::endl;
117 itkImage = reader->GetOutput();
119 const typename ItkImage::SizeType& inputSize =
120 itkImage->GetLargestPossibleRegion().GetSize();
121 const unsigned int width = inputSize[0];
122 const unsigned int height = inputSize[1];
123 const unsigned int depth = inputSize[2];
124 if ( !height || !width || !depth )
126 trace.error() << "DicomReader: one dimension is null (w=" << width
127 << ", h=" << height << ", d=" << depth << ")"
132 const TypeDGtalImage dgtalItkImage( itkImage );
134 return dgtalItkImage;
137template <typename TImageContainer, typename TFunctor>
138template <typename Image, typename Domain, typename OutPixelType,
141DicomReader<TImageContainer, TFunctor>::Aux<Image, Domain, OutPixelType,
143importDicomFiles( const std::vector<std::string> & filenames,
144 const TFunctor & aFunctor )
146 typedef OutPixelType Value;
148 typedef ImageContainerByITKImage<Domain, PixelType> TypeDGtalImage;
149 const TypeDGtalImage dgtalItkImage =
150 importDicomFiles_<Domain, PixelType>( filenames );
152 const Domain& domain = dgtalItkImage.domain();
154 typedef ConstImageAdapter<TypeDGtalImage, Domain, functors::Identity,
155 Value, TFunctor> AdaptedImage;
156 const functors::Identity identityFunctor{};
157 const AdaptedImage adapted( dgtalItkImage, domain, identityFunctor,
160 TImageContainer image( domain );
161 std::copy( adapted.constRange().begin(), adapted.constRange().end(),
162 image.range().outputIterator() );
168template <typename TImageContainer, typename TFunctor>
169template <typename Domain, typename OutPixelType, typename PixelType>
170ImageContainerByITKImage<Domain, OutPixelType>
171DicomReader<TImageContainer, TFunctor>::
172Aux<ImageContainerByITKImage<Domain, OutPixelType>, Domain, OutPixelType,
174importDicomFiles( const std::vector<std::string> & filenames,
175 const TFunctor & aFunctor )
177 typedef OutPixelType Value;
179 typedef ImageContainerByITKImage<Domain, PixelType> TypeDGtalImage;
180 const TypeDGtalImage dgtalItkImage =
181 importDicomFiles_<Domain, PixelType>( filenames );
183 const Domain& domain = dgtalItkImage.domain();
185 typedef ConstImageAdapter<TypeDGtalImage, Domain, functors::Identity, Value,
186 TFunctor> AdaptedImage;
187 const functors::Identity identityFunctor{};
188 const AdaptedImage adapted( dgtalItkImage, domain, identityFunctor, aFunctor );
190 TImageContainer image( domain );
191 std::copy( adapted.constRange().begin(), adapted.constRange().end(),
192 image.range().outputIterator() );
194 //copy ITKImage parameters
195 image.getITKImagePointer()->SetOrigin(
196 dgtalItkImage.getITKImagePointer()->GetOrigin() );
197 image.getITKImagePointer()->SetSpacing(
198 dgtalItkImage.getITKImagePointer()->GetSpacing() );
199 image.getITKImagePointer()->SetDirection(
200 dgtalItkImage.getITKImagePointer()->GetDirection() );
206template <typename TImageContainer, typename TFunctor>
207template <typename PixelType>
208inline TImageContainer
209DicomReader<TImageContainer, TFunctor>::
210importDicomFiles( const std::vector<std::string> & filenames,
211 const TFunctor & aFunctor )
213 typedef typename TImageContainer::Domain Domain;
214 return Aux<TImageContainer, Domain, Value, PixelType>::
215 importDicomFiles( filenames, aFunctor );
219template <typename TImageContainer, typename TFunctor>
222DicomReader<TImageContainer, TFunctor>::
223importDicom( const std::string & aFilename,
224 const TFunctor & aFunctor )
226 std::string directory = aFilename.substr( 0, aFilename.find_last_of("/") );
228 typedef itk::GDCMSeriesFileNames ItkNamesGenerator;
229 ItkNamesGenerator::Pointer nameGenerator = ItkNamesGenerator::New();
230 nameGenerator->SetDirectory( directory );
231 const std::vector<std::string> &filenames =
232 nameGenerator->GetInputFileNames();
234 return importDicomFiles<PixelType>( filenames, aFunctor );
237template <typename TImageContainer, typename TFunctor>
240DicomReader<TImageContainer, TFunctor>::
241importDicomSeries( const std::vector<std::string> & filenames,
242 const Functor & aFunctor )
244 return importDicomFiles<PixelType>( filenames, aFunctor );
250///////////////////////////////////////////////////////////////////////////////