[Insight-users] translating image volume using affine transformation
Bill Lorensen
bill.lorensen at gmail.com
Fri Nov 27 11:05:30 EST 2009
What is the origin, spacing and direction of the input volume?
On Fri, Nov 27, 2009 at 9:59 AM, michiel mentink
<michael.mentink at st-hughs.ox.ac.uk> wrote:
> Dear all,
>
> I'm trying to make a simple function that translates a dicom volume by a
> certain amount.
> It first opens all dicom slides of an mri scan.
>
> To do this, I pasted DicomSeriesReadImageWrite2.cxx and
> ResampleImageFilter.cxx and adjusted
> the latter so it accepts 3 dimensions instead of two and uses integer
> instead of unsigned char.
>
> The function compiles and a .vtk volume is written. However, there's no
> image data in the file.
> It does display all pixels with value 100, as I set by:
> filter->SetDefaultPixelValue( 100 );
>
> questions:
> 1) am I too naive to think that the ResampleImageFilter can easily be
> extended from 2 to 3 dimensions?
> 2) if not, what did I do wrong?
>
> I pasted the source code below.
>
> //////////////////////////////////////////////////////////////////////////////////////////////////
> #if defined(_MSC_VER)
> #pragma warning ( disable : 4786 )
> #endif
>
> #ifdef __BORLANDC__
> #define ITK_LEAN_AND_MEAN
> #endif
>
> #include "itkOrientedImage.h"
> #include "itkGDCMImageIO.h"
> #include "itkGDCMSeriesFileNames.h"
> #include "itkImageSeriesReader.h"
> #include "itkImageFileWriter.h"
> #include "itkResampleImageFilter.h"
>
> #include "itkAffineTransform.h"
> #include "itkNearestNeighborInterpolateImageFunction.h"
> // Software Guide : EndCodeSnippet
>
> int main( int argc, char* argv[] )
> {
>
> if( argc < 3 )
> {
> std::cerr << "Usage: " << std::endl;
> std::cerr << argv[0] << " DicomDirectory outputFileName [seriesName]"
> << std::endl;
> return EXIT_FAILURE;
> }
>
> typedef signed short PixelType;
> const unsigned int Dimension = 3;
>
> typedef itk::OrientedImage< PixelType, Dimension > ImageType;
>
> typedef itk::ImageSeriesReader< ImageType > ReaderType;
> ReaderType::Pointer reader = ReaderType::New();
>
> typedef itk::GDCMImageIO ImageIOType;
> ImageIOType::Pointer dicomIO = ImageIOType::New();
>
> reader->SetImageIO( dicomIO );
>
> typedef itk::GDCMSeriesFileNames NamesGeneratorType;
> NamesGeneratorType::Pointer nameGenerator = NamesGeneratorType::New();
>
> nameGenerator->SetUseSeriesDetails( true );
> nameGenerator->AddSeriesRestriction("0008|0021" );
>
> nameGenerator->SetDirectory( argv[1] );
>
> try
> {
> std::cout << std::endl << "The directory: " << std::endl;
> std::cout << std::endl << argv[1] << std::endl << std::endl;
> std::cout << "Contains the following DICOM Series: ";
> std::cout << std::endl << std::endl;
>
> typedef std::vector< std::string > SeriesIdContainer;
>
> const SeriesIdContainer & seriesUID = nameGenerator->GetSeriesUIDs();
>
> SeriesIdContainer::const_iterator seriesItr = seriesUID.begin();
> SeriesIdContainer::const_iterator seriesEnd = seriesUID.end();
> while( seriesItr != seriesEnd )
> {
> std::cout << seriesItr->c_str() << std::endl;
> seriesItr++;
> }
>
> std::string seriesIdentifier;
>
> if( argc > 3 ) // If no optional series identifier
> {
> seriesIdentifier = argv[3];
> }
> else
> {
> seriesIdentifier = seriesUID.begin()->c_str();
> }
>
> std::cout << std::endl << std::endl;
> std::cout << "Now reading series: " << std::endl << std::endl;
> std::cout << seriesIdentifier << std::endl;
> std::cout << std::endl << std::endl;
>
> typedef std::vector< std::string > FileNamesContainer;
> FileNamesContainer fileNames;
>
> fileNames = nameGenerator->GetFileNames( seriesIdentifier );
> reader->SetFileNames( fileNames );
> try
> {
> reader->Update();
> }
> catch (itk::ExceptionObject &ex)
> {
> std::cout << ex << std::endl;
> return EXIT_FAILURE;
> }
> }
> catch (itk::ExceptionObject &ex)
> {
> std::cout << ex << std::endl;
> return EXIT_FAILURE;
> }
> // return EXIT_SUCCESS;
>
> //////////////////////////////////////////////////////////////////////////////////////
> // FROM HERE ADJUSTED ResampleImageFilter.cxx CODE
> /////////////////////////////////////////////////////////////////////////////////////
>
> // const unsigned int Dimension = 3;
> typedef unsigned char InputPixelType;
> typedef unsigned char OutputPixelType;
> typedef itk::Image< InputPixelType, Dimension > InputImageType;
> // typedef itk::Image< OutputPixelType, Dimension > OutputImageType;
>
> typedef itk::Image< PixelType, Dimension > OutputImageType;
> // typedef itk::ImageFileReader< InputImageType > ReaderType;
>
> typedef itk::ImageFileWriter< ImageType > WriterType;
> WriterType::Pointer writer = WriterType::New();
>
>
> writer->SetFileName( argv[2] );
>
> // typedef itk::ResampleImageFilter<ImageType,OutputImageType> FilterType;
> typedef itk::ResampleImageFilter<ImageType,ImageType> FilterType;
> FilterType::Pointer filter = FilterType::New();
>
> typedef itk::AffineTransform< double, Dimension > TransformType;
> TransformType::Pointer transform = TransformType::New();
> filter->SetTransform( transform );
>
>
> typedef itk::NearestNeighborInterpolateImageFunction<ImageType, double >
> InterpolatorType;
> InterpolatorType::Pointer interpolator = InterpolatorType::New();
> filter->SetInterpolator( interpolator );
>
>
> filter->SetDefaultPixelValue( 100 ); // if pixel in output image not
> defined, what value?
>
>
> double spacing[ Dimension ];
> spacing[0] = 0.29; // pixel spacing in millimeters along X
> spacing[1] = 0.29; // pixel spacing in millimeters along Y
> spacing[2] = 3.3;
>
> filter->SetOutputSpacing( spacing );
>
> double origin[ Dimension ];
> origin[0] = 0.0; // X space coordinate of origin
> origin[1] = 0.0; // Y space coordinate of origin
> origin[2] = 0.0;
>
> filter->SetOutputOrigin( origin );
> ImageType::DirectionType direction;
> direction.SetIdentity();
> filter->SetOutputDirection( direction );
> ImageType::SizeType size;
>
> size[0] = 560; // number of pixels along X
> size[1] = 560; // number of pixels along Y
> size[2] = 300;
>
> filter->SetSize( size );
> filter->SetInput( reader->GetOutput() );
> // writer->SetInput( filter->GetOutput() );
> // writer->Update();
> TransformType::OutputVectorType translation;
> translation[0] = 0; // X translation in millimeters
> translation[1] = 0; // Y translation in millimeters
> translation[2] = 0;
>
> transform->Translate( translation );
> // Software Guide : EndCodeSnippet
>
> writer->SetInput( filter->GetOutput() );
>
> std::cout << "Writing the image as " << std::endl << std::endl;
> std::cout << argv[2] << std::endl << std::endl;
> writer->Update();
>
> }
>
> _____________________________________
> Powered by www.kitware.com
>
> Visit other Kitware open-source projects at
> http://www.kitware.com/opensource/opensource.html
>
> Kitware offers ITK Training Courses, for more information visit:
> http://www.kitware.com/products/protraining.html
>
> Please keep messages on-topic and check the ITK FAQ at:
> http://www.itk.org/Wiki/ITK_FAQ
>
> Follow this link to subscribe/unsubscribe:
> http://www.itk.org/mailman/listinfo/insight-users
>
>
More information about the Insight-users
mailing list