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"
36#pragma clang diagnostic push
37#pragma clang diagnostic ignored "-Wdocumentation"
39#include <itkImageSeriesReader.h>
40#include <itkGDCMImageIO.h>
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 if ( filenames.empty() )
57 trace.error() << "[ITKDicomReader] empty filenames vector passed.";
61 typedef typename Image::Domain Domain;
62 typedef itk::ImageIOBase::IOComponentType IOComponentType;
63 BOOST_CONCEPT_ASSERT( (concepts::CUnaryFunctor<TFunctor, ValueOut, Value>));
64 const IOComponentType componentType =
65 ITKReader<I>::getITKComponentType( filenames[0] );
66 // We suppose all file have the same 'componentType'.
68 switch ( componentType )
72 case itk::ImageIOBase::UNKNOWNCOMPONENTTYPE:
75 << "[ITKDicomReader] Unknown and unsupported component type!";
78 case itk::ImageIOBase::UCHAR:
80 typedef ImageContainerByITKImage<Domain, unsigned char> DGtalITKImage;
81 return readDGtalImageFromITKtypes<DGtalITKImage>( filenames, aFunctor );
83 case itk::ImageIOBase::CHAR:
85 typedef ImageContainerByITKImage<Domain, char> DGtalITKImage;
86 return readDGtalImageFromITKtypes<DGtalITKImage>( filenames, aFunctor );
88 case itk::ImageIOBase::USHORT:
90 typedef ImageContainerByITKImage<Domain, unsigned short> DGtalITKImage;
91 return readDGtalImageFromITKtypes<DGtalITKImage>( filenames, aFunctor );
93 case itk::ImageIOBase::SHORT:
95 typedef ImageContainerByITKImage<Domain, short> DGtalITKImage;
96 return readDGtalImageFromITKtypes<DGtalITKImage>( filenames, aFunctor );
98 case itk::ImageIOBase::UINT:
100 typedef ImageContainerByITKImage<Domain, unsigned int> DGtalITKImage;
101 return readDGtalImageFromITKtypes<DGtalITKImage>( filenames, aFunctor );
103 case itk::ImageIOBase::INT:
105 typedef ImageContainerByITKImage<Domain, int> DGtalITKImage;
106 return readDGtalImageFromITKtypes<DGtalITKImage>( filenames, aFunctor );
108 case itk::ImageIOBase::ULONG:
110 typedef ImageContainerByITKImage<Domain, unsigned long> DGtalITKImage;
111 return readDGtalImageFromITKtypes<DGtalITKImage>( filenames, aFunctor );
113 case itk::ImageIOBase::LONG:
115 typedef ImageContainerByITKImage<Domain, long> DGtalITKImage;
116 return readDGtalImageFromITKtypes<DGtalITKImage>( filenames, aFunctor );
118#if (ITK_VERSION_MAJOR > 4)\
119 || (ITK_VERSION_MAJOR == 4 && ITK_VERSION_MINOR >= 13)
120 case itk::ImageIOBase::ULONGLONG:
122 typedef ImageContainerByITKImage<Domain, unsigned long long>
124 return readDGtalImageFromITKtypes<DGtalITKImage>( filenames, aFunctor );
126 case itk::ImageIOBase::LONGLONG:
128 typedef ImageContainerByITKImage<Domain, long long> DGtalITKImage;
129 return readDGtalImageFromITKtypes<DGtalITKImage>( filenames, aFunctor );
132 case itk::ImageIOBase::FLOAT:
134 typedef ImageContainerByITKImage<Domain, float> DGtalITKImage;
135 return readDGtalImageFromITKtypes<DGtalITKImage>( filenames, aFunctor );
137 case itk::ImageIOBase::DOUBLE:
139 typedef ImageContainerByITKImage<Domain, double> DGtalITKImage;
140 return readDGtalImageFromITKtypes<DGtalITKImage>( filenames, aFunctor );
146 template <typename I>
147 template <typename Domain, typename PixelType>
149 ImageContainerByITKImage<Domain, PixelType>
151 importDicomFiles(const std::vector<std::string> & filenames)
153 typedef ImageContainerByITKImage<Domain, PixelType> ImageContainer;
155 const unsigned int dimension = Domain::dimension;
156 typedef itk::Image<PixelType, dimension> ItkImage;
157 typedef itk::ImageSeriesReader<ItkImage> ItkReader;
159 //typedef itk::GDCMImageIO ItkImageIO;
161 typedef typename ImageContainer::ITKImagePointer ITKImagePointer;
162 ITKImagePointer itkImage = nullptr;
166 typename ItkReader::Pointer reader = ItkReader::New();
167 //ItkImageIO::Pointer dicomIO = ItkImageIO::New();
168 //reader->SetImageIO( dicomIO );
170 reader->SetFileNames( filenames );
173 itkImage = reader->GetOutput();
175 catch ( itk::ExceptionObject & e )
182 trace.error() << "ITKDicomReader: can't read " << filenames.size()
183 << " files"<<std::endl;
187 const typename ItkImage::SizeType& inputSize =
188 itkImage->GetLargestPossibleRegion().GetSize();
189 const unsigned int width = inputSize[0];
190 const unsigned int height = inputSize[1];
191 const unsigned int depth = inputSize[2];
192 if ( !height || !width || !depth )
194 trace.error() << "ITKDicomReader: one dimension is null (w=" << width
195 << ", h=" << height << ", d=" << depth << ")" << std::endl;
199 const ImageContainer image( itkImage );
205 template <typename I>
206 template <typename Image, typename Domain, typename OrigValue,
207 typename TFunctor, typename Value>
209 ITKDicomReader<I>::Aux<Image, Domain, OrigValue, TFunctor, Value>::
210 readDGtalImageFromITKtypes( const std::vector<std::string> & filenames,
211 const TFunctor & aFunctor )
213 typedef ImageContainerByITKImage<Domain, OrigValue> TypeDGtalImage;
214 TypeDGtalImage dgtalItkImage =
215 importDicomFiles<Domain, OrigValue>( filenames );
217 const Domain& domain = dgtalItkImage.domain();
219 typedef ConstImageAdapter<TypeDGtalImage, Domain, functors::Identity,
222 const functors::Identity identityFunctor{};
223 const AdaptedImage adapted( dgtalItkImage, domain, identityFunctor,
226 Image image( domain );
227 std::copy( adapted.constRange().begin(), adapted.constRange().end(),
228 image.range().outputIterator() );
236 template <typename I>
237 template <typename Domain, typename OrigValue, typename TFunctor,
239 ImageContainerByITKImage<Domain, Value>
240 ITKDicomReader<I>::Aux<ImageContainerByITKImage<Domain, Value>, Domain,
241 OrigValue, TFunctor, Value>::
242 readDGtalImageFromITKtypes( const std::vector<std::string> & filenames,
243 const TFunctor & aFunctor )
245 typedef ImageContainerByITKImage<Domain, Value> Image;
247 typedef ImageContainerByITKImage<Domain, OrigValue> TypeDGtalImage;
248 TypeDGtalImage dgtalItkImage =
249 importDicomFiles<Domain, OrigValue>( filenames );
251 const Domain& domain = dgtalItkImage.domain();
253 typedef ConstImageAdapter<TypeDGtalImage, Domain, functors::Identity,
256 const functors::Identity identityFunctor{};
257 const AdaptedImage adapted( dgtalItkImage, domain, identityFunctor,
260 Image image( domain );
261 std::copy( adapted.constRange().begin(), adapted.constRange().end(),
262 image.range().outputIterator() );
264 //copy ITKImage spatial parameters
265 image.getITKImagePointer()->SetOrigin(
266 dgtalItkImage.getITKImagePointer()->GetOrigin() );
267 image.getITKImagePointer()->SetSpacing(
268 dgtalItkImage.getITKImagePointer()->GetSpacing() );
269 image.getITKImagePointer()->SetDirection(
270 dgtalItkImage.getITKImagePointer()->GetDirection() );
276 template <typename I>
277 template <typename TypeDGtalImage, typename TFunctor>
278 typename ITKDicomReader<I>::Image ITKDicomReader<I>::
279 readDGtalImageFromITKtypes( const std::vector<std::string> & filenames,
280 const TFunctor & aFunctor )
282 typedef typename Image::Domain Domain;
283 typedef typename TypeDGtalImage::Value OrigValue;
285 return Aux<Image, Domain, OrigValue, TFunctor, Value>::
286 readDGtalImageFromITKtypes( filenames, aFunctor );