[Insight-users] Accessing a POD pixel value as if it were the 0th component of a vector pixel type

David Doria daviddoria at gmail.com
Sat Jan 7 16:50:30 EST 2012


On Wed, Jan 4, 2012 at 3:16 PM, David Doria <daviddoria at gmail.com> wrote:
> I often have the case where I want a function template to operate on all
> channels of an image. I'd like to be able to pass both a scalar image and a
> vector image to the function.
>
> template <typename TImage>
> void OperateOnEveryChannel(const TImage* const image)
> {
>   itk::Index<2> index = {{0,0}};
>   typename TImage::PixelType pixel = image->GetPixel(index);
>
>   for(unsigned int i = 0; i < image->GetNumberOfComponentsPerPixel(); ++i)
>     {
>     std::cout << pixel[i] << std::endl;
>     }
> }
>
> If TImage is an itk::VectorImage, all is well. However, if TImage is an
> itk::Image<POD>, the scalar pixel types do not have an operator[], so
> although pixel[0] makes logical sense from the algorithm's perspective, it
> is not valid syntax.
>
> Is there any way to do this without writing a specialization?
>
> Thanks,
>
> David

I learned a neat trick with some c++0x:

template<typename T>
typename std::enable_if<std::is_fundamental<T>::value, T&>::type
index(T& t, size_t)
{
  return t;
}

template<typename T>
typename T::value_type& index(T& v, size_t i)
{
  return v[i];
}

Then you can do:

int myInt;
index(myInt, 0);

itk::CovariantVector<float,3> myVector;
index(myInt, 0);
index(myInt, 1);
index(myInt, 2);

This way in a loop of a template function, you can do:

template <typename TImage>
void DoSomething(TImage* image)
{
  while (... iterator over pixels...)
  for(unsigned int channel = 0; channel <
image->GetNumberOfComponentsPerPixel(); ++channel)
  {
    index(iterator.Get(), channel);
  }
}

and the loop will be will behaved even for POD image types like
itk::Image<int,2> . Cool!

David


More information about the Insight-users mailing list