Dear all,<br><br>I'm trying to make a simple function that translates a dicom volume by a certain amount.<br>It first opens all dicom slides of an mri scan.<br><br>To do this, I pasted DicomSeriesReadImageWrite2.cxx and ResampleImageFilter.cxx and adjusted<br>
the latter so it accepts 3 dimensions instead of two and uses integer instead of unsigned char.<br><br>The function compiles and a .vtk volume is written. However, there's no image data in the file.<br>It does display all pixels with value 100, as I set by: filter->SetDefaultPixelValue( 100 );<br>
<br>questions:<br>1) am I too naive to think that the ResampleImageFilter can easily be extended from 2 to 3 dimensions?<br>2) if not, what did I do wrong?<br><br>I pasted the source code below.<br><br>//////////////////////////////////////////////////////////////////////////////////////////////////<br>
#if defined(_MSC_VER)<br>#pragma warning ( disable : 4786 )<br>#endif<br><br>#ifdef __BORLANDC__<br>#define ITK_LEAN_AND_MEAN<br>#endif<br><br>#include "itkOrientedImage.h"<br>#include "itkGDCMImageIO.h"<br>
#include "itkGDCMSeriesFileNames.h"<br>#include "itkImageSeriesReader.h"<br>#include "itkImageFileWriter.h"<br>#include "itkResampleImageFilter.h"<br><br>#include "itkAffineTransform.h"<br>
#include "itkNearestNeighborInterpolateImageFunction.h"<br>// Software Guide : EndCodeSnippet<br><br>int main( int argc, char* argv[] )<br>{<br><br> if( argc < 3 )<br> {<br> std::cerr << "Usage: " << std::endl;<br>
std::cerr << argv[0] << " DicomDirectory outputFileName [seriesName]" <br> << std::endl;<br> return EXIT_FAILURE;<br> }<br><br> typedef signed short PixelType;<br>
const unsigned int Dimension = 3;<br>
<br> typedef itk::OrientedImage< PixelType, Dimension > ImageType;<br><br> typedef itk::ImageSeriesReader< ImageType > ReaderType;<br> ReaderType::Pointer reader = ReaderType::New();<br><br>
typedef itk::GDCMImageIO ImageIOType;<br>
ImageIOType::Pointer dicomIO = ImageIOType::New();<br> <br> reader->SetImageIO( dicomIO );<br><br> typedef itk::GDCMSeriesFileNames NamesGeneratorType;<br> NamesGeneratorType::Pointer nameGenerator = NamesGeneratorType::New();<br>
<br> nameGenerator->SetUseSeriesDetails( true );<br> nameGenerator->AddSeriesRestriction("0008|0021" );<br><br> nameGenerator->SetDirectory( argv[1] );<br><br> try<br> {<br> std::cout << std::endl << "The directory: " << std::endl;<br>
std::cout << std::endl << argv[1] << std::endl << std::endl;<br> std::cout << "Contains the following DICOM Series: ";<br> std::cout << std::endl << std::endl;<br>
<br> typedef std::vector< std::string > SeriesIdContainer;<br> <br> const SeriesIdContainer & seriesUID = nameGenerator->GetSeriesUIDs();<br> <br> SeriesIdContainer::const_iterator seriesItr = seriesUID.begin();<br>
SeriesIdContainer::const_iterator seriesEnd = seriesUID.end();<br> while( seriesItr != seriesEnd )<br> {<br> std::cout << seriesItr->c_str() << std::endl;<br> seriesItr++;<br> }<br>
<br> std::string seriesIdentifier;<br><br> if( argc > 3 ) // If no optional series identifier<br> {<br> seriesIdentifier = argv[3];<br> }<br> else<br> {<br> seriesIdentifier = seriesUID.begin()->c_str();<br>
}<br><br> std::cout << std::endl << std::endl;<br> std::cout << "Now reading series: " << std::endl << std::endl;<br> std::cout << seriesIdentifier << std::endl;<br>
std::cout << std::endl << std::endl;<br><br> typedef std::vector< std::string > FileNamesContainer;<br> FileNamesContainer fileNames;<br><br> fileNames = nameGenerator->GetFileNames( seriesIdentifier );<br>
reader->SetFileNames( fileNames );<br> try<br> {<br> reader->Update();<br> }<br> catch (itk::ExceptionObject &ex)<br> {<br> std::cout << ex << std::endl;<br> return EXIT_FAILURE;<br>
}<br> }<br> catch (itk::ExceptionObject &ex)<br> {<br> std::cout << ex << std::endl;<br> return EXIT_FAILURE;<br> }<br>// return EXIT_SUCCESS;<br><br>//////////////////////////////////////////////////////////////////////////////////////<br>
// FROM HERE ADJUSTED ResampleImageFilter.cxx CODE<br>/////////////////////////////////////////////////////////////////////////////////////<br><br>// const unsigned int Dimension = 3;<br> typedef unsigned char InputPixelType;<br>
typedef unsigned char OutputPixelType;<br> typedef itk::Image< InputPixelType, Dimension > InputImageType;<br>// typedef itk::Image< OutputPixelType, Dimension > OutputImageType;<br> <br> typedef itk::Image< PixelType, Dimension > OutputImageType;<br>
// typedef itk::ImageFileReader< InputImageType > ReaderType;<br><br> typedef itk::ImageFileWriter< ImageType > WriterType;<br> WriterType::Pointer writer = WriterType::New();<br><br><br> writer->SetFileName( argv[2] );<br>
<br>// typedef itk::ResampleImageFilter<ImageType,OutputImageType> FilterType;<br> typedef itk::ResampleImageFilter<ImageType,ImageType> FilterType;<br> FilterType::Pointer filter = FilterType::New();<br><br>
typedef itk::AffineTransform< double, Dimension > TransformType;<br> TransformType::Pointer transform = TransformType::New();<br> filter->SetTransform( transform );<br><br><br> typedef itk::NearestNeighborInterpolateImageFunction<ImageType, double > InterpolatorType;<br>
InterpolatorType::Pointer interpolator = InterpolatorType::New();<br> filter->SetInterpolator( interpolator );<br><br> <br> filter->SetDefaultPixelValue( 100 ); // if pixel in output image not defined, what value?<br>
<br><br> double spacing[ Dimension ];<br> spacing[0] = 0.29; // pixel spacing in millimeters along X<br> spacing[1] = 0.29; // pixel spacing in millimeters along Y<br> spacing[2] = 3.3; <br><br> filter->SetOutputSpacing( spacing );<br>
<br> double origin[ Dimension ];<br> origin[0] = 0.0; // X space coordinate of origin<br> origin[1] = 0.0; // Y space coordinate of origin<br> origin[2] = 0.0;<br><br> filter->SetOutputOrigin( origin );<br> ImageType::DirectionType direction;<br>
direction.SetIdentity();<br> filter->SetOutputDirection( direction );<br> ImageType::SizeType size;<br><br> size[0] = 560; // number of pixels along X<br> size[1] = 560; // number of pixels along Y<br> size[2] = 300;<br>
<br> filter->SetSize( size );<br> filter->SetInput( reader->GetOutput() );<br>// writer->SetInput( filter->GetOutput() );<br>// writer->Update();<br> TransformType::OutputVectorType translation;<br>
translation[0] = 0; // X translation in millimeters<br> translation[1] = 0; // Y translation in millimeters<br> translation[2] = 0;<br><br> transform->Translate( translation );<br> // Software Guide : EndCodeSnippet<br>
<br> writer->SetInput( filter->GetOutput() );<br><br> std::cout << "Writing the image as " << std::endl << std::endl;<br> std::cout << argv[2] << std::endl << std::endl;<br>
writer->Update();<br><br>}<br>