I am trying to implement some kind of numpy.where() for my ITK images in C++. ITK's way seems to be with Functors. I am not very experienced with templates, so my whole approach might be flawed, but here is my go:
using MASK_IMAGE_TYPE = itk::Image<unsigned short, 3>;
template<class T, T value, T if_equal, T if_n_equal> class WhereFunctor
{
private:
T v = value;
T e = if_equal;
T n = if_n_equal;
public:
WhereFunctor() = default;
~WhereFunctor() = default;
inline T operator()(const T& in_value)
{
return in_value == value ? if_equal : if_n_equal;
}
};
template<typename T> typename T::Pointer where(
typename T::Pointer& img,
typename T::PixelType value,
typename T::PixelType if_equal,
typename T::PixelType if_n_equal)
{
auto filter = itk::UnaryFunctorImageFilter<T, T, WhereFunctor<typename T::PixelType, value, if_equal, if_n_equal>>::New();
filter->SetInPlace(false);
filter->SetInput(img);
filter->Update();
typename T::Pointer ret_img = filter->GetOutput();
return ret_img;
}
When I try to call this where function with:
auto img = where<MASK_IMAGE_TYPE>(my_image, 0, 1, 0);
, I get the following error:
: In instantiation of ‘typename T::Pointer where(typename T::Pointer&, typename T::PixelType, typename T::PixelType, typename T::PixelType) [with T = itk::Image<short unsigned int, 3>; typename T::Pointer = itk::SmartPointer<itk::Image<short unsigned int, 3> >; typename T::PixelType = short unsigned int]’:
:23:55: required from here
:58:124: error: ‘value’ is not a constant expression
58 | auto filter = itk::UnaryFunctorImageFilter<T, T, WhereFunctor<typename T::PixelType, value, if_equal, if_n_equal>>::New();
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~
:58:124: note: in template argument for type ‘short unsigned int’
:58:124: error: ‘if_equal’ is not a constant expression
:58:124: note: in template argument for type ‘short unsigned int’
:58:124: error: ‘if_n_equal’ is not a constant expression
:58:124: note: in template argument for type ‘short unsigned int’
I think I understand that such an error can be due to type indeterminacy at compile type, but in this case I do not understand where it comes from.
You have needlessly many template parameters. You could follow the way it is done in a corresponding test. Define your function, set it via filter->SetFunctor() and call Update()
.