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 ITKDicomReader.ih
19 * @author Boris Mansencal (\c boris.mansencal@labri.fr )
20 * LaBRI (CNRS, UMR 5800, University of Bordeaux, Bordeaux-INP, France
24 * Header file for module ITKDicomReader.cpp
26 * This file is part of the DGtal library.
29 #include "DGtal/images/ConstImageAdapter.h"
30 #include "DGtal/io/readers/ITKReader.h"
32 #pragma GCC diagnostic push
33 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
35 #if defined(__clang__)
36 #pragma clang diagnostic push
37 #pragma clang diagnostic ignored "-Wdocumentation"
39 #include <itkImageSeriesReader.h>
40 #include <itkGDCMImageIO.h>
41 #if defined(__clang__)
42 #pragma clang diagnostic pop
45 #pragma GCC diagnostic pop
51 template <typename TFunctor>
52 I ITKDicomReader<I>::importDICOM( const std::vector<std::string> & filenames,
53 const TFunctor & aFunctor )
55 (void)ITK_IO_IMAGE_EXT; //To avoid compiler "not used" warning
56 //when building only this reader.
58 if ( filenames.empty() )
60 trace.error() << "[ITKDicomReader] empty filenames vector passed.";
64 typedef typename Image::Domain Domain;
65 typedef itk::ImageIOBase::IOComponentType IOComponentType;
66 BOOST_CONCEPT_ASSERT( (concepts::CUnaryFunctor<TFunctor, ValueOut, Value>));
67 const IOComponentType componentType =
68 ITKReader<I>::getITKComponentType( filenames[0] );
69 // We suppose all file have the same 'componentType'.
71 switch ( componentType )
75 case itk::ImageIOBase::UNKNOWNCOMPONENTTYPE:
78 << "[ITKDicomReader] Unknown and unsupported component type!";
81 case itk::ImageIOBase::UCHAR:
83 typedef ImageContainerByITKImage<Domain, unsigned char> DGtalITKImage;
84 return readDGtalImageFromITKtypes<DGtalITKImage>( filenames, aFunctor );
86 case itk::ImageIOBase::CHAR:
88 typedef ImageContainerByITKImage<Domain, char> DGtalITKImage;
89 return readDGtalImageFromITKtypes<DGtalITKImage>( filenames, aFunctor );
91 case itk::ImageIOBase::USHORT:
93 typedef ImageContainerByITKImage<Domain, unsigned short> DGtalITKImage;
94 return readDGtalImageFromITKtypes<DGtalITKImage>( filenames, aFunctor );
96 case itk::ImageIOBase::SHORT:
98 typedef ImageContainerByITKImage<Domain, short> DGtalITKImage;
99 return readDGtalImageFromITKtypes<DGtalITKImage>( filenames, aFunctor );
101 case itk::ImageIOBase::UINT:
103 typedef ImageContainerByITKImage<Domain, unsigned int> DGtalITKImage;
104 return readDGtalImageFromITKtypes<DGtalITKImage>( filenames, aFunctor );
106 case itk::ImageIOBase::INT:
108 typedef ImageContainerByITKImage<Domain, int> DGtalITKImage;
109 return readDGtalImageFromITKtypes<DGtalITKImage>( filenames, aFunctor );
111 case itk::ImageIOBase::ULONG:
113 typedef ImageContainerByITKImage<Domain, unsigned long> DGtalITKImage;
114 return readDGtalImageFromITKtypes<DGtalITKImage>( filenames, aFunctor );
116 case itk::ImageIOBase::LONG:
118 typedef ImageContainerByITKImage<Domain, long> DGtalITKImage;
119 return readDGtalImageFromITKtypes<DGtalITKImage>( filenames, aFunctor );
121 #if (ITK_VERSION_MAJOR > 4)\
122 || (ITK_VERSION_MAJOR == 4 && ITK_VERSION_MINOR >= 13)
123 case itk::ImageIOBase::ULONGLONG:
125 typedef ImageContainerByITKImage<Domain, unsigned long long>
127 return readDGtalImageFromITKtypes<DGtalITKImage>( filenames, aFunctor );
129 case itk::ImageIOBase::LONGLONG:
131 typedef ImageContainerByITKImage<Domain, long long> DGtalITKImage;
132 return readDGtalImageFromITKtypes<DGtalITKImage>( filenames, aFunctor );
135 case itk::ImageIOBase::FLOAT:
137 typedef ImageContainerByITKImage<Domain, float> DGtalITKImage;
138 return readDGtalImageFromITKtypes<DGtalITKImage>( filenames, aFunctor );
140 case itk::ImageIOBase::DOUBLE:
142 typedef ImageContainerByITKImage<Domain, double> DGtalITKImage;
143 return readDGtalImageFromITKtypes<DGtalITKImage>( filenames, aFunctor );
149 template <typename I>
150 template <typename Domain, typename PixelType>
152 ImageContainerByITKImage<Domain, PixelType>
154 importDicomFiles(const std::vector<std::string> & filenames)
156 typedef ImageContainerByITKImage<Domain, PixelType> ImageContainer;
158 const unsigned int dimension = Domain::dimension;
159 typedef itk::Image<PixelType, dimension> ItkImage;
160 typedef itk::ImageSeriesReader<ItkImage> ItkReader;
162 //typedef itk::GDCMImageIO ItkImageIO;
164 typedef typename ImageContainer::ITKImagePointer ITKImagePointer;
165 ITKImagePointer itkImage = nullptr;
169 typename ItkReader::Pointer reader = ItkReader::New();
170 //ItkImageIO::Pointer dicomIO = ItkImageIO::New();
171 //reader->SetImageIO( dicomIO );
173 reader->SetFileNames( filenames );
176 itkImage = reader->GetOutput();
178 catch ( itk::ExceptionObject & e )
185 trace.error() << "ITKDicomReader: can't read " << filenames.size()
186 << " files"<<std::endl;
190 const typename ItkImage::SizeType& inputSize =
191 itkImage->GetLargestPossibleRegion().GetSize();
192 const unsigned int width = inputSize[0];
193 const unsigned int height = inputSize[1];
194 const unsigned int depth = inputSize[2];
195 if ( !height || !width || !depth )
197 trace.error() << "ITKDicomReader: one dimension is null (w=" << width
198 << ", h=" << height << ", d=" << depth << ")" << std::endl;
202 const ImageContainer image( itkImage );
208 template <typename I>
209 template <typename Image, typename Domain, typename OrigValue,
210 typename TFunctor, typename Value>
212 ITKDicomReader<I>::Aux<Image, Domain, OrigValue, TFunctor, Value>::
213 readDGtalImageFromITKtypes( const std::vector<std::string> & filenames,
214 const TFunctor & aFunctor )
216 typedef ImageContainerByITKImage<Domain, OrigValue> TypeDGtalImage;
217 TypeDGtalImage dgtalItkImage =
218 importDicomFiles<Domain, OrigValue>( filenames );
220 const Domain& domain = dgtalItkImage.domain();
222 typedef ConstImageAdapter<TypeDGtalImage, Domain, functors::Identity,
225 const functors::Identity identityFunctor{};
226 const AdaptedImage adapted( dgtalItkImage, domain, identityFunctor,
229 Image image( domain );
230 std::copy( adapted.constRange().begin(), adapted.constRange().end(),
231 image.range().outputIterator() );
239 template <typename I>
240 template <typename Domain, typename OrigValue, typename TFunctor,
242 ImageContainerByITKImage<Domain, Value>
243 ITKDicomReader<I>::Aux<ImageContainerByITKImage<Domain, Value>, Domain,
244 OrigValue, TFunctor, Value>::
245 readDGtalImageFromITKtypes( const std::vector<std::string> & filenames,
246 const TFunctor & aFunctor )
248 typedef ImageContainerByITKImage<Domain, Value> Image;
250 typedef ImageContainerByITKImage<Domain, OrigValue> TypeDGtalImage;
251 TypeDGtalImage dgtalItkImage =
252 importDicomFiles<Domain, OrigValue>( filenames );
254 const Domain& domain = dgtalItkImage.domain();
256 typedef ConstImageAdapter<TypeDGtalImage, Domain, functors::Identity,
259 const functors::Identity identityFunctor{};
260 const AdaptedImage adapted( dgtalItkImage, domain, identityFunctor,
263 Image image( domain );
264 std::copy( adapted.constRange().begin(), adapted.constRange().end(),
265 image.range().outputIterator() );
267 //copy ITKImage spatial parameters
268 image.getITKImagePointer()->SetOrigin(
269 dgtalItkImage.getITKImagePointer()->GetOrigin() );
270 image.getITKImagePointer()->SetSpacing(
271 dgtalItkImage.getITKImagePointer()->GetSpacing() );
272 image.getITKImagePointer()->SetDirection(
273 dgtalItkImage.getITKImagePointer()->GetDirection() );
279 template <typename I>
280 template <typename TypeDGtalImage, typename TFunctor>
281 typename ITKDicomReader<I>::Image ITKDicomReader<I>::
282 readDGtalImageFromITKtypes( const std::vector<std::string> & filenames,
283 const TFunctor & aFunctor )
285 typedef typename Image::Domain Domain;
286 typedef typename TypeDGtalImage::Value OrigValue;
288 return Aux<Image, Domain, OrigValue, TFunctor, Value>::
289 readDGtalImageFromITKtypes( filenames, aFunctor );