From: tbaudier Date: Thu, 28 Feb 2019 13:25:04 +0000 (+0100) Subject: Add clitkImage2Dicom tool X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?p=clitk.git;a=commitdiff_plain;h=b50c4ae3e2850ad593d2c991b56e04ed22748f99 Add clitkImage2Dicom tool The difference with clitkWriteDicomSerie is that the number of slice can be different between the input image and the input dicom --- diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 0a044fe..34bb132 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -104,7 +104,12 @@ if(CLITK_BUILD_TOOLS) add_executable(clitkWriteDicomSeries clitkWriteDicomSeries.cxx ${clitkWriteDicomSeries_GGO_C}) target_link_libraries(clitkWriteDicomSeries clitkCommon ) set(TOOLS_INSTALL ${TOOLS_INSTALL} clitkWriteDicomSeries) - + + WRAP_GGO(clitkImage2Dicom_GGO_C clitkImage2Dicom.ggo) + add_executable(clitkImage2Dicom clitkImage2Dicom.cxx ${clitkImage2Dicom_GGO_C}) + target_link_libraries(clitkImage2Dicom clitkCommon ) + set(TOOLS_INSTALL ${TOOLS_INSTALL} clitkImage2Dicom) + WRAP_GGO(clitkSpect2Dicom_GGO_C clitkSpect2Dicom.ggo) add_executable(clitkSpect2Dicom clitkSpect2Dicom.cxx ${clitkSpect2Dicom_GGO_C}) target_link_libraries(clitkSpect2Dicom clitkCommon ) diff --git a/tools/clitkImage2Dicom.cxx b/tools/clitkImage2Dicom.cxx new file mode 100644 index 0000000..cebeb02 --- /dev/null +++ b/tools/clitkImage2Dicom.cxx @@ -0,0 +1,53 @@ +/*========================================================================= + Program: vv http://www.creatis.insa-lyon.fr/rio/vv + + Authors belong to: + - University of LYON http://www.universite-lyon.fr/ + - Léon Bérard cancer center http://www.centreleonberard.fr + - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the copyright notices for more information. + + It is distributed under dual licence + + - BSD See included LICENSE.txt file + - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html +===========================================================================**/ + +/* ================================================= + * @file clitkImage2Dicom.cxx + * @author Thomas B + * @date 2018 + * + * @brief Write a volume into a series with the header of another series + * + ===================================================*/ + + +// clitk +#include "clitkImage2Dicom_ggo.h" +#include "clitkIO.h" +#include "clitkImage2DicomGenericFilter.h" +#include "clitkCommon.h" + +//-------------------------------------------------------------------- +int main(int argc, char * argv[]) +{ + + // Init command line + GGO(clitkImage2Dicom, args_info); + CLITK_INIT; + + // Filter + typedef clitk::Image2DicomGenericFilter FilterType; + FilterType::Pointer genericFilter = FilterType::New(); + + genericFilter->SetArgsInfo(args_info); + genericFilter->Update(); + + return EXIT_SUCCESS; +}// end main + +//-------------------------------------------------------------------- diff --git a/tools/clitkImage2Dicom.ggo b/tools/clitkImage2Dicom.ggo new file mode 100644 index 0000000..d790cbf --- /dev/null +++ b/tools/clitkImage2Dicom.ggo @@ -0,0 +1,12 @@ +#File clitkImage2Dicom.ggo +package "clitkImage2Dicom" +version "1.0" +purpose "Convert the 3D mhd input image (int image) into a 3D dicom (outputDcm) based on the dictionary of the dicoms in inputDcm. The number of slice between the input and the inputDcm could be different" + +option "config" - "Config file" string no +option "verbose" v "Verbose" flag off + +option "input" i "Input image filename" string no +option "inputDcm" d "Input dicom filename" string no +option "outputDcm" o "Output dicom filename" string no + diff --git a/tools/clitkImage2DicomGenericFilter.cxx b/tools/clitkImage2DicomGenericFilter.cxx new file mode 100644 index 0000000..641681c --- /dev/null +++ b/tools/clitkImage2DicomGenericFilter.cxx @@ -0,0 +1,39 @@ +/*========================================================================= + Program: vv http://www.creatis.insa-lyon.fr/rio/vv + + Authors belong to: + - University of LYON http://www.universite-lyon.fr/ + - Léon Bérard cancer center http://www.centreleonberard.fr + - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the copyright notices for more information. + + It is distributed under dual licence + + - BSD See included LICENSE.txt file + - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html +===========================================================================**/ +#ifndef clitkImage2DicomGenericFilter_cxx +#define clitkImage2DicomGenericFilter_cxx + +/* ================================================= + * @file clitkImage2DicomGenericFilter.cxx + * @author + * @date + * + * @brief + * + ===================================================*/ + +#include "clitkImage2DicomGenericFilter.h" + + +namespace clitk +{ + + +} //end clitk + +#endif //#define clitkImage2DicomGenericFilter_cxx diff --git a/tools/clitkImage2DicomGenericFilter.h b/tools/clitkImage2DicomGenericFilter.h new file mode 100644 index 0000000..3e47a34 --- /dev/null +++ b/tools/clitkImage2DicomGenericFilter.h @@ -0,0 +1,152 @@ +/*========================================================================= + Program: vv http://www.creatis.insa-lyon.fr/rio/vv + + Authors belong to: + - University of LYON http://www.universite-lyon.fr/ + - Léon Bérard cancer center http://www.centreleonberard.fr + - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the copyright notices for more information. + + It is distributed under dual licence + + - BSD See included LICENSE.txt file + - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html +===========================================================================**/ +#ifndef clitkImage2DicomGenericFilter_h +#define clitkImage2DicomGenericFilter_h + +/* ================================================= + * @file clitkImage2DicomGenericFilter.h + * @author + * @date + * + * @brief + * + ===================================================*/ + + +// clitk include +#include "clitkIO.h" +#include "clitkImageCommon.h" +#include "clitkImage2Dicom_ggo.h" + +//itk include +#include "itkLightObject.h" +#include "itkGDCMImageIO.h" +#include "itkMetaDataDictionary.h" +#include "itkGDCMSeriesFileNames.h" +#include "itkImageSeriesReader.h" +#include "itkImageSeriesWriter.h" +#include +#include + +#include "itkImage.h" +#include "itkMinimumMaximumImageFilter.h" + +#include "itkGDCMImageIO.h" +#include "itkGDCMSeriesFileNames.h" +#include "itkNumericSeriesFileNames.h" + +#include "itkImageSeriesReader.h" +#include "itkImageSeriesWriter.h" + +#include "itkResampleImageFilter.h" + +#if ( ( ITK_VERSION_MAJOR == 4 ) && ( ITK_VERSION_MINOR < 6 ) ) +#include "itkShiftScaleImageFilter.h" +#endif + +#include "itkIdentityTransform.h" +#include "itkLinearInterpolateImageFunction.h" + +#include + +#if ITK_VERSION_MAJOR >= 4 +#include "gdcmUIDGenerator.h" +#else +#include "gdcm/src/gdcmFile.h" +#include "gdcm/src/gdcmUtil.h" +#endif + +#include +#include + +namespace clitk +{ + template + class ITK_EXPORT Image2DicomGenericFilter : public itk::LightObject + { + public: + //---------------------------------------- + // ITK + //---------------------------------------- + typedef Image2DicomGenericFilter Self; + typedef itk::LightObject Superclass; + typedef itk::SmartPointer Pointer; + typedef itk::SmartPointer ConstPointer; + + // Method for creation through the object factory + itkNewMacro(Self); + + // Run-time type information (and related methods) + itkTypeMacro( Image2DicomGenericFilter, LightObject ); + + + //---------------------------------------- + // Typedefs + //---------------------------------------- + + + //---------------------------------------- + // Set & Get + //---------------------------------------- + void SetArgsInfo(const args_info_type & a) + { + m_ArgsInfo=a; + m_Verbose=m_ArgsInfo.verbose_flag; + m_InputFileName=m_ArgsInfo.input_arg; + } + + + //---------------------------------------- + // Update + //---------------------------------------- + void Update(); + + protected: + + //---------------------------------------- + // Constructor & Destructor + //---------------------------------------- + Image2DicomGenericFilter(); + ~Image2DicomGenericFilter() {}; + + + //void CopyDictionary (itk::MetaDataDictionary &fromDict, itk::MetaDataDictionary &toDict); + //---------------------------------------- + // Templated members + //---------------------------------------- + template void UpdateWithDim(std::string PixelType); + template void UpdateWithDimAndPixelType(); + + + //---------------------------------------- + // Data members + //---------------------------------------- + args_info_type m_ArgsInfo; + bool m_Verbose; + std::string m_InputFileName; + + }; + + +} // end namespace clitk + +#ifndef ITK_MANUAL_INSTANTIATION +#include "clitkImage2DicomGenericFilter.txx" +#endif + +#endif // #define clitkImage2DicomGenericFilter_h diff --git a/tools/clitkImage2DicomGenericFilter.txx b/tools/clitkImage2DicomGenericFilter.txx new file mode 100644 index 0000000..c58bd2f --- /dev/null +++ b/tools/clitkImage2DicomGenericFilter.txx @@ -0,0 +1,425 @@ +/*========================================================================= + Program: vv http://www.creatis.insa-lyon.fr/rio/vv + + Authors belong to: + - University of LYON http://www.universite-lyon.fr/ + - Léon Bérard cancer center http://www.centreleonberard.fr + - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the copyright notices for more information. + + It is distributed under dual licence + + - BSD See included LICENSE.txt file + - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html +===========================================================================**/ +#ifndef clitkImage2DicomGenericFilter_txx +#define clitkImage2DicomGenericFilter_txx + +/* ================================================= + * @file clitkImage2DicomGenericFilter.txx + * @author + * @date + * + * @brief + * + ===================================================*/ + +#include "itkVersion.h" +#include "itkImage.h" +#include "itkGDCMImageIO.h" +#include "itkGDCMSeriesFileNames.h" +#include "itkNumericSeriesFileNames.h" +#include "itkImageSeriesReader.h" +#include "itkImageSeriesWriter.h" + +#include "itkThresholdImageFilter.h" + +#if ( ( ITK_VERSION_MAJOR == 4 ) && ( ITK_VERSION_MINOR < 6 ) ) +#include "itkShiftScaleImageFilter.h" +#endif + +#include +#include +#if GDCM_MAJOR_VERSION >= 2 +#include +#include +#include +#include +#include +#include +#include +#else +#include "gdcmFile.h" +#include "gdcmUtil.h" +#endif + +namespace clitk +{ + + +//----------------------------------------------------------- +// Constructor +//----------------------------------------------------------- +template +Image2DicomGenericFilter::Image2DicomGenericFilter() +{ + m_Verbose=false; + m_InputFileName=""; +} + + +//----------------------------------------------------------- +// Update +//----------------------------------------------------------- +template +void Image2DicomGenericFilter::Update() +{ + // Read the Dimension and PixelType + int Dimension; + std::string PixelType; + ReadImageDimensionAndPixelType(m_InputFileName, Dimension, PixelType); + + + // Call UpdateWithDim + if(Dimension==2) UpdateWithDim<2>(PixelType); + else if(Dimension==3) UpdateWithDim<3>(PixelType); + // else if (Dimension==4)UpdateWithDim<4>(PixelType); + else { + std::cout<<"Error, Only for 2 or 3 Dimensions!!!"< +template +void +Image2DicomGenericFilter::UpdateWithDim(std::string PixelType) +{ + if (m_Verbose) std::cout << "Image was detected to be "<(); + } + else if(PixelType == "unsigned_short"){ + if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_short..." << std::endl; + UpdateWithDimAndPixelType(); + } + + else if (PixelType == "unsigned_char") { + if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_char..." << std::endl; + UpdateWithDimAndPixelType(); + } + + // else if (PixelType == "char"){ + // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and signed_char..." << std::endl; + // UpdateWithDimAndPixelType(); + // } + else if (PixelType == "double") { + if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and double..." << std::endl; + UpdateWithDimAndPixelType(); + } + else { + if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and float..." << std::endl; + UpdateWithDimAndPixelType(); + } +} + +//------------------------------------------------------------------- +// Update with the number of dimensions and the pixeltype read from +// the dicom files. The MHD files may be resampled to match the +// dicom spacing (and number of slices). Rounding errors in resampling +// are handled by removing files when generating the output dicom +// series. +//------------------------------------------------------------------- +template +template +void +Image2DicomGenericFilter::UpdateWithDimAndPixelType() +{ + // Validate input parameters + + const unsigned int InputDimension = Dimension; + const unsigned int OutputDimension = Dimension-1; + + typedef itk::Image< PixelType, InputDimension > InputImageType; + typedef itk::Image< PixelType, OutputDimension > OutputImageType; + typedef itk::ImageSeriesReader< InputImageType > ReaderType; + typedef itk::GDCMImageIO ImageIOType; +#if ( ( ITK_VERSION_MAJOR == 4 ) && ( ITK_VERSION_MINOR < 6 ) ) + typedef itk::ShiftScaleImageFilter< InputImageType, InputImageType > ShiftScaleType; +#endif + typedef itk::ImageSeriesWriter< InputImageType, OutputImageType > SeriesWriterType; + +//////////////////////////////////////////////// +// 1) Read the input series + +// Read the input (MHD file) + typedef typename InputImageType::RegionType RegionType; + typedef typename RegionType::SizeType SizeType; + typedef itk::ImageFileReader InputReaderType; + typename InputReaderType::Pointer volumeReader = InputReaderType::New(); + volumeReader->SetFileName(m_ArgsInfo.input_arg); + volumeReader->Update(); + typename InputImageType::Pointer input = volumeReader->GetOutput(); + typedef itk::NumericSeriesFileNames OutputNamesGeneratorType; + + ImageIOType::Pointer gdcmIO = ImageIOType::New(); + gdcmIO->LoadPrivateTagsOn(); + typename ReaderType::FileNamesContainer filenames; + filenames.push_back(m_ArgsInfo.inputDcm_arg); + typename ReaderType::Pointer reader = ReaderType::New(); + reader->SetImageIO(gdcmIO); + reader->SetFileNames(filenames); + try { + reader->Update(); + } catch (itk::ExceptionObject &excp) { + std::cerr << "Exception thrown while reading the series" << std::endl; + std::cerr << excp << std::endl; + return; + } + + typename InputImageType::SpacingType outputSpacing; + typename InputImageType::SizeType outputSize; + for (unsigned int i = 0; i < 3; i++) { + outputSpacing[i] = input->GetSpacing()[i]; + outputSize[i] = input->GetLargestPossibleRegion().GetSize()[i]; + } + +//////////////////////////////////////////////// +// 2) Ensure to have value >= -1024 + + typedef itk::ThresholdImageFilter ThresholdImageFilterType; + typename ThresholdImageFilterType::Pointer thresholdFilter = ThresholdImageFilterType::New(); + thresholdFilter->SetInput(input); + thresholdFilter->ThresholdBelow(-1024); + thresholdFilter->SetOutsideValue(-1024); + thresholdFilter->Update(); + + input=thresholdFilter->GetOutput(); + +//////////////////////////////////////////////// +// 3) Create a MetaDataDictionary for each slice. + + // Copy the dictionary from the first image and override slice + // specific fields + typename ReaderType::DictionaryRawPointer inputDict = (*(reader->GetMetaDataDictionaryArray()))[0]; + typename ReaderType::DictionaryArrayType outputArray; + + // To keep the new series in the same study as the original we need + // to keep the same study UID. But we need new series and frame of + // reference UID's. +#if ITK_VERSION_MAJOR >= 4 + gdcm::UIDGenerator suid; + std::string seriesUID = suid.Generate(); + gdcm::UIDGenerator fuid; + std::string frameOfReferenceUID = fuid.Generate(); +#else + std::string seriesUID = gdcm::Util::CreateUniqueUID( gdcmIO->GetUIDPrefix()); + std::string frameOfReferenceUID = gdcm::Util::CreateUniqueUID( gdcmIO->GetUIDPrefix()); +#endif + std::string studyUID; + std::string sopClassUID; + itk::ExposeMetaData(*inputDict, "0020|000d", studyUID); + itk::ExposeMetaData(*inputDict, "0008|0016", sopClassUID); + gdcmIO->KeepOriginalUIDOn(); + for (unsigned int f = 0; f < outputSize[2]; f++) + { + // Create a new dictionary for this slice + typename ReaderType::DictionaryRawPointer dict = new typename ReaderType::DictionaryType; + + typedef itk::MetaDataDictionary DictionaryType; + + DictionaryType::ConstIterator itrDic = (*inputDict).Begin(); + DictionaryType::ConstIterator endDic = (*inputDict).End(); + typedef itk::MetaDataObject< std::string > MetaDataStringType; + + while( itrDic != endDic ) + { + itk::MetaDataObjectBase::Pointer entry = itrDic->second; + + MetaDataStringType::Pointer entryvalue = + dynamic_cast( entry.GetPointer() ) ; + if( entryvalue ) + { + std::string tagkey = itrDic->first; + std::string tagvalue = entryvalue->GetMetaDataObjectValue(); + itk::EncapsulateMetaData(*dict, tagkey, tagvalue); + } + ++itrDic; + } + + // Set the UID's for the study, series, SOP and frame of reference + itk::EncapsulateMetaData(*dict,"0020|000d", studyUID); + itk::EncapsulateMetaData(*dict,"0020|000e", seriesUID); + itk::EncapsulateMetaData(*dict,"0020|0052", frameOfReferenceUID); + + #if ITK_VERSION_MAJOR >= 4 + gdcm::UIDGenerator sopuid; + std::string sopInstanceUID = sopuid.Generate(); + #else + std::string sopInstanceUID = gdcm::Util::CreateUniqueUID( gdcmIO->GetUIDPrefix()); + #endif + itk::EncapsulateMetaData(*dict,"0008|0018", sopInstanceUID); + itk::EncapsulateMetaData(*dict,"0002|0003", sopInstanceUID); + + // Change fields that are slice specific + std::ostringstream value; + value.str(""); + value << f + 1; + // Image Number + itk::EncapsulateMetaData(*dict,"0020|0013", value.str()); + + // Series Description - Append new description to current series + // description + std::string oldSeriesDesc; + itk::ExposeMetaData(*inputDict, "0008|103e", oldSeriesDesc); + + value.str(""); + value << oldSeriesDesc + << ": Resampled with pixel spacing " + << outputSpacing[0] << ", " + << outputSpacing[1] << ", " + << outputSpacing[2]; + // This is an long string and there is a 64 character limit in the + // standard + unsigned lengthDesc = value.str().length(); + + std::string seriesDesc( value.str(), 0, + lengthDesc > 64 ? 64 + : lengthDesc); + itk::EncapsulateMetaData(*dict,"0008|103e", seriesDesc); + + // Series Number + value.str(""); + value << 1001; + itk::EncapsulateMetaData(*dict,"0020|0011", value.str()); + + // Derivation Description - How this image was derived + value.str(""); + + + + + + value << ": " << ITK_SOURCE_VERSION; + + lengthDesc = value.str().length(); + std::string derivationDesc( value.str(), 0, + lengthDesc > 1024 ? 1024 + : lengthDesc); + itk::EncapsulateMetaData(*dict,"0008|2111", derivationDesc); + + // Image Position Patient: This is calculated by computing the + // physical coordinate of the first pixel in each slice. + typename InputImageType::PointType position; + typename InputImageType::IndexType index; + index[0] = 0; + index[1] = 0; + index[2] = f; + input->TransformIndexToPhysicalPoint(index, position); + + value.str(""); + value << position[0] << "\\" << position[1] << "\\" << position[2]; + itk::EncapsulateMetaData(*dict,"0020|0032", value.str()); + // Slice Location: For now, we store the z component of the Image + // Position Patient. + value.str(""); + value << position[2]; + itk::EncapsulateMetaData(*dict,"0020|1041", value.str()); + + // Slice Thickness: For now, we store the z spacing + value.str(""); + value << outputSpacing[2]; + itk::EncapsulateMetaData(*dict,"0018|0050", value.str()); + // Spacing Between Slices + itk::EncapsulateMetaData(*dict,"0018|0088", value.str()); + // Save the dictionary + outputArray.push_back(dict); + } + +#if ( ( ITK_VERSION_MAJOR == 4 ) && ( ITK_VERSION_MINOR < 6 ) ) +//////////////////////////////////////////////// +// 4) Shift data to undo the effect of a rescale intercept by the +// DICOM reader + std::string interceptTag("0028|1052"); + typedef itk::MetaDataObject MetaDataStringType; + itk::MetaDataObjectBase::Pointer entry = (*inputDict)[interceptTag]; + + MetaDataStringType::ConstPointer interceptValue = + dynamic_cast(entry.GetPointer()); + + int interceptShift = 0; + if(interceptValue ) { + std::string tagValue = interceptValue->GetMetaDataObjectValue(); + interceptShift = -atoi (tagValue.c_str()); + } + + ShiftScaleType::Pointer shiftScale = ShiftScaleType::New(); + shiftScale->SetInput(resampler->GetOutput()); + shiftScale->SetShift(interceptShift ); +#endif + +//////////////////////////////////////////////// +// 5) Write the new DICOM series + // Generate the file names + typename ReaderType::FileNamesContainer fileNamesOutput; + + // Generate the file names + OutputNamesGeneratorType::Pointer outputNames = OutputNamesGeneratorType::New(); + std::string seriesFormat(m_ArgsInfo.outputDcm_arg); + seriesFormat = seriesFormat + "/" + "IM%d.dcm"; + outputNames->SetSeriesFormat(seriesFormat.c_str()); + outputNames->SetStartIndex(1); + outputNames->SetEndIndex(outputSize[2]); + + typename SeriesWriterType::Pointer seriesWriter = SeriesWriterType::New(); +#if ( ( ITK_VERSION_MAJOR == 4 ) && ( ITK_VERSION_MINOR < 6 ) ) + seriesWriter->SetInput(input); +#else + seriesWriter->SetInput(input); +#endif + seriesWriter->SetImageIO(gdcmIO); + seriesWriter->SetFileNames(outputNames->GetFileNames()); + seriesWriter->SetMetaDataDictionaryArray(&outputArray); + try { + seriesWriter->Update(); + } catch(itk::ExceptionObject & excp) { + std::cerr << "Exception thrown while writing the series " << std::endl; + std::cerr << excp << std::endl; + return; + } +/* +//////////////////////////////////////////////// +// 5) Read the new dicom data tag and copy it in the model data tag to have all dicom tags + gdcm::Reader readerModel, readerOutput; + readerModel.SetFileName(filenames[0].c_str()); + readerOutput.SetFileName(fileNamesOutput[0].c_str()); + readerModel.Read(); + readerOutput.Read(); + gdcm::File &fileModel = readerModel.GetFile(); + gdcm::File &fileOutput = readerOutput.GetFile(); + gdcm::DataSet &dsModel = fileModel.GetDataSet(); + gdcm::DataSet &dsOutput = fileOutput.GetDataSet(); + const unsigned int ptr_len = 42; + char *ptr = new char[ptr_len]; + memset(ptr,0,ptr_len); + + const gdcm::DataElement &dataOutput = dsOutput.GetDataElement(gdcm::Tag(0x7fe0, 0x10)); + dsModel.Replace(dataOutput); + gdcm::Writer w; + w.SetFile(fileModel); + w.SetFileName(fileNamesOutput[0].c_str()); + w.Write(); + return; +*/ +} +}//end clitk + +#endif //#define clitkImage2DicomGenericFilter_txx