[Insight-users] How to transfer a set of 2D image data to a 3D
image data?
HIRAKI Hideaki
hhiraki at lab.nig.ac.jp
Thu, 05 Feb 2004 20:05:49 +0900
----Next_Part(Thu_Feb__5_20:00:33_2004_886)--
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
vtkImageAppend in VTK can do it.
But if you want to process with itk::Image,
the attached code may help you.
Regards,
Hideaki Hiraki
"jiang" <jiang at TI.Uni-Trier.DE> wrote:
> Dear itk-users,
> I have a set of 2D image data. The type is, for example:
> typedef unsigned char PixelType;
> typedef itk::Image< InputPixelType, 2 > ImageType;
>
> Now I want to transfer them to 3D image data:
> typedef itk::Image< InputPixelType, 3 > VolumeType;
>
> Then transfer the volume to vtk data in order to render it. How should I do?
>
>
> Thanks a lot!
>
>
>
> Chunyan
>
----Next_Part(Thu_Feb__5_20:00:33_2004_886)--
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="itkJoinSeriesImageFilter.h"
/*=========================================================================
Program: Insight Segmentation & Registration Toolkit
Module: $RCSfile$
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) Insight Software Consortium. All rights reserved.
See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
#ifndef __itkJoinSeriesImageFilter_h
#define __itkJoinSeriesImageFilter_h
#include "itkImageToImageFilter.h"
namespace itk
{
/** \class JoinSeriesImageFilter
* \brief Join N-D images into an (N+1)-D image
*
* Details should be described here.
*
* \ingroup GeometricTransforms
*
*/
template <class TInputImage, class TOutputImage>
class ITK_EXPORT JoinSeriesImageFilter:
public ImageToImageFilter<TInputImage,TOutputImage>
{
public:
/** Standard class typedefs. */
typedef JoinSeriesImageFilter Self;
typedef ImageToImageFilter<TInputImage,TOutputImage> Superclass;
typedef SmartPointer<Self> Pointer;
typedef SmartPointer<const Self> ConstPointer;
/** Method for creation through the object factory. */
itkNewMacro(Self);
/** Run-time type information (and related methods). */
itkTypeMacro(JoinSeriesImageFilter, ImageToImageFilter);
/** Compiler can't inherit typedef? */
typedef typename Superclass::InputImageType InputImageType;
typedef typename Superclass::OutputImageType OutputImageType;
typedef typename InputImageType::Pointer InputImagePointer;
typedef typename OutputImageType::Pointer OutputImagePointer;
typedef typename InputImageType::RegionType InputImageRegionType;
typedef typename OutputImageType::RegionType OutputImageRegionType;
/** Compiler can't inherit ImageDimension enumeration? */
itkStaticConstMacro(InputImageDimension, unsigned int,
TInputImage::ImageDimension);
itkStaticConstMacro(OutputImageDimension, unsigned int,
TOutputImage::ImageDimension);
/** IndexValueType is used to switch among the inputs and
* is used as the index value of the new dimension */
typedef unsigned int IndexValueType;
/** Set/Get spacing of the new dimension */
itkSetMacro(Spacing, double);
itkGetMacro(Spacing, double);
/** Set/Get origin of the new dimension */
itkSetMacro(Origin, double);
itkGetMacro(Origin, double);
protected:
JoinSeriesImageFilter();
~JoinSeriesImageFilter() {};
void PrintSelf(std::ostream& os, Indent indent) const;
/** Overrides GenerateOutputInformation() in order to produce
* an image which has a different information than the first input.
* \sa ProcessObject::GenerateOutputInformaton() */
virtual void GenerateOutputInformation();
/** Overrides GenerateInputRequestedRegion() in order to inform
* the pipeline execution model of different input requested regions
* than the output requested region.
* \sa ImageToImageFilter::GenerateInputRequestedRegion() */
virtual void GenerateInputRequestedRegion();
/** JoinSeriesImageFilter can be implemented as a multithreaded filter.
* \sa ImageSource::ThreadedGenerateData(),
* ImageSource::GenerateData() */
virtual void ThreadedGenerateData(const OutputImageRegionType&
outputRegionForThread, int threadId );
private:
JoinSeriesImageFilter(const Self&); //purposely not implemented
void operator=(const Self&); //purposely not implemented
double m_Spacing;
double m_Origin;
};
} // end namespace itk
#ifndef ITK_MANUAL_INSTANTIATION
#include "itkJoinSeriesImageFilter.txx"
#endif
#endif
----Next_Part(Thu_Feb__5_20:00:33_2004_886)--
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="itkJoinSeriesImageFilter.txx"
#ifndef _itkJoinSeriesImageFilter_txx
#define _itkJoinSeriesImageFilter_txx
#include "itkJoinSeriesImageFilter.h"
#include "itkProgressReporter.h"
#include "itkImageRegionConstIterator.h"
#include "itkImageRegionIterator.h"
namespace itk
{
template <class TInputImage, class TOutputImage>
JoinSeriesImageFilter<TInputImage,TOutputImage>
::JoinSeriesImageFilter()
{
m_Spacing = 1.0;
m_Origin = 0.0;
}
template <class TInputImage, class TOutputImage>
void
JoinSeriesImageFilter<TInputImage,TOutputImage>
::PrintSelf(std::ostream& os, Indent indent) const
{
Superclass::PrintSelf(os,indent);
os << indent << "Spacing: " << m_Spacing << std::endl;
os << indent << "Origin: " << m_Origin << std::endl;
}
/**
* \sa UnaryFunctorImageFilter::GenerateOutputInformation()
*/
template <class TInputImage, class TOutputImage>
void
JoinSeriesImageFilter<TInputImage,TOutputImage>
::GenerateOutputInformation()
{
// do not call the superclass' implementation of this method since
// this filter allows the input the output to be of different dimensions
// get pointers to the input and output
typename Superclass::OutputImagePointer outputPtr = this->GetOutput();
typename Superclass::InputImageConstPointer inputPtr = this->GetInput();
if ( !outputPtr || !inputPtr)
{
return;
}
// Set the output image largest possible region. Use a RegionCopier
// so that the input and output images can be different dimensions.
OutputImageRegionType outputLargestPossibleRegion;
this->CallCopyInputRegionToOutputRegion(outputLargestPossibleRegion,
inputPtr->GetLargestPossibleRegion());
// for the new dimension, assuming the index has been set 0.
outputLargestPossibleRegion.SetSize(InputImageDimension,
this->GetNumberOfInputs());
outputPtr->SetLargestPossibleRegion( outputLargestPossibleRegion );
// Set the output spacing and origin
const ImageBase<InputImageDimension> *phyData;
phyData
= dynamic_cast<const ImageBase<InputImageDimension>*>(this->GetInput());
if (phyData)
{
// Copy what we can from the image from spacing and origin of the input
// This logic needs to be augmented with logic that select which
// dimensions to copy
unsigned int i;
const typename InputImageType::SpacingType&
inputSpacing = inputPtr->GetSpacing();
const typename InputImageType::PointType&
inputOrigin = inputPtr->GetOrigin();
typename OutputImageType::SpacingType outputSpacing;
typename OutputImageType::PointType outputOrigin;
// copy the input to the output and fill the rest of the
// output with zeros.
for (i=0; i < InputImageDimension; ++i)
{
outputSpacing[i] = inputSpacing[i];
outputOrigin[i] = inputOrigin[i];
}
for (; i < OutputImageDimension; ++i)
{
outputSpacing[i] = 1.0;
outputOrigin[i] = 0.0;
}
// for the new dimension
outputSpacing[InputImageDimension] = this->GetSpacing();
outputOrigin[InputImageDimension] = this->GetOrigin();
// set the spacing and origin
outputPtr->SetSpacing( outputSpacing );
outputPtr->SetOrigin( outputOrigin );
}
else
{
// pointer could not be cast back down
itkExceptionMacro(<< "itk::JoinSeriesImageFilter::GenerateOutputInformation "
<< "cannot cast input to "
<< typeid(ImageBase<InputImageDimension>*).name() );
}
}
template <class TInputImage, class TOutputImage>
void
JoinSeriesImageFilter<TInputImage,TOutputImage>
::GenerateInputRequestedRegion()
{
Superclass::GenerateInputRequestedRegion();
OutputImageRegionType outputRegion = this->GetOutput()->GetRequestedRegion();
IndexValueType begin = outputRegion.GetIndex(InputImageDimension);
IndexValueType end = begin + outputRegion.GetSize(InputImageDimension);
for (IndexValueType idx = 0; idx < this->GetNumberOfInputs(); ++idx)
{
InputImagePointer inputPtr =
const_cast<InputImageType *>(this->GetInput(idx));
if ( !inputPtr )
{
itkExceptionMacro(<< "missing input " << idx);
}
InputImageRegionType inputRegion; // assuming default is null
if ( begin <= idx && idx < end )
{
this->CallCopyOutputRegionToInputRegion(inputRegion, outputRegion);
}
inputPtr->SetRequestedRegion(inputRegion);
}
}
template <class TInputImage, class TOutputImage>
void
JoinSeriesImageFilter<TInputImage,TOutputImage>
::ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread,
int threadId)
{
itkDebugMacro(<<"Actually executing");
ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels());
OutputImageRegionType outputRegion = outputRegionForThread;
outputRegion.SetSize(InputImageDimension, 1);
InputImageRegionType inputRegion;
this->CallCopyOutputRegionToInputRegion(inputRegion, outputRegionForThread);
IndexValueType begin = outputRegionForThread.GetIndex(InputImageDimension);
IndexValueType end =
begin + outputRegionForThread.GetSize(InputImageDimension);
for (IndexValueType idx = begin; idx < end; ++idx)
{
outputRegion.SetIndex(InputImageDimension, idx);
ImageRegionIterator<OutputImageType>
outIt(this->GetOutput(), outputRegion);
ImageRegionConstIterator<InputImageType>
inIt(this->GetInput(idx), inputRegion);
outIt.GoToBegin();
inIt.GoToBegin();
while( !outIt.IsAtEnd() )
{
outIt.Set( inIt.Get() );
++outIt;
++inIt;
progress.CompletedPixel();
}
}
}
} // end namespace itk
#endif
----Next_Part(Thu_Feb__5_20:00:33_2004_886)----