[Insight-users] A question about the iterator : 4D to 3D

Luis Ibanez luis.ibanez at kitware.com
Tue, 30 Dec 2003 03:47:30 -0500


Hi Peng,

In order to compute the mean across time of the values
in your 4D image you should simply use the iterator:

"ImageLinearConstIteratorWithIndex"
http://www . itk . org/Insight/Doxygen/html/classitk_1_1ImageLinearConstIteratorWithIndex . html

because you only need to go along (time) lines in the 4D image
and the order in which you pass from one line to another is
irrelevant for your processing.

The code will look like:


#include "itkImageLinearConstIteratorWithIndex.h"
#include "itkImage.h"


typedef unsigned char               PixelType;

typedef itk::Image< PixelType, 3 >  Image3DType;
typedef itk::Image< PixelType, 4 >  Image4DType;

typedef itk::ImageLinearConstIteratorWithIndex<
                                Image4DType > IteratorType;

typedef itk::NumericTraits< PixelType >::AccumulationType  SumType;
typedef itk::NumericTraits< SumType   >::RealType          MeanType;

Image3DType::IndexType index3D;
Image4DType::IndexType index4D;

Image4DType::ConstPointer image4D = Get4DImageSomehow();
Image4DType::Pointer      image3D = Get3DImageSomehow();

Image4DType::RegionType region = image4D->GetBufferedRegion();
const unsigned int timeLength = region.GetSize()[3];

IteratorType it( image4D, region );

it.SetDirection( 3 ); // Walk along time dimension
it.GoToBegin();

while( !it.IsAtEnd() )
  {

  SumType sum = itk::NumericTraits< SumType >::Zero;
  it.GoToBeginOfLine();
  index4D = it.GetIndex();

  while( !it.IsAtEndOfLine() )
    {
     sum += it.Get();
     ++it;
    }
  MeanType mean = static_cast< MeanType >( sum ) /
                  static_cast< MeanType >( timeLength );

  index3D[0] = index4D[0];
  index3D[1] = index4D[1];
  index3D[2] = index4D[2];

  image3D->SetPixel( index3D, static_cast< PixelType >( mean ) );
  it.NextLine();
  }


As you can see, we avoid to use a 3D iterator to walk
over the mean image. The reason is that there is no
guarranty that the 3D iterator will walk in the same
order as the 4D one. Iterators just adhere to their contract
of visiting all the pixels, but do not enforce any particular
order for the visits.  The linear iterator guarraties to
visit the pixels along a line of the image in the order
in which they are placed in the line, but do not states
in what order one line will be visited with respect to
other lines.  Here we simply take advantage of knowing
the first three components of the 4D iterator index,
and use them to place the resulting mean value in the
output 3D image.



Please let us know if you have further questions,


Thanks



  Luis


--------------------
Peng Cheng wrote:
> 												peng-cheng at uiowa . edu
> 												2003-12-30
> Hi all,
> I am trying to write a function to do the following job. The input image is a 4D image (3D in space and the 4th dimension is the time). The output image should be a 3D image. Suppose we are doing an average operation on the 4D image over the time (the 4th dimension). And put the average value into the result 3D image. I dont know if I am doing right here. For the ImageSliceIteratorWithIndex it has only two directions for user specification. What if there are more than 3 dimensions. How the iterator goes through the image? Is there any default order for these linear interators to follow other than the specified directions? 
> I pasted my code as follows:
> 
> 	typedef itk::ImageSliceConstIteratorWithIndex<4DImageType> 4DIteratorType;
> 	typedef itk::ImageSliceIteratorWithIndex< 3DImageType > 3DIteratorType;
> 	4DIteratorType 4D_It( m_4DImage, m_4DImage->GetRequestedRegion() );
> 	3DIteratorType 3D_It( m_3DImage, m_3DImage->GetRequestedRegion() );
> 
>     4D_It.SetFirstDirection(3);
> 	4D_It.SetSecondDirection(0);
> 	// whatt the next direction?????
> 
> 	3D_It.SetFirstDirection(0);
> 	3D_It.SetSecondDirection(1);
> 	
> 	
> 	4D_It.GoToBegin();
> 	3D_It.GoToBegin();
> 	while( !4D_It.IsAtEnd())
> 	{
> 		float sum=0;
> 		while( !4D_It.IsAtEndOfLine())
> 		{
> 			sum+= 4D_It.Get();
> 			++4D_It;
> 		} 
> 		3D_It.Set(sum/T);
> 
> 		4D_It.NextLine();
> 		++3D_It;
> 	}
> 
> 
> Sincerely yours,
> Peng Cheng
> 
> Dept. of BME
> University of Iowa
> 
> 
> "{"n왨x%HȠ۬z"J+m?f?X)ߣ(!rs==