[Insight-users] I thought this code might help someone; it shows how to change a MetaDataDictionaryArray when dealing with changing header info in Dicom series.
John Drozd
john.drozd at gmail.com
Thu Oct 28 20:09:49 EDT 2010
Hi,
Since this is not shown in the ITK software guide,
I thought this code that I wrote based on
http://www.paraview.org/Bug/view.php?id=6258&nbn=1 , might help someone:
It shows how to change a MetaDataDictionaryArray when dealing with changing
header info in Dicom series.
Thanks,
John
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif
#ifdef __BORLANDC__
#define ITK_LEAN_AND_MEAN
#endif
//
// This example illustrates how to change a MetaDataDictionaryArray.
// This example illustrates how to read two DICOM series, adds key
// tags that are in the second DICOM series to the first DICOM series
// and write it back with some changed header information as another
// DICOM series. This can be useful when sometimes conversion between
// different file formats as between NIFTI and DICOM and some dicom tags
// are lost.
// The keys are defined in the file
//
// \code{Insight/Utilities/gdcm/Dicts/dicomV3.dic}
//
// Please note that modifying the content of a DICOM header is a very risky
// operation. The Header contains fundamental information about the patient
// and therefore its consistency must be protected from any data
corruption.
// Before attempting to modify the DICOM headers of your files, you must
make
// sure that you have a very good reason for doing so, and that you can
ensure
// that this information change will not result in a lower quality of
health
// care to be delivered to the patient.
//
// \index{DICOM!Changing Headers}
//
// Software Guide : BeginLatex
//
// We must start by including the relevant header files. Here we include the
// image reader, image writer, the image, the Meta data dictionary and its
// entries the Meta data objects and the GDCMImageIO. The Meta data
dictionary
// is the data container that stores all the entries from the DICOM header
once
// the DICOM image file is read into an ITK image.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkImage.h"
#include "itkMetaDataDictionary.h"
#include "itkMetaDataObject.h"
#include "itkGDCMImageIO.h"
// Software Guide : EndCodeSnippet
#include <list>
#include <fstream>
#include "itkGDCMImageIO.h"
#include "itkGDCMSeriesFileNames.h"
#include "itkImageSeriesReader.h"
#include "itkImageSeriesWriter.h"
int main(int argc, char* argv[])
{
if( argc < 4 )
{
std::cerr << "Usage: " << argv[0] << " OriginalDicomImageDIR
ProcessedDicomImageDIR OutputDicomImageDIR\n";
//DIR means Directory
return EXIT_FAILURE;
}
typedef unsigned short InputPixelType;
const unsigned int Dimension = 3;
typedef itk::Image< InputPixelType, Dimension > InputImageType;
typedef itk::GDCMSeriesFileNames NamesGeneratorTypeOrig;
NamesGeneratorTypeOrig::Pointer namesGeneratororig =
NamesGeneratorTypeOrig::New();
namesGeneratororig->SetInputDirectory( argv[1] );
typedef itk::Image< InputPixelType, Dimension > ImageTypeOrig;
typedef itk::ImageSeriesReader< ImageTypeOrig > ReaderTypeOrig;
const ReaderTypeOrig::FileNamesContainer & filenamesorig =
namesGeneratororig->GetInputFileNames();
unsigned int numberOfFilenames = filenamesorig.size();
std::cout << numberOfFilenames << std::endl;
for(unsigned int fni = 0; fni<numberOfFilenames; fni++)
{
std::cout << "filename # " << fni << " = ";
std::cout << filenamesorig[fni] << std::endl;
}
typedef itk::GDCMImageIO ImageIOTypeOrig;
ImageIOTypeOrig::Pointer gdcmImageIOorig = ImageIOTypeOrig::New();
//reader->SetImageIO( gdcmImageIOorig );
ReaderTypeOrig::Pointer readerorig = ReaderTypeOrig::New();
readerorig->SetImageIO( gdcmImageIOorig );
readerorig->SetFileNames( filenamesorig );
//end of added code
// Software Guide : BeginLatex
//
// The reading of the image is triggered by invoking \code{Update()} in the
// reader.
//
// Software Guide : EndLatex
try
{
// Software Guide : BeginCodeSnippet
readerorig->Update();
// Software Guide : EndCodeSnippet
}
catch (itk::ExceptionObject & e)
{
std::cerr << "exception in file reader " << std::endl;
std::cerr << e.GetDescription() << std::endl;
std::cerr << e.GetLocation() << std::endl;
return EXIT_FAILURE;
}
typedef itk::Image< InputPixelType, Dimension > InputImageType2;
typedef itk::GDCMSeriesFileNames NamesGeneratorTypeProc;
NamesGeneratorTypeProc::Pointer namesGeneratorproc =
NamesGeneratorTypeProc::New();
namesGeneratorproc->SetInputDirectory( argv[2] );
typedef itk::Image< InputPixelType, Dimension > ImageTypeProc;
typedef itk::ImageSeriesReader< ImageTypeProc > ReaderTypeProc;
const ReaderTypeProc::FileNamesContainer & filenamesproc =
namesGeneratorproc->GetInputFileNames();
numberOfFilenames = filenamesproc.size();
std::cout << numberOfFilenames << std::endl;
for(unsigned int fni = 0; fni<numberOfFilenames; fni++)
{
std::cout << "filename # " << fni << " = ";
std::cout << filenamesproc[fni] << std::endl;
}
typedef itk::GDCMImageIO ImageIOTypeProc;
ImageIOTypeProc::Pointer gdcmImageIOproc = ImageIOTypeProc::New();
ReaderTypeProc::Pointer readerproc = ReaderTypeProc::New();
readerproc->SetImageIO( gdcmImageIOproc );
readerproc->SetFileNames( filenamesproc );
try
{
readerproc->Update();
}
catch (itk::ExceptionObject & e)
{
std::cerr << "exception in file reader " << std::endl;
std::cerr << e.GetDescription() << std::endl;
std::cerr << e.GetLocation() << std::endl;
return EXIT_FAILURE;
}
typedef itk::MetaDataObject< std::string > MetaDataStringType;
typedef itk::MetaDataDictionary DictionaryType1b;
typedef itk::MetaDataDictionary DictionaryType2b;
std::vector<DictionaryType2b*> pdictArray2b;
DictionaryType1b::ConstIterator itr1b;
DictionaryType1b::ConstIterator end1b;
DictionaryType2b::ConstIterator itr2b;
DictionaryType2b::ConstIterator end2b;
for ( unsigned int idx = 0;
idx < readerproc->GetMetaDataDictionaryArray()->size();
idx++ )
{
itk::MetaDataDictionary* pdictionary1b = new
itk::MetaDataDictionary;
itk::MetaDataDictionary* pSrc1b =
(*(readerorig->GetMetaDataDictionaryArray()))[idx];
itk::MetaDataDictionary* pdictionary2b = new
itk::MetaDataDictionary;
itk::MetaDataDictionary* pSrc2b =
(*(readerproc->GetMetaDataDictionaryArray()))[idx];
if ( pSrc2b )
{
*pdictionary1b = (*pSrc1b);
*pdictionary2b = (*pSrc2b);
itr1b = pdictionary1b->Begin();
end1b = pdictionary1b->End();
itr2b = pdictionary2b->Begin();
end2b = pdictionary2b->End();
while( itr1b != end1b )
{
itk::MetaDataObjectBase::Pointer entry1b = itr1b->second;
MetaDataStringType::Pointer entryvalue1b =
dynamic_cast<MetaDataStringType *>( entry1b.GetPointer() );
std::string tagkey1b = itr1b->first;
DictionaryType2b::ConstIterator tagItr2b =
pdictionary2b->Find( tagkey1b );
if( tagItr2b == end2b )
{
std::string tagkey = itr1b->first;
std::string tagvalue = entryvalue1b->GetMetaDataObjectValue();
//std::cout << tagkey << " = " << tagvalue << std::endl;
itk::EncapsulateMetaData<std::string>( *pdictionary2b, tagkey
, tagvalue );
}
++itr1b;
}
std::string entryIdMR = "0008|0060";
std::string valueMR = "MR";
itk::EncapsulateMetaData<std::string>( *pdictionary2b, entryIdMR,
valueMR );
pdictArray2b.push_back( pdictionary2b );
}
}
typedef unsigned short OutputPixelType;
const unsigned int OutputDimension = 2;
typedef itk::Image< OutputPixelType, OutputDimension > Image2DType;
typedef itk::ImageSeriesWriter<
ImageTypeProc, Image2DType > SeriesWriterType;
SeriesWriterType::Pointer seriesWriter = SeriesWriterType::New();
seriesWriter->SetMetaDataDictionaryArray( &pdictArray2b );
seriesWriter->SetInput( readerproc->GetOutput() );
seriesWriter->SetImageIO( gdcmImageIOproc );
namesGeneratorproc->SetOutputDirectory( argv[3] );
seriesWriter->SetFileNames( namesGeneratorproc->GetOutputFileNames() );
try
{
seriesWriter->Update();
}
catch (itk::ExceptionObject & e)
{
std::cerr << "exception in file writer " << std::endl;
std::cerr << e.GetDescription() << std::endl;
std::cerr << e.GetLocation() << std::endl;
return EXIT_FAILURE;
}
// Software Guide : BeginLatex
//
// Remember again, that modifying the header entries of a DICOM file
involves
// very serious risks for patients and therefore must be done with extreme
// caution.
//
// Software Guide : EndLatex
return EXIT_SUCCESS;
}
Thanks,
John
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.itk.org/pipermail/insight-users/attachments/20101028/3bd14dbb/attachment.htm>
More information about the Insight-users
mailing list