[Insight-users] MultipleImageIterator

Joël Schaerer joel.schaerer at gmail.com
Thu Feb 6 05:54:47 EST 2014


Hi all,

Recently I've had to iterate over many images at the same time. Instead 
of mixing the tedious iterator housekeeping code with the algorithm, I 
thought it could be a good idea to have a "multiple image iterator" for 
that. Since I didn't find one in ITK, I started writing a simple one 
myself. Its main limitation is that all iterators and thus all images 
must be of the same type:

namespace itk {
template<typename TIterator>
class MultipleImageIterator {
public:
   typedef MultipleImageIterator Self;
   typedef TIterator IteratorType;
   typedef typename IteratorType::ImageType ImageType;
   IteratorType& operator[](const int i) {return m_iterators[i];}
   void AddIterator(const IteratorType& it) {m_iterators.push_back(it);}
   Self& operator++() {
     for (typename std::vector<IteratorType>::iterator it = 
m_iterators.begin();
       it != m_iterators.end(); ++it) {
       ++(*it);
     }
   }
   void GoToBegin() {
     for (typename std::vector<IteratorType>::iterator it = 
m_iterators.begin();
       it != m_iterators.end(); ++it) {
       it->GoToBegin();
     }
   }
   unsigned int Size () const { return m_iterators.size(); }
protected:
   std::vector<IteratorType> m_iterators;

};
}

Here is a pretty straightforward usage example, which prints the values 
of 4 images side by side:

int main()
{
   typedef itk::Image<float,3> ImageType;
   typedef itk::ImageFileReader<ImageType> ReaderType;

   typedef itk::ImageRegionIterator<ImageType> IteratorType;
   itk::MultipleImageIterator<IteratorType> it;

   std::string filenames[] = 
{"originalT1.mha","csf_reg.nii.gz","grey_reg.nii.gz","white_reg.nii.gz"};
   std::vector<ImageType::Pointer> images; // Need to keep a reference 
as iterators only have weak references
   ReaderType::Pointer r = ReaderType::New();
   for (unsigned int i=0; i<4;++i) {
     r->SetFileName(filenames[i]);
     r->Update();
     ImageType::Pointer im = r->GetOutput();
     im->DisconnectPipeline();
     images.push_back(im);
it.AddIterator(itk::ImageRegionIterator<ImageType>(im,im->GetLargestPossibleRegion()));
   }

   for (it.GoToBegin(); !it[0].IsAtEnd(); ++it) {
     if ((it[1].Get() != 0) && ((float)std::rand()) / RAND_MAX < 0.01) {
       for (unsigned int i=0; i<it.Size(); ++i) {
         std::cout << it[i].Get() << ";";
       }
       std::cout << std::endl;
     }
   }
}


Any comments? What is the usual way of doing this with ITK? If there is 
any interest, this could be improved and potentially included in the 
library.

joel


More information about the Insight-users mailing list