Use of itkImageIterator

Miller, James V (CRD) millerjv at crd.ge.com
Mon May 1 16:32:06 EDT 2000


Your code is not far off. The usage is a little complex right now because I have been focusing on how
one could write a filter that processes an N dimensional image, regardless of the value of N.  We are
trying to provide a single N-dimensional image class that supports iterators.
Testing/Code/Common/itkBasicArchitectureTest.cxx illustrates how you could write a function that
processes an N dimensional image without knowing N ahead of time. Since you do not know N when you
write the code, you do not know how "many" nested loops are needed.  So, itkBasicArchitectureTest
uses recursion to loop over all dimensions until it gets down to a row, then it walks across the row.
We need to streamline this API when dealing with 2D and 3D images.

itkIndex has a method GetBasisIndex() which returns an index that can be used to move up/down a row
or up/down a slice, etc. Using is essentially what your stepy variable is doing. I would keep two
interators, one that walks up the rows, one that walks across a row: (Don't knwoif this code is
syntactically correct, I'm writing it off the top of my head)....

imageType::Iterator myIterator = myImage->Begin();
imageType::Iterator resultIterator = myResult->Begin();

imageType::Iterator myRowIterator = myIterator;
imageType::Iterator resultRowIterator = resultIterator;

imageType::itkIndex basisIndex = myIterator->GetIndex()->GetBasisIndex(1);

for(unsigned int y=0; y<ny; y++) {
  myIterator = myRowIterator;
  resultIterator = resultRowIterator;

  for(unsigned int x=0; x<nx; x++) {
      *resultIterator++ = *myIterator++;
   }
  
  myRowIterator += basisIndex;
  resultRowIterator += basisIndex;
}

This is similar to Increments in vtk for walking around an image....

We need to come up with a good way to initialize/set an index, i.e. what is a good API for this?  I
was hoping that we'd be able to construct the API, so that people could not make a mistake when
setting an index. For instance, if the index is 3D, the user would have to give 3 values, either 3
scalars or an array of length 3.  I wanted to set it up so that if you can an array of length 2 to
something that needed 3, then the code would not compile.  Unfortunately, it does not look as though
this is supported on many compilers.

I have to run to a meeting now.  Please let me know if this cleared things up (or not).

I am planning to be able to set up an iterator that will walk along any dimension when the operator++
is used.  That may simplify the above code more.



-----Original Message-----
From: Luis Ibanez [mailto:ibanez at cs.unc.edu]
Sent: Monday, May 01, 2000 3:58 PM
To: insight-developers at public.kitware.com
Subject: Use of itkImageIterator


Hi,

We are trying to write our first simple algorithm,
but we get confused about how to use image
iterators in the way they are set now.

Our understanding is that an itkImageIterator
contains an itkIndex (an array of unsigned longs
with size equal to the dimension of the image).

The numbers in the index array are used to
address a particular element (pixel/voxel) of the
image.

This looks fine for getting access to a particular
pixel. But it is not very clear how to go through
the whole image.

This is what we tried:

==================================
typedef   itkImage<char,2>  imageType;
imageType *myImage = imageType::New();
imageType *myResult = imageType::New();
unsigned long int size[] = { 1024,1024 };
myImage->SetSize(size);
myResult->SetSize(size);
imageType::Iterator myIterator = myImage->Begin();
imageType::Iterator resultIterator = myResult->Begin();
// so far we have an iterator pointing to the upper left
// pixel of the image
// now... incrementing the iterator will move in the
// inner loop of the image memory array... and only
// there.

// now we recover the size of the image
// and create an index to jump in the vertical direction
// because itkImageIterators can be incremented by
// using itkIndex's

const unsigned int nx = myImage->GetSize()[0];
const unsigned int ny = myImage->GetSize()[1];
imageType::Index   stepy;
stepy[1] = 1;
for(unsigned int y=0; y<ny; y++) {
  imageType::Index start = myIterator->GetIndex()
  start[0] = 0;  // we didn't find other way to reset the
                    // inner loop part of the iterator/index
  myIterator.SetIndex(start);
  resultIterator.SetIndex(start);
  for(unsigned int x=0; x<nx; x++) {
      *resultIterator++ = *myIterator++;
   }
   myIterator += stepy;
   resultIterator += stepy;
}



But this construction look unnatural and quite complex,

could somebody gives a hint about what are we missing  ?

=================================

On the other hand, there is no an operator

operator!=

nor

operator==

So we cannot make expression like

while(  iter != image->End() );

==================================

We are looking a little the implementation
done in Blitz++, to see if there are some
options.


Luis



More information about the Insight-developers mailing list