1 /*=========================================================================
2 Program: vv http://www.creatis.insa-lyon.fr/rio/vv
5 - University of LYON http://www.universite-lyon.fr/
6 - Léon Bérard cancer center http://www.centreleonberard.fr
7 - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
9 This software is distributed WITHOUT ANY WARRANTY; without even
10 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11 PURPOSE. See the copyright notices for more information.
13 It is distributed under dual licence
15 - BSD See included LICENSE.txt file
16 - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
17 ===========================================================================**/
18 #ifndef clitkImage2DicomSeriesGenericFilter_txx
19 #define clitkImage2DicomSeriesGenericFilter_txx
21 /* =================================================
22 * @file clitkImage2DicomSeriesGenericFilter.txx
28 ===================================================*/
31 #include "clitkResampleImageWithOptionsFilter.h"
32 #if GDCM_MAJOR_VERSION >= 2
33 #include "gdcmUIDGenerator.h"
38 #include "itkVersion.h"
41 #include "itkMinimumMaximumImageFilter.h"
43 #include "itkGDCMImageIO.h"
44 #include "itkGDCMSeriesFileNames.h"
45 #include "itkNumericSeriesFileNames.h"
47 #include "itkImageSeriesReader.h"
48 #include "itkImageSeriesWriter.h"
50 #include "itkResampleImageFilter.h"
52 #if ( ( ITK_VERSION_MAJOR == 4 ) && ( ITK_VERSION_MINOR < 6 ) )
53 #include "itkShiftScaleImageFilter.h"
56 #include "itkIdentityTransform.h"
57 #include "itkLinearInterpolateImageFunction.h"
59 #include <itksys/SystemTools.hxx>
61 #if ITK_VERSION_MAJOR >= 4
62 #include "gdcmUIDGenerator.h"
64 #include "gdcm/src/gdcmFile.h"
65 #include "gdcm/src/gdcmUtil.h"
75 //-----------------------------------------------------------
77 //-----------------------------------------------------------
78 template<class args_info_type>
79 Image2DicomSeriesGenericFilter<args_info_type>::Image2DicomSeriesGenericFilter()
86 //-----------------------------------------------------------
88 //-----------------------------------------------------------
89 template<class args_info_type>
90 void Image2DicomSeriesGenericFilter<args_info_type>::Update()
92 // Read the Dimension and PixelType
94 std::string PixelType;
95 ReadImageDimensionAndPixelType(m_InputFileName, Dimension, PixelType);
99 if(Dimension==2) UpdateWithDim<2>(PixelType);
100 else if(Dimension==3) UpdateWithDim<3>(PixelType);
101 // else if (Dimension==4)UpdateWithDim<4>(PixelType);
103 std::cout<<"Error, Only for 2 or 3 Dimensions!!!"<<std::endl ;
108 //-------------------------------------------------------------------
109 // Update with the number of dimensions
110 //-------------------------------------------------------------------
111 template<class args_info_type>
112 template<unsigned int Dimension>
114 Image2DicomSeriesGenericFilter<args_info_type>::UpdateWithDim(std::string PixelType)
116 if (m_Verbose) std::cout << "Image was detected to be "<<Dimension<<"D and "<< PixelType<<"..."<<std::endl;
118 if(PixelType == "short") {
119 if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and signed short..." << std::endl;
120 UpdateWithDimAndPixelType<Dimension, signed short>();
122 else if(PixelType == "unsigned_short"){
123 if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_short..." << std::endl;
124 UpdateWithDimAndPixelType<Dimension, unsigned short>();
127 else if (PixelType == "unsigned_char") {
128 if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_char..." << std::endl;
129 UpdateWithDimAndPixelType<Dimension, unsigned char>();
132 // else if (PixelType == "char"){
133 // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and signed_char..." << std::endl;
134 // UpdateWithDimAndPixelType<Dimension, signed char>();
136 else if (PixelType == "double") {
137 if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and double..." << std::endl;
138 UpdateWithDimAndPixelType<Dimension, double>();
141 if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and float..." << std::endl;
142 UpdateWithDimAndPixelType<Dimension, float>();
146 //-------------------------------------------------------------------
147 // Update with the number of dimensions and the pixeltype read from
148 // the dicom files. The MHD files may be resampled to match the
149 // dicom spacing (and number of slices). Rounding errors in resampling
150 // are handled by removing files when generating the output dicom
152 //-------------------------------------------------------------------
153 template<class args_info_type>
154 template <unsigned int Dimension, class PixelType>
156 Image2DicomSeriesGenericFilter<args_info_type>::UpdateWithDimAndPixelType()
160 // Resample a DICOM study
161 // Usage: ResampleDICOM InputDirectory OutputDirectory
162 // xSpacing ySpacing zSpacing
164 // Example: ResampleDICOM CT CTResample 0 0 1.5
165 // will read a series from the CT directory and create a
166 // new series in the CTResample directory. The new series
167 // will have the same x,y spacing as the input series, but
168 // will have a z-spacing of 1.5.
171 // ResampleDICOM resamples a DICOM series with user-specified
172 // spacing. The program outputs a new DICOM series with a series
173 // number set to 1001. All non-private DICOM tags are moved from the input
174 // series to the output series. The Image Position Patient is adjusted
175 // for each slice to reflect the z-spacing. The number of slices in
176 // the output series may be larger or smaller due to changes in the
177 // z-spacing. To retain the spacing for a given dimension, specify 0.
179 // The program progresses as follows:
180 // 1) Read the input series
181 // 2) Resample the series according to the user specified x-y-z
183 // 3) Create a MetaDataDictionary for each slice.
184 // 4) Shift data to undo the effect of a rescale intercept by the
185 // DICOM reader (only for ITK < 4.6)
186 // 5) Write the new DICOM series
192 // Validate input parameters
194 const unsigned int InputDimension = 3;
195 const unsigned int OutputDimension = 2;
198 typedef itk::Image< PixelType, InputDimension >
200 typedef itk::Image< PixelType, OutputDimension >
202 typedef itk::ImageSeriesReader< InputImageType >
204 typedef itk::GDCMImageIO
206 typedef itk::GDCMSeriesFileNames
207 InputNamesGeneratorType;
208 typedef itk::NumericSeriesFileNames
209 OutputNamesGeneratorType;
210 typedef itk::IdentityTransform< double, InputDimension >
212 typedef itk::LinearInterpolateImageFunction< InputImageType, double >
214 typedef itk::ResampleImageFilter< InputImageType, InputImageType >
216 #if ( ( ITK_VERSION_MAJOR == 4 ) && ( ITK_VERSION_MINOR < 6 ) )
217 typedef itk::ShiftScaleImageFilter< InputImageType, InputImageType >
220 typedef itk::ImageSeriesWriter< InputImageType, OutputImageType >
223 ////////////////////////////////////////////////
224 // 1) Read the input series
226 // Read the input (MHD file)
227 typedef typename InputImageType::RegionType RegionType;
228 typedef typename RegionType::SizeType SizeType;
229 typedef itk::ImageFileReader<InputImageType> InputReaderType;
230 typename InputReaderType::Pointer volumeReader = InputReaderType::New();
231 volumeReader->SetFileName( m_ArgsInfo.input_arg );
232 volumeReader->Update();
234 typename InputImageType::Pointer input = volumeReader->GetOutput();
236 ImageIOType::Pointer gdcmIO = ImageIOType::New();
237 gdcmIO->LoadPrivateTagsOn();
238 InputNamesGeneratorType::Pointer inputNames = InputNamesGeneratorType::New();
239 inputNames->SetInputDirectory( m_ArgsInfo.inputDir_arg );
241 const typename ReaderType::FileNamesContainer & filenames =
242 inputNames->GetInputFileNames();
244 typename ReaderType::Pointer reader = ReaderType::New();
246 reader->SetImageIO( gdcmIO );
247 reader->SetFileNames( filenames );
252 catch (itk::ExceptionObject &excp)
254 std::cerr << "Exception thrown while reading the series" << std::endl;
255 std::cerr << excp << std::endl;
258 typename InputImageType::SpacingType outputSpacing;
259 typename InputImageType::SizeType outputSize;
260 for (unsigned int i = 0; i < 3; i++)
262 outputSpacing[i] = input->GetSpacing()[i];
263 outputSize[i] = input->GetLargestPossibleRegion().GetSize()[i];
266 ////////////////////////////////////////////////
267 // 2) Resample the series
268 /* typename InterpolatorType::Pointer interpolator = InterpolatorType::New();
270 TransformType::Pointer transform = TransformType::New();
271 transform->SetIdentity();
273 const typename InputImageType::SpacingType& inputSpacing =
274 reader->GetOutput()->GetSpacing();
275 const typename InputImageType::RegionType& inputRegion =
276 reader->GetOutput()->GetLargestPossibleRegion();
277 const typename InputImageType::SizeType& inputSize =
278 inputRegion.GetSize();
280 std::cout << "The input series in directory " << m_ArgsInfo.inputDir_arg
281 << " has " << filenames.size() << " files with spacing "
285 // Compute the size of the output. The user specifies a spacing on
286 // the command line. If the spacing is 0, the input spacing will be
287 // used. The size (# of pixels) in the output is recomputed using
288 // the ratio of the input and output sizes.
289 typename InputImageType::SpacingType outputSpacing;
291 bool changeInSpacing = false;
292 for (unsigned int i = 0; i < 3; i++)
294 outputSpacing[i] = inputSpacing[i];
296 typename InputImageType::SizeType outputSize;
297 typedef typename InputImageType::SizeType::SizeValueType SizeValueType;
298 outputSize[0] = static_cast<SizeValueType>(inputSize[0] * inputSpacing[0] / outputSpacing[0] + .5);
299 outputSize[1] = static_cast<SizeValueType>(inputSize[1] * inputSpacing[1] / outputSpacing[1] + .5);
300 outputSize[2] = static_cast<SizeValueType>(inputSize[2] * inputSpacing[2] / outputSpacing[2] + .5);
302 typename ResampleFilterType::Pointer resampler = ResampleFilterType::New();
303 resampler->SetInput( reader->GetOutput() );
304 resampler->SetTransform( transform );
305 resampler->SetInterpolator( interpolator );
306 resampler->SetOutputOrigin ( reader->GetOutput()->GetOrigin());
307 resampler->SetOutputSpacing ( outputSpacing );
308 resampler->SetOutputDirection ( reader->GetOutput()->GetDirection());
309 resampler->SetSize ( outputSize );
310 resampler->Update ();
314 ////////////////////////////////////////////////
315 // 3) Create a MetaDataDictionary for each slice.
317 // Copy the dictionary from the first image and override slice
319 typename ReaderType::DictionaryRawPointer inputDict = (*(reader->GetMetaDataDictionaryArray()))[0];
320 typename ReaderType::DictionaryArrayType outputArray;
322 // To keep the new series in the same study as the original we need
323 // to keep the same study UID. But we need new series and frame of
325 #if ITK_VERSION_MAJOR >= 4
326 gdcm::UIDGenerator suid;
327 std::string seriesUID = suid.Generate();
328 gdcm::UIDGenerator fuid;
329 std::string frameOfReferenceUID = fuid.Generate();
331 std::string seriesUID = gdcm::Util::CreateUniqueUID( gdcmIO->GetUIDPrefix());
332 std::string frameOfReferenceUID = gdcm::Util::CreateUniqueUID( gdcmIO->GetUIDPrefix());
334 std::string studyUID;
335 std::string sopClassUID;
336 itk::ExposeMetaData<std::string>(*inputDict, "0020|000d", studyUID);
337 itk::ExposeMetaData<std::string>(*inputDict, "0008|0016", sopClassUID);
338 gdcmIO->KeepOriginalUIDOn();
340 for (unsigned int f = 0; f < outputSize[2]; f++)
342 // Create a new dictionary for this slice
343 typename ReaderType::DictionaryRawPointer dict = new typename ReaderType::DictionaryType;
345 // Copy the dictionary from the first slice
346 //CopyDictionary (*inputDict, *dict);
348 typedef itk::MetaDataDictionary DictionaryType;
350 DictionaryType::ConstIterator itrDic = (*inputDict).Begin();
351 DictionaryType::ConstIterator endDic = (*inputDict).End();
352 typedef itk::MetaDataObject< std::string > MetaDataStringType;
354 while( itrDic != endDic )
356 itk::MetaDataObjectBase::Pointer entry = itrDic->second;
358 MetaDataStringType::Pointer entryvalue =
359 dynamic_cast<MetaDataStringType *>( entry.GetPointer() ) ;
362 std::string tagkey = itrDic->first;
363 std::string tagvalue = entryvalue->GetMetaDataObjectValue();
364 itk::EncapsulateMetaData<std::string>(*dict, tagkey, tagvalue);
369 // Set the UID's for the study, series, SOP and frame of reference
370 itk::EncapsulateMetaData<std::string>(*dict,"0020|000d", studyUID);
371 itk::EncapsulateMetaData<std::string>(*dict,"0020|000e", seriesUID);
372 itk::EncapsulateMetaData<std::string>(*dict,"0020|0052", frameOfReferenceUID);
374 #if ITK_VERSION_MAJOR >= 4
375 gdcm::UIDGenerator sopuid;
376 std::string sopInstanceUID = sopuid.Generate();
378 std::string sopInstanceUID = gdcm::Util::CreateUniqueUID( gdcmIO->GetUIDPrefix());
380 itk::EncapsulateMetaData<std::string>(*dict,"0008|0018", sopInstanceUID);
381 itk::EncapsulateMetaData<std::string>(*dict,"0002|0003", sopInstanceUID);
383 // Change fields that are slice specific
384 std::ostringstream value;
386 //unsigned int f = 0;
390 itk::EncapsulateMetaData<std::string>(*dict,"0020|0013", value.str());
392 // Series Description - Append new description to current series
394 std::string oldSeriesDesc;
395 itk::ExposeMetaData<std::string>(*inputDict, "0008|103e", oldSeriesDesc);
398 value << oldSeriesDesc
399 << ": Resampled with pixel spacing "
400 << outputSpacing[0] << ", "
401 << outputSpacing[1] << ", "
403 // This is an long string and there is a 64 character limit in the
405 unsigned lengthDesc = value.str().length();
407 std::string seriesDesc( value.str(), 0,
410 itk::EncapsulateMetaData<std::string>(*dict,"0008|103e", seriesDesc);
415 itk::EncapsulateMetaData<std::string>(*dict,"0020|0011", value.str());
417 // Derivation Description - How this image was derived
420 value << ": " << ITK_SOURCE_VERSION;
422 lengthDesc = value.str().length();
423 std::string derivationDesc( value.str(), 0,
424 lengthDesc > 1024 ? 1024
426 itk::EncapsulateMetaData<std::string>(*dict,"0008|2111", derivationDesc);
428 // Image Position Patient: This is calculated by computing the
429 // physical coordinate of the first pixel in each slice.
430 typename InputImageType::PointType position;
431 typename InputImageType::IndexType index;
435 input->TransformIndexToPhysicalPoint(index, position);
438 value << position[0] << "\\" << position[1] << "\\" << position[2];
439 itk::EncapsulateMetaData<std::string>(*dict,"0020|0032", value.str());
440 // Slice Location: For now, we store the z component of the Image
443 value << position[2];
444 itk::EncapsulateMetaData<std::string>(*dict,"0020|1041", value.str());
447 // Slice Thickness: For now, we store the z spacing
449 value << outputSpacing[2];
450 itk::EncapsulateMetaData<std::string>(*dict,"0018|0050",
452 // Spacing Between Slices
453 itk::EncapsulateMetaData<std::string>(*dict,"0018|0088",
458 value << 0.999987 << "\\" << -0.005061 << "\\" << 0.000000 << "\\" << 0.000000 << "\\" << 0.000000 << "\\" << -1.000000;
459 itk::EncapsulateMetaData<std::string>(*dict, "0020|0037", value.str());
463 itk::EncapsulateMetaData<std::string>(*dict, "0002|0000", value.str());
466 itk::EncapsulateMetaData<std::string>(*dict, "0008|0000", value.str());
469 itk::EncapsulateMetaData<std::string>(*dict, "0009|0000", value.str());
472 itk::EncapsulateMetaData<std::string>(*dict, "0010|0000", value.str());
475 itk::EncapsulateMetaData<std::string>(*dict, "0011|0000", value.str());
477 value << 0 << "\\" << 0;
478 itk::EncapsulateMetaData<std::string>(*dict, "0011|1011", value.str());
480 value << 1 << "\\" << 1;
481 itk::EncapsulateMetaData<std::string>(*dict, "0011|1015", value.str());
483 value << 1 << "\\" << 2;
484 itk::EncapsulateMetaData<std::string>(*dict, "0011|1016", value.str());
486 value << 0 << "\\" << 0;
487 itk::EncapsulateMetaData<std::string>(*dict, "0011|1017", value.str());
489 value << 0 << "\\" << 0;
490 itk::EncapsulateMetaData<std::string>(*dict, "0011|1018", value.str());
492 value << 0 << "\\" << 0;
493 itk::EncapsulateMetaData<std::string>(*dict, "0011|1019", value.str());
495 value << 0 << "\\" << 0;
496 itk::EncapsulateMetaData<std::string>(*dict, "0011|101a", value.str());
498 value << 0 << "\\" << 0;
499 itk::EncapsulateMetaData<std::string>(*dict, "0011|101f", value.str());
501 value << 0 << "\\" << 0;
502 itk::EncapsulateMetaData<std::string>(*dict, "0011|1026", value.str());
504 value << 0 << "\\" << 0 << "\\" << 0 << "\\" << 0;
505 itk::EncapsulateMetaData<std::string>(*dict, "0011|1027", value.str());
507 value << 0 << "\\" << 0 << "\\" << 0 << "\\" << 0;
508 itk::EncapsulateMetaData<std::string>(*dict, "0011|1028", value.str());
510 value << 0 << "\\" << 0;
511 itk::EncapsulateMetaData<std::string>(*dict, "0011|102c", value.str());
513 value << 0 << "\\" << 0;
514 itk::EncapsulateMetaData<std::string>(*dict, "0011|102d", value.str());
516 value << 0 << "\\" << 0;
517 itk::EncapsulateMetaData<std::string>(*dict, "0011|102e", value.str());
518 std::ostringstream valueVec[2];
520 valueVec[0] << 32767;
522 valueVec[1] << 32767;
523 std::string valueVec2[2];
524 valueVec2[0]=valueVec[0].str();
525 valueVec2[1]=valueVec[1].str();
526 itk::EncapsulateMetaData<std::string*>(*dict, "0011|102f", valueVec2);
529 itk::EncapsulateMetaData<std::string>(*dict, "0020|1011", value.str());
532 itk::EncapsulateMetaData<std::string>(*dict, "0028|0107", value.str());
536 itk::EncapsulateMetaData<std::string>(*dict, "0018|1130", value.str());
539 itk::EncapsulateMetaData<std::string>(*dict, "0018|1131", value.str());
542 itk::EncapsulateMetaData<std::string>(*dict, "0018|1140", value.str());
545 itk::EncapsulateMetaData<std::string>(*dict, "0018|1142", value.str());
548 itk::EncapsulateMetaData<std::string>(*dict, "0018|1143", value.str());
551 itk::EncapsulateMetaData<std::string>(*dict, "0018|1144", value.str());
554 itk::EncapsulateMetaData<std::string>(*dict, "0018|1242", value.str());
557 itk::EncapsulateMetaData<std::string>(*dict, "0054|0053", value.str());
560 itk::EncapsulateMetaData<std::string>(*dict, "0054|0200", value.str());
563 itk::EncapsulateMetaData<std::string>(*dict, "0008|0100", value.str());
566 itk::EncapsulateMetaData<std::string>(*dict, "0008|0102", value.str());
568 value << "recumbent" ;
569 itk::EncapsulateMetaData<std::string>(*dict, "0008|0104", value.str());
572 itk::EncapsulateMetaData<std::string>(*dict, "0054|0014", value.str());
575 itk::EncapsulateMetaData<std::string>(*dict, "0054|0015", value.str());
577 value << "Tc99m_SC" ;
578 itk::EncapsulateMetaData<std::string>(*dict, "0054|0018", value.str());
581 itk::EncapsulateMetaData<std::string>(*dict, "0018|1120", value.str());
584 itk::EncapsulateMetaData<std::string>(*dict, "0018|1145", value.str());
586 value << 0 << "\\" << 0;
587 itk::EncapsulateMetaData<std::string>(*dict, "0018|1149", value.str());
590 itk::EncapsulateMetaData<std::string>(*dict, "0018|1180", value.str());
593 itk::EncapsulateMetaData<std::string>(*dict, "0018|1181", value.str());
596 itk::EncapsulateMetaData<std::string>(*dict, "0018|1182", value.str());
599 itk::EncapsulateMetaData<std::string>(*dict, "0018|1183", value.str());
602 itk::EncapsulateMetaData<std::string>(*dict, "0018|1184", value.str());
604 value << 1.000000 << "\\" << 1.000000 ;
605 itk::EncapsulateMetaData<std::string>(*dict, "0028|0031", value.str());
607 value << 0.000000 << "\\" << 0.000000 ;
608 itk::EncapsulateMetaData<std::string>(*dict, "0028|0032", value.str());
611 itk::EncapsulateMetaData<std::string>(*dict, "0011|101c", value.str());
614 itk::EncapsulateMetaData<std::string>(*dict, "0011|101d", value.str());
617 itk::EncapsulateMetaData<std::string>(*dict, "0013|1016", value.str());
620 itk::EncapsulateMetaData<std::string>(*dict, "0013|1017", value.str());
623 itk::EncapsulateMetaData<std::string>(*dict, "0011|1023", value.str());
626 itk::EncapsulateMetaData<std::string>(*dict, "0011|1024", value.str());
629 itk::EncapsulateMetaData<std::string>(*dict, "0011|1025", value.str());
632 itk::EncapsulateMetaData<std::string>(*dict, "0011|1029", value.str());
635 itk::EncapsulateMetaData<std::string>(*dict, "0011|103e", value.str());
638 itk::EncapsulateMetaData<std::string>(*dict, "0013|1018", value.str());
641 itk::EncapsulateMetaData<std::string>(*dict, "0013|1019", value.str());
644 itk::EncapsulateMetaData<std::string>(*dict, "0013|101a", value.str());
646 value << "GEMS_GENIE_1" ;
647 itk::EncapsulateMetaData<std::string>(*dict, "0035|0010", value.str());
650 itk::EncapsulateMetaData<std::string>(*dict, "0035|1001", value.str());
653 // Save the dictionary
654 outputArray.push_back(dict);
657 #if ( ( ITK_VERSION_MAJOR == 4 ) && ( ITK_VERSION_MINOR < 6 ) )
658 ////////////////////////////////////////////////
659 // 4) Shift data to undo the effect of a rescale intercept by the
661 std::string interceptTag("0028|1052");
662 typedef itk::MetaDataObject< std::string > MetaDataStringType;
663 itk::MetaDataObjectBase::Pointer entry = (*inputDict)[interceptTag];
665 MetaDataStringType::ConstPointer interceptValue =
666 dynamic_cast<const MetaDataStringType *>( entry.GetPointer() ) ;
668 int interceptShift = 0;
671 std::string tagValue = interceptValue->GetMetaDataObjectValue();
672 interceptShift = -atoi ( tagValue.c_str() );
675 ShiftScaleType::Pointer shiftScale = ShiftScaleType::New();
676 shiftScale->SetInput( resampler->GetOutput());
677 shiftScale->SetShift( interceptShift );
680 ////////////////////////////////////////////////
681 // 5) Write the new DICOM series
683 // Make the output directory and generate the file names.
684 itksys::SystemTools::MakeDirectory( m_ArgsInfo.outputDir_arg );
686 // Generate the file names
687 OutputNamesGeneratorType::Pointer outputNames = OutputNamesGeneratorType::New();
688 std::string seriesFormat(m_ArgsInfo.outputDir_arg);
689 seriesFormat = seriesFormat + "/" + "IM%d.dcm";
690 outputNames->SetSeriesFormat (seriesFormat.c_str());
691 outputNames->SetStartIndex (1);
692 //outputNames->SetEndIndex (1);
693 outputNames->SetEndIndex (outputSize[2]);
695 typename SeriesWriterType::Pointer seriesWriter = SeriesWriterType::New();
696 #if ( ( ITK_VERSION_MAJOR == 4 ) && ( ITK_VERSION_MINOR < 6 ) )
697 seriesWriter->SetInput( input );
699 seriesWriter->SetInput( input );
701 seriesWriter->SetImageIO( gdcmIO );
702 seriesWriter->SetFileNames( outputNames->GetFileNames() );
703 seriesWriter->SetMetaDataDictionaryArray( &outputArray );
706 seriesWriter->Update();
708 catch( itk::ExceptionObject & excp )
710 std::cerr << "Exception thrown while writing the series " << std::endl;
711 std::cerr << excp << std::endl;
714 std::cout << "The output series in directory " << m_ArgsInfo.outputDir_arg
715 << " has " << outputSize[2] << " files with spacing "
722 /*void CopyDictionary (itk::MetaDataDictionary &fromDict, itk::MetaDataDictionary &toDict)
724 typedef itk::MetaDataDictionary DictionaryType;
726 DictionaryType::ConstIterator itr = fromDict.Begin();
727 DictionaryType::ConstIterator end = fromDict.End();
728 typedef itk::MetaDataObject< std::string > MetaDataStringType;
732 itk::MetaDataObjectBase::Pointer entry = itr->second;
734 MetaDataStringType::Pointer entryvalue =
735 dynamic_cast<MetaDataStringType *>( entry.GetPointer() ) ;
738 std::string tagkey = itr->first;
739 std::string tagvalue = entryvalue->GetMetaDataObjectValue();
740 itk::EncapsulateMetaData<std::string>(toDict, tagkey, tagvalue);
749 #endif //#define clitkImage2DicomSeriesGenericFilter_txx