[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