Preserve datatype on a simple Reader--Writer pipeline

Hello.

Linking a simple ImageReader<type> with a ImageWriter<type> seems to change the datatype at the output. I have tried to load a .nrrd image (short) and when I write it back it turns to int:

type: short  # This is the header of the input
type: int  # This is the header of the output

Below is the code I’m using. I find strange that the first std::cout gives 2 and the second gives 4. Is this expected? Is it a bug? Am I missing something here?

template <class inputT>
int DoIt(const Arguments &arguments, inputT)
{
  // =========================================================================
  // Datatype definitions
  // =========================================================================
  using ImageType = itk::Image<inputT, 3>;
  using ImageReaderType = itk::ImageFileReader<ImageType>;
  using ImageWriterType = itk::ImageFileWriter<ImageType>;

  // =========================================================================
  // Datatype definitions
  // =========================================================================
  auto imageReader = ImageReaderType::New();
  imageReader->SetFileName(arguments.inputFileName);
  imageReader->Update();

  auto readerIO = imageReader->GetImageIO();
  readerIO->Print(std::cout, 0);
  std::cout << readerIO->GetComponentSize() << std::endl;

  // =========================================================================
  // Write out
  // =========================================================================
  auto imageWriter = ImageWriterType::New();
  imageWriter->SetFileName(arguments.outputFileName);
  imageWriter->SetInput(imageReader->GetOutput());
  imageWriter->SetImageIO(readerIO);
  imageWriter->Update();
  std::cout << readerIO->GetComponentSize() << std::endl;


  return EXIT_SUCCESS;
}

Thank you!

This is a strange and unnecessary step. Why do you do this? Does it work well without it?

Yes, that is unnecessary. I just added it as an attempt to make the writer respect the IO of the reader; it also used to print out the value of the component size and see that reader and writer have it different. I get the same result if I remove it

If you use itk::ReadImage and itk::WriteImage instead of reader and writer, does it still happen? What if you mix them? Can you share the header of the offending image?

I have tried itk::ReadImage<ImageType> with itk::ImageFileWriter<ImageType> and it does not work: the same I got earlier. The opposite (itk::ImageFileReader<ImageType> with itk::WriteImage<ImageType>) does not really compile for me; the same for itk::ReadImage<ImageType> combined with itk::WriteImage<ImageType>

The header of the offending file is as follows:

NRRD0004
# Complete NRRD file format specification at:
# http://teem.sourceforge.net/nrrd/format.html
type: short
dimension: 3
space: left-posterior-superior
sizes: 338 343 294
space directions: (0.703125,0,0) (0,0.703125,0) (0,0,0.60000038146972656)
kinds: domain domain domain
endian: little

Strange enough, it works for other datatypes…like loading/saving that image with float or unsigned int

Let’s figure out whether this is a problem in reading or writing. What type is the image after reading? std::cout<<imageReader->GetOutput();

What is the compile error for this:

auto inImage = itk::ReadImage<ImageType>(arguments.inputFileName);
std::cout << inImage;
itk::WriteImage(inImage, arguments.outputFileName);
1 Like

Here is the printout of the image:

mage (0x555df98ca3c0)
  RTTI typeinfo:   itk::Image<int, 3u>
  Reference Count: 1
  Modified Time: 248
  Debug: Off
  Object Name:
  Observers:
    none
  Source: (0x555df98c6d70)
  Source output name: Primary
  Release Data: Off
  Data Released: False
  Global Release Data: Off
  PipelineMTime: 59
  UpdateMTime: 249
  RealTimeStamp: 0 seconds
  LargestPossibleRegion:
    Dimension: 3
    Index: [0, 0, 0]
    Size: [338, 343, 294]
  BufferedRegion:
    Dimension: 3
    Index: [0, 0, 0]
    Size: [338, 343, 294]
  RequestedRegion:
    Dimension: 3
    Index: [0, 0, 0]
    Size: [338, 343, 294]
  Spacing: [0.703125, 0.703125, 0.6]
  Origin: [-158.906, -141.069, 34.2]
  Direction:
1 0 0
0 1 0
0 0 1

  IndexToPointMatrix:
0.703125 0 0
0 0.703125 0
0 0 0.6

  PointToIndexMatrix:
1.42222 0 0
0 1.42222 0
0 0 1.66667

  Inverse Direction:
1 0 0
0 1 0
0 0 1

  PixelContainer:
    ImportImageContainer (0x555df98ca680)
      RTTI typeinfo:   itk::ImportImageContainer<unsigned long, int>
      Reference Count: 1
      Modified Time: 246
      Debug: Off
      Object Name:
      Observers:
        none
      Pointer: 0x7f892837a010
      Container manages memory: true
      Size: 34084596
      Capacity: 34084596

This compiles fine and produces the same results that we have now. The following, which is slightly different, won’t compile

auto inImage = itk::ReadImage<ImageType>(arguments.inputFileName);
std::cout << inImage;
itk::WriteImage<ImageType>(inImage, arguments.outputFileName);

Thanks again!

If you invoke DoIt with int template argument, the image will be read with int pixels (conversion will occur from disk type during reading). Then the image will be written with int pixels, as that is your image type. Invoking DoIt<short>(...) should do the trick.

What is the compile error message for this? I think that this should compile, no matter the type of inputT.

1 Like

You seem to be doing the image type determination improperly. Maybe take inspiration from here: ITKTubeTK/tubeCLIHelperFunctions.h at 7536c6c112e1785cead4d008e8fae5ca8f527f20 · InsightSoftwareConsortium/ITKTubeTK · GitHub

1 Like
Consolidate compiler generated dependencies of target itkImageConvert
[ 50%] Building CXX object CMakeFiles/itkImageConvert.dir/main.cxx.o
/home/rafael/src/itkImageConvert/main.cxx: In instantiation of ‘int DoIt(const Arguments&, inputT) [with inputT = int]’:
/home/rafael/src/itkImageConvert/main.cxx:108:18:   required from here
/home/rafael/src/itkImageConvert/main.cxx:57:28: error: invalid initialization of reference of type ‘itk::Image<int, 3>&&’ from expression of type ‘itk::SmartPointer<itk::Image<int, 3> >’
   57 | itk::WriteImage<ImageType>(inImage, arguments.outputFileName);
      |                            ^~~~~~~
In file included from /home/rafael/src/itkImageConvert/main.cxx:4:
/home/rafael/src/itk/Modules/IO/ImageBase/include/itkImageFileWriter.h:247:29: note: in passing argument 1 of ‘void itk::WriteImage(TImagePointer&&, const string&, bool) [with TImagePointer = itk::Image<int, 3>; std::string = std::__cxx11::basic_string<char>]’
  247 | WriteImage(TImagePointer && image, const std::string & filename, bool compress = false)
      |            ~~~~~~~~~~~~~~~~~^~~~~
/home/rafael/src/itkImageConvert/main.cxx: In instantiation of ‘int DoIt(const Arguments&, inputT) [with inputT = unsigned int]’:
/home/rafael/src/itkImageConvert/main.cxx:112:18:   required from here
/home/rafael/src/itkImageConvert/main.cxx:57:28: error: invalid initialization of reference of type ‘itk::Image<unsigned int, 3>&&’ from expression of type ‘itk::SmartPointer<itk::Image<unsigned int, 3> >’
   57 | itk::WriteImage<ImageType>(inImage, arguments.outputFileName);
      |                            ^~~~~~~
In file included from /home/rafael/src/itkImageConvert/main.cxx:4:
/home/rafael/src/itk/Modules/IO/ImageBase/include/itkImageFileWriter.h:247:29: note: in passing argument 1 of ‘void itk::WriteImage(TImagePointer&&, const string&, bool) [with TImagePointer = itk::Image<unsigned int, 3>; std::string = std::__cxx11::basic_string<char>]’
  247 | WriteImage(TImagePointer && image, const std::string & filename, bool compress = false)
      |            ~~~~~~~~~~~~~~~~~^~~~~
/home/rafael/src/itkImageConvert/main.cxx: In instantiation of ‘int DoIt(const Arguments&, inputT) [with inputT = float]’:
/home/rafael/src/itkImageConvert/main.cxx:116:18:   required from here
/home/rafael/src/itkImageConvert/main.cxx:57:28: error: invalid initialization of reference of type ‘itk::Image<float, 3>&&’ from expression of type ‘itk::SmartPointer<itk::Image<float, 3> >’
   57 | itk::WriteImage<ImageType>(inImage, arguments.outputFileName);
      |                            ^~~~~~~
In file included from /home/rafael/src/itkImageConvert/main.cxx:4:
/home/rafael/src/itk/Modules/IO/ImageBase/include/itkImageFileWriter.h:247:29: note: in passing argument 1 of ‘void itk::WriteImage(TImagePointer&&, const string&, bool) [with TImagePointer = itk::Image<float, 3>; std::string = std::__cxx11::basic_string<char>]’
  247 | WriteImage(TImagePointer && image, const std::string & filename, bool compress = false)
      |            ~~~~~~~~~~~~~~~~~^~~~~
/home/rafael/src/itk/Modules/IO/ImageBase/include/itkImageFileWriter.h: In instantiation of ‘void itk::WriteImage(TImagePointer&&, const string&, bool) [with TImagePointer = itk::Image<int, 3>; std::string = std::__cxx11::basic_string<char>]’:
/home/rafael/src/itkImageConvert/main.cxx:57:27:   required from ‘int DoIt(const Arguments&, inputT) [with inputT = int]’
/home/rafael/src/itkImageConvert/main.cxx:108:18:   required from here
/home/rafael/src/itk/Modules/IO/ImageBase/include/itkImageFileWriter.h:250:66: error: static assertion failed: WriteImage requires a raw pointer or SmartPointer.
  250 |   static_assert(std::is_pointer<NonReferenceImagePointer>::value ||
      |                                                            ~~~~~~^~
  251 |                   mpl::IsSmartPointer<NonReferenceImagePointer>::Value,
      |                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/rafael/src/itk/Modules/IO/ImageBase/include/itkImageFileWriter.h:250:66: note: ‘(((bool)std::integral_constant<bool, false>::value) || ((itk::mpl::FalseType::ValueType)itk::mpl::FalseType::Value))’ evaluates to false
/home/rafael/src/itk/Modules/IO/ImageBase/include/itkImageFileWriter.h:254:88: error: no match for ‘operator*’ (operand type is ‘itk::Image<int, 3>’)
  254 |   using ImageType = typename std::remove_const<typename std::remove_reference<decltype(*image)>::type>::type;
      |                                                                                        ^~~~~~
In file included from /home/rafael/src/itk/Modules/Core/Common/include/itkPoint.h:23,
                 from /home/rafael/src/itk/Modules/Core/Common/include/itkContinuousIndex.h:21,
                 from /home/rafael/src/itk/Modules/Core/Common/include/itkImageRegion.h:34,
                 from /home/rafael/src/itk/Modules/Core/Common/include/itkImage.h:21,
                 from /home/rafael/src/itkImageConvert/main.cxx:2:
/home/rafael/src/itk/Modules/Core/Common/include/itkVector.h:297:36: note: candidate: ‘template<class T, unsigned int NVectorDimension> itk::Vector<T, NVectorDimension> itk::operator*(const T&, const itk::Vector<T, NVectorDimension>&)’
  297 | inline Vector<T, NVectorDimension> operator*(const T & scalar, const Vector<T, NVectorDimension> & v)
      |                                    ^~~~~~~~
/home/rafael/src/itk/Modules/Core/Common/include/itkVector.h:297:36: note:   template argument deduction/substitution failed:
In file included from /home/rafael/src/itkImageConvert/main.cxx:4:
/home/rafael/src/itk/Modules/IO/ImageBase/include/itkImageFileWriter.h:254:88: note:   candidate expects 2 arguments, 1 provided
  254 |   using ImageType = typename std::remove_const<typename std::remove_reference<decltype(*image)>::type>::type;
      |                                                                                        ^~~~~~
In file included from /home/rafael/src/itk/Modules/Core/Common/include/itkMatrix.h:22,
                 from /home/rafael/src/itk/Modules/Core/Common/include/itkImageBase.h:34,
                 from /home/rafael/src/itk/Modules/Core/Common/include/itkNeighborhoodAccessorFunctor.h:22,
                 from /home/rafael/src/itk/Modules/Core/Common/include/itkImage.h:28,
                 from /home/rafael/src/itkImageConvert/main.cxx:2:
/home/rafael/src/itk/Modules/Core/Common/include/itkCovariantVector.h:268:45: note: candidate: ‘template<class T, unsigned int NVectorDimension> itk::CovariantVector<T, NVectorDimension> itk::operator*(const T&, const itk::CovariantVector<T, NVectorDimension>&)’
  268 | inline CovariantVector<T, NVectorDimension> operator*(const T & scalar, const CovariantVector<T, NVectorDimension> & v)
      |                                             ^~~~~~~~
/home/rafael/src/itk/Modules/Core/Common/include/itkCovariantVector.h:268:45: note:   template argument deduction/substitution failed:
In file included from /home/rafael/src/itkImageConvert/main.cxx:4:
/home/rafael/src/itk/Modules/IO/ImageBase/include/itkImageFileWriter.h:254:88: note:   candidate expects 2 arguments, 1 provided
  254 |   using ImageType = typename std::remove_const<typename std::remove_reference<decltype(*image)>::type>::type;
      |                                                                                        ^~~~~~
In file included from /home/rafael/src/itk/Modules/Core/Common/include/itkMatrix.h:22,
                 from /home/rafael/src/itk/Modules/Core/Common/include/itkImageBase.h:34,
                 from /home/rafael/src/itk/Modules/Core/Common/include/itkNeighborhoodAccessorFunctor.h:22,
                 from /home/rafael/src/itk/Modules/Core/Common/include/itkImage.h:28,
                 from /home/rafael/src/itkImageConvert/main.cxx:2:
/home/rafael/src/itk/Modules/Core/Common/include/itkCovariantVector.h:276:10: note: candidate: ‘template<class T, unsigned int NVectorDimension> T itk::operator*(const itk::Vector<T, NVectorDimension>&, const itk::CovariantVector<T, NVectorDimension>&)’
  276 | inline T operator*(const Vector<T, NVectorDimension> &          contravariant,
      |          ^~~~~~~~
/home/rafael/src/itk/Modules/Core/Common/include/itkCovariantVector.h:276:10: note:   template argument deduction/substitution failed:
In file included from /home/rafael/src/itkImageConvert/main.cxx:4:
/home/rafael/src/itk/Modules/IO/ImageBase/include/itkImageFileWriter.h:254:88: note:   ‘itk::Image<int, 3>’ is not derived from ‘const itk::Vector<T, NVectorDimension>’
  254 |   using ImageType = typename std::remove_const<typename std::remove_reference<decltype(*image)>::type>::type;
      |                                                                                        ^~~~~~
In file included from /home/rafael/src/itk/Modules/Core/Common/include/itkDefaultConvertPixelTraits.h:24,
                 from /home/rafael/src/itk/Modules/IO/ImageBase/include/itkImageFileReader.h:28,
                 from /home/rafael/src/itkImageConvert/main.cxx:3:
/home/rafael/src/itk/Modules/Core/Common/include/itkVariableLengthVector.h:1301:1: note: candidate: ‘template<class TExpr1, class TExpr2> typename itk::mpl::EnableIf<itk::Details::op::CanBeMultiplied<TExpr1, TExpr2>, itk::VariableLengthVectorExpression<TExpr1, TExpr2, itk::Details::op::Mult> >::Type itk::operator*(const TExpr1&, const TExpr2&)’
 1301 | operator*(TExpr1 const & lhs, TExpr2 const & rhs)
      | ^~~~~~~~
/home/rafael/src/itk/Modules/Core/Common/include/itkVariableLengthVector.h:1301:1: note:   template argument deduction/substitution failed:
In file included from /home/rafael/src/itkImageConvert/main.cxx:4:
/home/rafael/src/itk/Modules/IO/ImageBase/include/itkImageFileWriter.h:254:88: note:   candidate expects 2 arguments, 1 provided
  254 |   using ImageType = typename std::remove_const<typename std::remove_reference<decltype(*image)>::type>::type;
      |                                                                                        ^~~~~~
/home/rafael/src/itk/Modules/IO/ImageBase/include/itkImageFileWriter.h:254:88: error: no match for ‘operator*’ (operand type is ‘itk::Image<int, 3>’)
In file included from /home/rafael/src/itk/Modules/Core/Common/include/itkPoint.h:23,
                 from /home/rafael/src/itk/Modules/Core/Common/include/itkContinuousIndex.h:21,
                 from /home/rafael/src/itk/Modules/Core/Common/include/itkImageRegion.h:34,
                 from /home/rafael/src/itk/Modules/Core/Common/include/itkImage.h:21,
                 from /home/rafael/src/itkImageConvert/main.cxx:2:
/home/rafael/src/itk/Modules/Core/Common/include/itkVector.h:297:36: note: candidate: ‘template<class T, unsigned int NVectorDimension> itk::Vector<T, NVectorDimension> itk::operator*(const T&, const itk::Vector<T, NVectorDimension>&)’
  297 | inline Vector<T, NVectorDimension> operator*(const T & scalar, const Vector<T, NVectorDimension> & v)
      |                                    ^~~~~~~~
/home/rafael/src/itk/Modules/Core/Common/include/itkVector.h:297:36: note:   template argument deduction/substitution failed:
In file included from /home/rafael/src/itkImageConvert/main.cxx:4:
/home/rafael/src/itk/Modules/IO/ImageBase/include/itkImageFileWriter.h:254:88: note:   candidate expects 2 arguments, 1 provided
  254 |   using ImageType = typename std::remove_const<typename std::remove_reference<decltype(*image)>::type>::type;
      |                                                                                        ^~~~~~
In file included from /home/rafael/src/itk/Modules/Core/Common/include/itkMatrix.h:22,
                 from /home/rafael/src/itk/Modules/Core/Common/include/itkImageBase.h:34,
                 from /home/rafael/src/itk/Modules/Core/Common/include/itkNeighborhoodAccessorFunctor.h:22,
                 from /home/rafael/src/itk/Modules/Core/Common/include/itkImage.h:28,
                 from /home/rafael/src/itkImageConvert/main.cxx:2:
/home/rafael/src/itk/Modules/Core/Common/include/itkCovariantVector.h:268:45: note: candidate: ‘template<class T, unsigned int NVectorDimension> itk::CovariantVector<T, NVectorDimension> itk::operator*(const T&, const itk::CovariantVector<T, NVectorDimension>&)’
  268 | inline CovariantVector<T, NVectorDimension> operator*(const T & scalar, const CovariantVector<T, NVectorDimension> & v)
      |                                             ^~~~~~~~
/home/rafael/src/itk/Modules/Core/Common/include/itkCovariantVector.h:268:45: note:   template argument deduction/substitution failed:
In file included from /home/rafael/src/itkImageConvert/main.cxx:4:
/home/rafael/src/itk/Modules/IO/ImageBase/include/itkImageFileWriter.h:254:88: note:   candidate expects 2 arguments, 1 provided
  254 |   using ImageType = typename std::remove_const<typename std::remove_reference<decltype(*image)>::type>::type;
      |                                                                                        ^~~~~~
In file included from /home/rafael/src/itk/Modules/Core/Common/include/itkMatrix.h:22,
                 from /home/rafael/src/itk/Modules/Core/Common/include/itkImageBase.h:34,
                 from /home/rafael/src/itk/Modules/Core/Common/include/itkNeighborhoodAccessorFunctor.h:22,
                 from /home/rafael/src/itk/Modules/Core/Common/include/itkImage.h:28,
                 from /home/rafael/src/itkImageConvert/main.cxx:2:
/home/rafael/src/itk/Modules/Core/Common/include/itkCovariantVector.h:276:10: note: candidate: ‘template<class T, unsigned int NVectorDimension> T itk::operator*(const itk::Vector<T, NVectorDimension>&, const itk::CovariantVector<T, NVectorDimension>&)’
  276 | inline T operator*(const Vector<T, NVectorDimension> &          contravariant,
      |          ^~~~~~~~
/home/rafael/src/itk/Modules/Core/Common/include/itkCovariantVector.h:276:10: note:   template argument deduction/substitution failed:
In file included from /home/rafael/src/itkImageConvert/main.cxx:4:
/home/rafael/src/itk/Modules/IO/ImageBase/include/itkImageFileWriter.h:254:88: note:   ‘itk::Image<int, 3>’ is not derived from ‘const itk::Vector<T, NVectorDimension>’
  254 |   using ImageType = typename std::remove_const<typename std::remove_reference<decltype(*image)>::type>::type;
      |                                                                                        ^~~~~~
In file included from /home/rafael/src/itk/Modules/Core/Common/include/itkDefaultConvertPixelTraits.h:24,
                 from /home/rafael/src/itk/Modules/IO/ImageBase/include/itkImageFileReader.h:28,
                 from /home/rafael/src/itkImageConvert/main.cxx:3:
/home/rafael/src/itk/Modules/Core/Common/include/itkVariableLengthVector.h:1301:1: note: candidate: ‘template<class TExpr1, class TExpr2> typename itk::mpl::EnableIf<itk::Details::op::CanBeMultiplied<TExpr1, TExpr2>, itk::VariableLengthVectorExpression<TExpr1, TExpr2, itk::Details::op::Mult> >::Type itk::operator*(const TExpr1&, const TExpr2&)’
 1301 | operator*(TExpr1 const & lhs, TExpr2 const & rhs)
      | ^~~~~~~~
/home/rafael/src/itk/Modules/Core/Common/include/itkVariableLengthVector.h:1301:1: note:   template argument deduction/substitution failed:
In file included from /home/rafael/src/itkImageConvert/main.cxx:4:
/home/rafael/src/itk/Modules/IO/ImageBase/include/itkImageFileWriter.h:254:88: note:   candidate expects 2 arguments, 1 provided
  254 |   using ImageType = typename std::remove_const<typename std::remove_reference<decltype(*image)>::type>::type;
      |                                                                                        ^~~~~~
/home/rafael/src/itk/Modules/IO/ImageBase/include/itkImageFileWriter.h: In instantiation of ‘void itk::WriteImage(TImagePointer&&, const string&, bool) [with TImagePointer = itk::Image<unsigned int, 3>; std::string = std::__cxx11::basic_string<char>]’:
/home/rafael/src/itkImageConvert/main.cxx:57:27:   required from ‘int DoIt(const Arguments&, inputT) [with inputT = unsigned int]’
/home/rafael/src/itkImageConvert/main.cxx:112:18:   required from here
/home/rafael/src/itk/Modules/IO/ImageBase/include/itkImageFileWriter.h:250:66: error: static assertion failed: WriteImage requires a raw pointer or SmartPointer.
  250 |   static_assert(std::is_pointer<NonReferenceImagePointer>::value ||
      |                                                            ~~~~~~^~
  251 |                   mpl::IsSmartPointer<NonReferenceImagePointer>::Value,
      |                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/rafael/src/itk/Modules/IO/ImageBase/include/itkImageFileWriter.h:250:66: note: ‘(((bool)std::integral_constant<bool, false>::value) || ((itk::mpl::FalseType::ValueType)itk::mpl::FalseType::Value))’ evaluates to false
/home/rafael/src/itk/Modules/IO/ImageBase/include/itkImageFileWriter.h:254:88: error: no match for ‘operator*’ (operand type is ‘itk::Image<unsigned int, 3>’)
  254 |   using ImageType = typename std::remove_const<typename std::remove_reference<decltype(*image)>::type>::type;
      |                                                                                        ^~~~~~
In file included from /home/rafael/src/itk/Modules/Core/Common/include/itkPoint.h:23,
                 from /home/rafael/src/itk/Modules/Core/Common/include/itkContinuousIndex.h:21,
                 from /home/rafael/src/itk/Modules/Core/Common/include/itkImageRegion.h:34,
                 from /home/rafael/src/itk/Modules/Core/Common/include/itkImage.h:21,
                 from /home/rafael/src/itkImageConvert/main.cxx:2:
/home/rafael/src/itk/Modules/Core/Common/include/itkVector.h:297:36: note: candidate: ‘template<class T, unsigned int NVectorDimension> itk::Vector<T, NVectorDimension> itk::operator*(const T&, const itk::Vector<T, NVectorDimension>&)’
  297 | inline Vector<T, NVectorDimension> operator*(const T & scalar, const Vector<T, NVectorDimension> & v)
      |                                    ^~~~~~~~
/home/rafael/src/itk/Modules/Core/Common/include/itkVector.h:297:36: note:   template argument deduction/substitution failed:
In file included from /home/rafael/src/itkImageConvert/main.cxx:4:
/home/rafael/src/itk/Modules/IO/ImageBase/include/itkImageFileWriter.h:254:88: note:   candidate expects 2 arguments, 1 provided
  254 |   using ImageType = typename std::remove_const<typename std::remove_reference<decltype(*image)>::type>::type;
      |                                                                                        ^~~~~~
In file included from /home/rafael/src/itk/Modules/Core/Common/include/itkMatrix.h:22,
                 from /home/rafael/src/itk/Modules/Core/Common/include/itkImageBase.h:34,
                 from /home/rafael/src/itk/Modules/Core/Common/include/itkNeighborhoodAccessorFunctor.h:22,
                 from /home/rafael/src/itk/Modules/Core/Common/include/itkImage.h:28,
                 from /home/rafael/src/itkImageConvert/main.cxx:2:
/home/rafael/src/itk/Modules/Core/Common/include/itkCovariantVector.h:268:45: note: candidate: ‘template<class T, unsigned int NVectorDimension> itk::CovariantVector<T, NVectorDimension> itk::operator*(const T&, const itk::CovariantVector<T, NVectorDimension>&)’
  268 | inline CovariantVector<T, NVectorDimension> operator*(const T & scalar, const CovariantVector<T, NVectorDimension> & v)
      |                                             ^~~~~~~~
/home/rafael/src/itk/Modules/Core/Common/include/itkCovariantVector.h:268:45: note:   template argument deduction/substitution failed:
In file included from /home/rafael/src/itkImageConvert/main.cxx:4:
/home/rafael/src/itk/Modules/IO/ImageBase/include/itkImageFileWriter.h:254:88: note:   candidate expects 2 arguments, 1 provided
  254 |   using ImageType = typename std::remove_const<typename std::remove_reference<decltype(*image)>::type>::type;
      |                                                                                        ^~~~~~
In file included from /home/rafael/src/itk/Modules/Core/Common/include/itkMatrix.h:22,
                 from /home/rafael/src/itk/Modules/Core/Common/include/itkImageBase.h:34,
                 from /home/rafael/src/itk/Modules/Core/Common/include/itkNeighborhoodAccessorFunctor.h:22,
                 from /home/rafael/src/itk/Modules/Core/Common/include/itkImage.h:28,
                 from /home/rafael/src/itkImageConvert/main.cxx:2:
/home/rafael/src/itk/Modules/Core/Common/include/itkCovariantVector.h:276:10: note: candidate: ‘template<class T, unsigned int NVectorDimension> T itk::operator*(const itk::Vector<T, NVectorDimension>&, const itk::CovariantVector<T, NVectorDimension>&)’
  276 | inline T operator*(const Vector<T, NVectorDimension> &          contravariant,
      |          ^~~~~~~~
/home/rafael/src/itk/Modules/Core/Common/include/itkCovariantVector.h:276:10: note:   template argument deduction/substitution failed:
In file included from /home/rafael/src/itkImageConvert/main.cxx:4:
/home/rafael/src/itk/Modules/IO/ImageBase/include/itkImageFileWriter.h:254:88: note:   ‘itk::Image<unsigned int, 3>’ is not derived from ‘const itk::Vector<T, NVectorDimension>’
  254 |   using ImageType = typename std::remove_const<typename std::remove_reference<decltype(*image)>::type>::type;
      |                                                                                        ^~~~~~
In file included from /home/rafael/src/itk/Modules/Core/Common/include/itkDefaultConvertPixelTraits.h:24,
                 from /home/rafael/src/itk/Modules/IO/ImageBase/include/itkImageFileReader.h:28,
                 from /home/rafael/src/itkImageConvert/main.cxx:3:
/home/rafael/src/itk/Modules/Core/Common/include/itkVariableLengthVector.h:1301:1: note: candidate: ‘template<class TExpr1, class TExpr2> typename itk::mpl::EnableIf<itk::Details::op::CanBeMultiplied<TExpr1, TExpr2>, itk::VariableLengthVectorExpression<TExpr1, TExpr2, itk::Details::op::Mult> >::Type itk::operator*(const TExpr1&, const TExpr2&)’
 1301 | operator*(TExpr1 const & lhs, TExpr2 const & rhs)
      | ^~~~~~~~
/home/rafael/src/itk/Modules/Core/Common/include/itkVariableLengthVector.h:1301:1: note:   template argument deduction/substitution failed:
In file included from /home/rafael/src/itkImageConvert/main.cxx:4:
/home/rafael/src/itk/Modules/IO/ImageBase/include/itkImageFileWriter.h:254:88: note:   candidate expects 2 arguments, 1 provided
  254 |   using ImageType = typename std::remove_const<typename std::remove_reference<decltype(*image)>::type>::type;
      |                                                                                        ^~~~~~
/home/rafael/src/itk/Modules/IO/ImageBase/include/itkImageFileWriter.h:254:88: error: no match for ‘operator*’ (operand type is ‘itk::Image<unsigned int, 3>’)
In file included from /home/rafael/src/itk/Modules/Core/Common/include/itkPoint.h:23,
                 from /home/rafael/src/itk/Modules/Core/Common/include/itkContinuousIndex.h:21,
                 from /home/rafael/src/itk/Modules/Core/Common/include/itkImageRegion.h:34,
                 from /home/rafael/src/itk/Modules/Core/Common/include/itkImage.h:21,
                 from /home/rafael/src/itkImageConvert/main.cxx:2:
/home/rafael/src/itk/Modules/Core/Common/include/itkVector.h:297:36: note: candidate: ‘template<class T, unsigned int NVectorDimension> itk::Vector<T, NVectorDimension> itk::operator*(const T&, const itk::Vector<T, NVectorDimension>&)’
  297 | inline Vector<T, NVectorDimension> operator*(const T & scalar, const Vector<T, NVectorDimension> & v)
      |                                    ^~~~~~~~
/home/rafael/src/itk/Modules/Core/Common/include/itkVector.h:297:36: note:   template argument deduction/substitution failed:
In file included from /home/rafael/src/itkImageConvert/main.cxx:4:
/home/rafael/src/itk/Modules/IO/ImageBase/include/itkImageFileWriter.h:254:88: note:   candidate expects 2 arguments, 1 provided
  254 |   using ImageType = typename std::remove_const<typename std::remove_reference<decltype(*image)>::type>::type;
      |                                                                                        ^~~~~~
In file included from /home/rafael/src/itk/Modules/Core/Common/include/itkMatrix.h:22,
                 from /home/rafael/src/itk/Modules/Core/Common/include/itkImageBase.h:34,
                 from /home/rafael/src/itk/Modules/Core/Common/include/itkNeighborhoodAccessorFunctor.h:22,
                 from /home/rafael/src/itk/Modules/Core/Common/include/itkImage.h:28,
                 from /home/rafael/src/itkImageConvert/main.cxx:2:
/home/rafael/src/itk/Modules/Core/Common/include/itkCovariantVector.h:268:45: note: candidate: ‘template<class T, unsigned int NVectorDimension> itk::CovariantVector<T, NVectorDimension> itk::operator*(const T&, const itk::CovariantVector<T, NVectorDimension>&)’
  268 | inline CovariantVector<T, NVectorDimension> operator*(const T & scalar, const CovariantVector<T, NVectorDimension> & v)
      |                                             ^~~~~~~~
/home/rafael/src/itk/Modules/Core/Common/include/itkCovariantVector.h:268:45: note:   template argument deduction/substitution failed:
In file included from /home/rafael/src/itkImageConvert/main.cxx:4:
/home/rafael/src/itk/Modules/IO/ImageBase/include/itkImageFileWriter.h:254:88: note:   candidate expects 2 arguments, 1 provided
  254 |   using ImageType = typename std::remove_const<typename std::remove_reference<decltype(*image)>::type>::type;
      |                                                                                        ^~~~~~
In file included from /home/rafael/src/itk/Modules/Core/Common/include/itkMatrix.h:22,
                 from /home/rafael/src/itk/Modules/Core/Common/include/itkImageBase.h:34,
                 from /home/rafael/src/itk/Modules/Core/Common/include/itkNeighborhoodAccessorFunctor.h:22,
                 from /home/rafael/src/itk/Modules/Core/Common/include/itkImage.h:28,
                 from /home/rafael/src/itkImageConvert/main.cxx:2:
/home/rafael/src/itk/Modules/Core/Common/include/itkCovariantVector.h:276:10: note: candidate: ‘template<class T, unsigned int NVectorDimension> T itk::operator*(const itk::Vector<T, NVectorDimension>&, const itk::CovariantVector<T, NVectorDimension>&)’
  276 | inline T operator*(const Vector<T, NVectorDimension> &          contravariant,
      |          ^~~~~~~~
/home/rafael/src/itk/Modules/Core/Common/include/itkCovariantVector.h:276:10: note:   template argument deduction/substitution failed:
In file included from /home/rafael/src/itkImageConvert/main.cxx:4:
/home/rafael/src/itk/Modules/IO/ImageBase/include/itkImageFileWriter.h:254:88: note:   ‘itk::Image<unsigned int, 3>’ is not derived from ‘const itk::Vector<T, NVectorDimension>’
  254 |   using ImageType = typename std::remove_const<typename std::remove_reference<decltype(*image)>::type>::type;
      |                                                                                        ^~~~~~
In file included from /home/rafael/src/itk/Modules/Core/Common/include/itkDefaultConvertPixelTraits.h:24,
                 from /home/rafael/src/itk/Modules/IO/ImageBase/include/itkImageFileReader.h:28,
                 from /home/rafael/src/itkImageConvert/main.cxx:3:
/home/rafael/src/itk/Modules/Core/Common/include/itkVariableLengthVector.h:1301:1: note: candidate: ‘template<class TExpr1, class TExpr2> typename itk::mpl::EnableIf<itk::Details::op::CanBeMultiplied<TExpr1, TExpr2>, itk::VariableLengthVectorExpression<TExpr1, TExpr2, itk::Details::op::Mult> >::Type itk::operator*(const TExpr1&, const TExpr2&)’
 1301 | operator*(TExpr1 const & lhs, TExpr2 const & rhs)
      | ^~~~~~~~
/home/rafael/src/itk/Modules/Core/Common/include/itkVariableLengthVector.h:1301:1: note:   template argument deduction/substitution failed:
In file included from /home/rafael/src/itkImageConvert/main.cxx:4:
/home/rafael/src/itk/Modules/IO/ImageBase/include/itkImageFileWriter.h:254:88: note:   candidate expects 2 arguments, 1 provided
  254 |   using ImageType = typename std::remove_const<typename std::remove_reference<decltype(*image)>::type>::type;
      |                                                                                        ^~~~~~
/home/rafael/src/itk/Modules/IO/ImageBase/include/itkImageFileWriter.h: In instantiation of ‘void itk::WriteImage(TImagePointer&&, const string&, bool) [with TImagePointer = itk::Image<float, 3>; std::string = std::__cxx11::basic_string<char>]’:
/home/rafael/src/itkImageConvert/main.cxx:57:27:   required from ‘int DoIt(const Arguments&, inputT) [with inputT = float]’
/home/rafael/src/itkImageConvert/main.cxx:116:18:   required from here
/home/rafael/src/itk/Modules/IO/ImageBase/include/itkImageFileWriter.h:250:66: error: static assertion failed: WriteImage requires a raw pointer or SmartPointer.
  250 |   static_assert(std::is_pointer<NonReferenceImagePointer>::value ||
      |                                                            ~~~~~~^~
  251 |                   mpl::IsSmartPointer<NonReferenceImagePointer>::Value,
      |                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/rafael/src/itk/Modules/IO/ImageBase/include/itkImageFileWriter.h:250:66: note: ‘(((bool)std::integral_constant<bool, false>::value) || ((itk::mpl::FalseType::ValueType)itk::mpl::FalseType::Value))’ evaluates to false
/home/rafael/src/itk/Modules/IO/ImageBase/include/itkImageFileWriter.h:254:88: error: no match for ‘operator*’ (operand type is ‘itk::Image<float, 3>’)
  254 |   using ImageType = typename std::remove_const<typename std::remove_reference<decltype(*image)>::type>::type;
      |                                                                                        ^~~~~~
In file included from /home/rafael/src/itk/Modules/Core/Common/include/itkPoint.h:23,
                 from /home/rafael/src/itk/Modules/Core/Common/include/itkContinuousIndex.h:21,
                 from /home/rafael/src/itk/Modules/Core/Common/include/itkImageRegion.h:34,
                 from /home/rafael/src/itk/Modules/Core/Common/include/itkImage.h:21,
                 from /home/rafael/src/itkImageConvert/main.cxx:2:
/home/rafael/src/itk/Modules/Core/Common/include/itkVector.h:297:36: note: candidate: ‘template<class T, unsigned int NVectorDimension> itk::Vector<T, NVectorDimension> itk::operator*(const T&, const itk::Vector<T, NVectorDimension>&)’
  297 | inline Vector<T, NVectorDimension> operator*(const T & scalar, const Vector<T, NVectorDimension> & v)
      |                                    ^~~~~~~~
/home/rafael/src/itk/Modules/Core/Common/include/itkVector.h:297:36: note:   template argument deduction/substitution failed:
In file included from /home/rafael/src/itkImageConvert/main.cxx:4:
/home/rafael/src/itk/Modules/IO/ImageBase/include/itkImageFileWriter.h:254:88: note:   candidate expects 2 arguments, 1 provided
  254 |   using ImageType = typename std::remove_const<typename std::remove_reference<decltype(*image)>::type>::type;
      |                                                                                        ^~~~~~
In file included from /home/rafael/src/itk/Modules/Core/Common/include/itkMatrix.h:22,
                 from /home/rafael/src/itk/Modules/Core/Common/include/itkImageBase.h:34,
                 from /home/rafael/src/itk/Modules/Core/Common/include/itkNeighborhoodAccessorFunctor.h:22,
                 from /home/rafael/src/itk/Modules/Core/Common/include/itkImage.h:28,
                 from /home/rafael/src/itkImageConvert/main.cxx:2:
/home/rafael/src/itk/Modules/Core/Common/include/itkCovariantVector.h:268:45: note: candidate: ‘template<class T, unsigned int NVectorDimension> itk::CovariantVector<T, NVectorDimension> itk::operator*(const T&, const itk::CovariantVector<T, NVectorDimension>&)’
  268 | inline CovariantVector<T, NVectorDimension> operator*(const T & scalar, const CovariantVector<T, NVectorDimension> & v)
      |                                             ^~~~~~~~
/home/rafael/src/itk/Modules/Core/Common/include/itkCovariantVector.h:268:45: note:   template argument deduction/substitution failed:
In file included from /home/rafael/src/itkImageConvert/main.cxx:4:
/home/rafael/src/itk/Modules/IO/ImageBase/include/itkImageFileWriter.h:254:88: note:   candidate expects 2 arguments, 1 provided
  254 |   using ImageType = typename std::remove_const<typename std::remove_reference<decltype(*image)>::type>::type;
      |                                                                                        ^~~~~~
In file included from /home/rafael/src/itk/Modules/Core/Common/include/itkMatrix.h:22,
                 from /home/rafael/src/itk/Modules/Core/Common/include/itkImageBase.h:34,
                 from /home/rafael/src/itk/Modules/Core/Common/include/itkNeighborhoodAccessorFunctor.h:22,
                 from /home/rafael/src/itk/Modules/Core/Common/include/itkImage.h:28,
                 from /home/rafael/src/itkImageConvert/main.cxx:2:
/home/rafael/src/itk/Modules/Core/Common/include/itkCovariantVector.h:276:10: note: candidate: ‘template<class T, unsigned int NVectorDimension> T itk::operator*(const itk::Vector<T, NVectorDimension>&, const itk::CovariantVector<T, NVectorDimension>&)’
  276 | inline T operator*(const Vector<T, NVectorDimension> &          contravariant,
      |          ^~~~~~~~
/home/rafael/src/itk/Modules/Core/Common/include/itkCovariantVector.h:276:10: note:   template argument deduction/substitution failed:
In file included from /home/rafael/src/itkImageConvert/main.cxx:4:
/home/rafael/src/itk/Modules/IO/ImageBase/include/itkImageFileWriter.h:254:88: note:   ‘itk::Image<float, 3>’ is not derived from ‘const itk::Vector<T, NVectorDimension>’
  254 |   using ImageType = typename std::remove_const<typename std::remove_reference<decltype(*image)>::type>::type;
      |                                                                                        ^~~~~~
In file included from /home/rafael/src/itk/Modules/Core/Common/include/itkDefaultConvertPixelTraits.h:24,
                 from /home/rafael/src/itk/Modules/IO/ImageBase/include/itkImageFileReader.h:28,
                 from /home/rafael/src/itkImageConvert/main.cxx:3:
/home/rafael/src/itk/Modules/Core/Common/include/itkVariableLengthVector.h:1301:1: note: candidate: ‘template<class TExpr1, class TExpr2> typename itk::mpl::EnableIf<itk::Details::op::CanBeMultiplied<TExpr1, TExpr2>, itk::VariableLengthVectorExpression<TExpr1, TExpr2, itk::Details::op::Mult> >::Type itk::operator*(const TExpr1&, const TExpr2&)’
 1301 | operator*(TExpr1 const & lhs, TExpr2 const & rhs)
      | ^~~~~~~~
/home/rafael/src/itk/Modules/Core/Common/include/itkVariableLengthVector.h:1301:1: note:   template argument deduction/substitution failed:
In file included from /home/rafael/src/itkImageConvert/main.cxx:4:
/home/rafael/src/itk/Modules/IO/ImageBase/include/itkImageFileWriter.h:254:88: note:   candidate expects 2 arguments, 1 provided
  254 |   using ImageType = typename std::remove_const<typename std::remove_reference<decltype(*image)>::type>::type;
      |                                                                                        ^~~~~~
/home/rafael/src/itk/Modules/IO/ImageBase/include/itkImageFileWriter.h:254:88: error: no match for ‘operator*’ (operand type is ‘itk::Image<float, 3>’)
In file included from /home/rafael/src/itk/Modules/Core/Common/include/itkPoint.h:23,
                 from /home/rafael/src/itk/Modules/Core/Common/include/itkContinuousIndex.h:21,
                 from /home/rafael/src/itk/Modules/Core/Common/include/itkImageRegion.h:34,
                 from /home/rafael/src/itk/Modules/Core/Common/include/itkImage.h:21,
                 from /home/rafael/src/itkImageConvert/main.cxx:2:
/home/rafael/src/itk/Modules/Core/Common/include/itkVector.h:297:36: note: candidate: ‘template<class T, unsigned int NVectorDimension> itk::Vector<T, NVectorDimension> itk::operator*(const T&, const itk::Vector<T, NVectorDimension>&)’
  297 | inline Vector<T, NVectorDimension> operator*(const T & scalar, const Vector<T, NVectorDimension> & v)
      |                                    ^~~~~~~~
/home/rafael/src/itk/Modules/Core/Common/include/itkVector.h:297:36: note:   template argument deduction/substitution failed:
In file included from /home/rafael/src/itkImageConvert/main.cxx:4:
/home/rafael/src/itk/Modules/IO/ImageBase/include/itkImageFileWriter.h:254:88: note:   candidate expects 2 arguments, 1 provided
  254 |   using ImageType = typename std::remove_const<typename std::remove_reference<decltype(*image)>::type>::type;
      |                                                                                        ^~~~~~
In file included from /home/rafael/src/itk/Modules/Core/Common/include/itkMatrix.h:22,
                 from /home/rafael/src/itk/Modules/Core/Common/include/itkImageBase.h:34,
                 from /home/rafael/src/itk/Modules/Core/Common/include/itkNeighborhoodAccessorFunctor.h:22,
                 from /home/rafael/src/itk/Modules/Core/Common/include/itkImage.h:28,
                 from /home/rafael/src/itkImageConvert/main.cxx:2:
/home/rafael/src/itk/Modules/Core/Common/include/itkCovariantVector.h:268:45: note: candidate: ‘template<class T, unsigned int NVectorDimension> itk::CovariantVector<T, NVectorDimension> itk::operator*(const T&, const itk::CovariantVector<T, NVectorDimension>&)’
  268 | inline CovariantVector<T, NVectorDimension> operator*(const T & scalar, const CovariantVector<T, NVectorDimension> & v)
      |                                             ^~~~~~~~
/home/rafael/src/itk/Modules/Core/Common/include/itkCovariantVector.h:268:45: note:   template argument deduction/substitution failed:
In file included from /home/rafael/src/itkImageConvert/main.cxx:4:
/home/rafael/src/itk/Modules/IO/ImageBase/include/itkImageFileWriter.h:254:88: note:   candidate expects 2 arguments, 1 provided
  254 |   using ImageType = typename std::remove_const<typename std::remove_reference<decltype(*image)>::type>::type;
      |                                                                                        ^~~~~~
In file included from /home/rafael/src/itk/Modules/Core/Common/include/itkMatrix.h:22,
                 from /home/rafael/src/itk/Modules/Core/Common/include/itkImageBase.h:34,
                 from /home/rafael/src/itk/Modules/Core/Common/include/itkNeighborhoodAccessorFunctor.h:22,
                 from /home/rafael/src/itk/Modules/Core/Common/include/itkImage.h:28,
                 from /home/rafael/src/itkImageConvert/main.cxx:2:
/home/rafael/src/itk/Modules/Core/Common/include/itkCovariantVector.h:276:10: note: candidate: ‘template<class T, unsigned int NVectorDimension> T itk::operator*(const itk::Vector<T, NVectorDimension>&, const itk::CovariantVector<T, NVectorDimension>&)’
  276 | inline T operator*(const Vector<T, NVectorDimension> &          contravariant,
      |          ^~~~~~~~
/home/rafael/src/itk/Modules/Core/Common/include/itkCovariantVector.h:276:10: note:   template argument deduction/substitution failed:
In file included from /home/rafael/src/itkImageConvert/main.cxx:4:
/home/rafael/src/itk/Modules/IO/ImageBase/include/itkImageFileWriter.h:254:88: note:   ‘itk::Image<float, 3>’ is not derived from ‘const itk::Vector<T, NVectorDimension>’
  254 |   using ImageType = typename std::remove_const<typename std::remove_reference<decltype(*image)>::type>::type;
      |                                                                                        ^~~~~~
In file included from /home/rafael/src/itk/Modules/Core/Common/include/itkDefaultConvertPixelTraits.h:24,
                 from /home/rafael/src/itk/Modules/IO/ImageBase/include/itkImageFileReader.h:28,
                 from /home/rafael/src/itkImageConvert/main.cxx:3:
/home/rafael/src/itk/Modules/Core/Common/include/itkVariableLengthVector.h:1301:1: note: candidate: ‘template<class TExpr1, class TExpr2> typename itk::mpl::EnableIf<itk::Details::op::CanBeMultiplied<TExpr1, TExpr2>, itk::VariableLengthVectorExpression<TExpr1, TExpr2, itk::Details::op::Mult> >::Type itk::operator*(const TExpr1&, const TExpr2&)’
 1301 | operator*(TExpr1 const & lhs, TExpr2 const & rhs)
      | ^~~~~~~~
/home/rafael/src/itk/Modules/Core/Common/include/itkVariableLengthVector.h:1301:1: note:   template argument deduction/substitution failed:
In file included from /home/rafael/src/itkImageConvert/main.cxx:4:
/home/rafael/src/itk/Modules/IO/ImageBase/include/itkImageFileWriter.h:254:88: note:   candidate expects 2 arguments, 1 provided
  254 |   using ImageType = typename std::remove_const<typename std::remove_reference<decltype(*image)>::type>::type;
      |                                                                                        ^~~~~~
gmake[2]: *** [CMakeFiles/itkImageConvert.dir/build.make:76: CMakeFiles/itkImageConvert.dir/main.cxx.o] Error 1
gmake[1]: *** [CMakeFiles/Makefile2:83: CMakeFiles/itkImageConvert.dir/all] Error 2
gmake: *** [Makefile:91: all] Error 2

Compilation exited abnormally with code 2 at Tue Jun  7 14:23:21

Unfortunately this does not really work when I use the short datatype (even if the input image is originally of short datatype. The full code (it is a short one) can be found at GitHub - ALive-research/itkImageConvert: Simple program to convert images

Why? I think this should work with short pixel type.

Does this compile: itk::WriteImage<typename ImageType::Pointer>(inImage, arguments.outputFileName);? WriteImage is meant to be used with automatic type deduction.

1 Like

In theory it should, and it does work well for other types using DoIt<float> produces a nrrd with float datatype in the header, the same for int, but using short does produce an output with int as datatype.

What if you change this into return DoIt<short>(arguments, 0);?

Thank you @dzenanz for the help and the patience. This solves the issue!

2 Likes